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