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 import java.util.ArrayList; 29 import java.util.Collection; 30 31 /** 32 * Dispatches events to {@link DarkReceiver}s about changes in darkness, tint area and dark 33 * intensity. Accessible through {@link PluginDependency} 34 */ 35 @ProvidesInterface(version = DarkIconDispatcher.VERSION) 36 @DependsOn(target = DarkReceiver.class) 37 public interface DarkIconDispatcher { 38 int VERSION = 2; 39 40 /** 41 * Sets the dark area so {@link #applyDark} only affects the icons in the specified area. 42 * 43 * @param r the areas in which icons should change its tint, in logical screen 44 * coordinates 45 */ setIconsDarkArea(ArrayList<Rect> r)46 void setIconsDarkArea(ArrayList<Rect> r); 47 48 /** 49 * Adds a receiver to receive callbacks onDarkChanged 50 */ addDarkReceiver(DarkReceiver receiver)51 void addDarkReceiver(DarkReceiver receiver); 52 53 /** 54 * Adds a receiver to receive callbacks onDarkChanged 55 */ addDarkReceiver(ImageView imageView)56 void addDarkReceiver(ImageView imageView); 57 58 /** 59 * Must have been previously been added through one of the addDarkReceive methods above. 60 */ removeDarkReceiver(DarkReceiver object)61 void removeDarkReceiver(DarkReceiver object); 62 63 /** 64 * Must have been previously been added through one of the addDarkReceive methods above. 65 */ removeDarkReceiver(ImageView object)66 void removeDarkReceiver(ImageView object); 67 68 /** 69 * Used to reapply darkness on an object, must have previously been added through 70 * addDarkReceiver. 71 */ applyDark(DarkReceiver object)72 void applyDark(DarkReceiver object); 73 74 int DEFAULT_ICON_TINT = Color.WHITE; 75 Rect sTmpRect = new Rect(); 76 int[] sTmpInt2 = new int[2]; 77 78 /** 79 * @return the tint to apply to view depending on the desired tint color and 80 * the screen tintArea in which to apply that tint 81 */ getTint(Collection<Rect> tintAreas, View view, int color)82 static int getTint(Collection<Rect> tintAreas, View view, int color) { 83 if (isInAreas(tintAreas, view)) { 84 return color; 85 } else { 86 return DEFAULT_ICON_TINT; 87 } 88 } 89 90 /** 91 * @return true if more than half of the view area are in any of the given 92 * areas, false otherwise 93 */ isInAreas(Collection<Rect> areas, View view)94 static boolean isInAreas(Collection<Rect> areas, View view) { 95 if (areas.isEmpty()) { 96 return true; 97 } 98 for (Rect area : areas) { 99 if (isInArea(area, view)) { 100 return true; 101 } 102 } 103 return false; 104 } 105 106 /** 107 * @return true if more than half of the view area are in area, false 108 * otherwise 109 */ isInArea(Rect area, View view)110 static boolean isInArea(Rect area, View view) { 111 if (area.isEmpty()) { 112 return true; 113 } 114 sTmpRect.set(area); 115 view.getLocationOnScreen(sTmpInt2); 116 int left = sTmpInt2[0]; 117 118 int intersectStart = Math.max(left, area.left); 119 int intersectEnd = Math.min(left + view.getWidth(), area.right); 120 int intersectAmount = Math.max(0, intersectEnd - intersectStart); 121 122 boolean coversFullStatusBar = area.top <= 0; 123 boolean majorityOfWidth = 2 * intersectAmount > view.getWidth(); 124 return majorityOfWidth && coversFullStatusBar; 125 } 126 127 /** 128 * Receives a callback on darkness changes 129 */ 130 @ProvidesInterface(version = DarkReceiver.VERSION) 131 interface DarkReceiver { 132 int VERSION = 2; onDarkChanged(ArrayList<Rect> areas, float darkIntensity, int tint)133 void onDarkChanged(ArrayList<Rect> areas, float darkIntensity, int tint); 134 } 135 } 136