1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.plugins; 18 19 import android.graphics.Color; 20 import android.graphics.Rect; 21 import android.view.View; 22 import android.widget.ImageView; 23 24 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; 25 import com.android.systemui.plugins.annotations.DependsOn; 26 import com.android.systemui.plugins.annotations.ProvidesInterface; 27 28 /** 29 * Dispatches events to {@link DarkReceiver}s about changes in darkness, tint area and dark 30 * intensity. Accessible through {@link PluginDependency} 31 */ 32 @ProvidesInterface(version = DarkIconDispatcher.VERSION) 33 @DependsOn(target = DarkReceiver.class) 34 public interface DarkIconDispatcher { 35 int VERSION = 1; 36 37 /** 38 * Sets the dark area so {@link #applyDark} only affects the icons in the specified area. 39 * 40 * @param r the area in which icons should change its tint, in logical screen 41 * coordinates 42 */ setIconsDarkArea(Rect r)43 void setIconsDarkArea(Rect r); 44 45 /** 46 * Adds a receiver to receive callbacks onDarkChanged 47 */ addDarkReceiver(DarkReceiver receiver)48 void addDarkReceiver(DarkReceiver receiver); 49 50 /** 51 * Adds a receiver to receive callbacks onDarkChanged 52 */ addDarkReceiver(ImageView imageView)53 void addDarkReceiver(ImageView imageView); 54 55 /** 56 * Must have been previously been added through one of the addDarkReceive methods above. 57 */ removeDarkReceiver(DarkReceiver object)58 void removeDarkReceiver(DarkReceiver object); 59 60 /** 61 * Must have been previously been added through one of the addDarkReceive methods above. 62 */ removeDarkReceiver(ImageView object)63 void removeDarkReceiver(ImageView object); 64 65 /** 66 * Used to reapply darkness on an object, must have previously been added through 67 * addDarkReceiver. 68 */ applyDark(DarkReceiver object)69 void applyDark(DarkReceiver object); 70 71 int DEFAULT_ICON_TINT = Color.WHITE; 72 Rect sTmpRect = new Rect(); 73 int[] sTmpInt2 = new int[2]; 74 75 /** 76 * @return the tint to apply to view depending on the desired tint color and 77 * the screen tintArea in which to apply that tint 78 */ getTint(Rect tintArea, View view, int color)79 static int getTint(Rect tintArea, View view, int color) { 80 if (isInArea(tintArea, view)) { 81 return color; 82 } else { 83 return DEFAULT_ICON_TINT; 84 } 85 } 86 87 /** 88 * @return the dark intensity to apply to view depending on the desired dark 89 * intensity and the screen tintArea in which to apply that intensity 90 */ getDarkIntensity(Rect tintArea, View view, float intensity)91 static float getDarkIntensity(Rect tintArea, View view, float intensity) { 92 if (isInArea(tintArea, view)) { 93 return intensity; 94 } else { 95 return 0f; 96 } 97 } 98 99 /** 100 * @return true if more than half of the view area are in area, false 101 * otherwise 102 */ isInArea(Rect area, View view)103 static boolean isInArea(Rect area, View view) { 104 if (area.isEmpty()) { 105 return true; 106 } 107 sTmpRect.set(area); 108 view.getLocationOnScreen(sTmpInt2); 109 int left = sTmpInt2[0]; 110 111 int intersectStart = Math.max(left, area.left); 112 int intersectEnd = Math.min(left + view.getWidth(), area.right); 113 int intersectAmount = Math.max(0, intersectEnd - intersectStart); 114 115 boolean coversFullStatusBar = area.top <= 0; 116 boolean majorityOfWidth = 2 * intersectAmount > view.getWidth(); 117 return majorityOfWidth && coversFullStatusBar; 118 } 119 120 /** 121 * Receives a callback on darkness changes 122 */ 123 @ProvidesInterface(version = DarkReceiver.VERSION) 124 interface DarkReceiver { 125 int VERSION = 1; onDarkChanged(Rect area, float darkIntensity, int tint)126 void onDarkChanged(Rect area, float darkIntensity, int tint); 127 } 128 } 129