1 /* 2 * Copyright (C) 2016 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.statusbar.phone; 18 19 import android.graphics.Rect; 20 import android.view.View; 21 22 import com.android.systemui.statusbar.policy.BatteryController; 23 24 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT; 25 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; 26 27 /** 28 * Controls how light status bar flag applies to the icons. 29 */ 30 public class LightStatusBarController implements BatteryController.BatteryStateChangeCallback { 31 32 private final StatusBarIconController mIconController; 33 private final BatteryController mBatteryController; 34 private FingerprintUnlockController mFingerprintUnlockController; 35 36 private int mFullscreenStackVisibility; 37 private int mDockedStackVisibility; 38 private boolean mFullscreenLight; 39 private boolean mDockedLight; 40 private int mLastStatusBarMode; 41 42 private final Rect mLastFullscreenBounds = new Rect(); 43 private final Rect mLastDockedBounds = new Rect(); 44 45 public LightStatusBarController(StatusBarIconController iconController, 46 BatteryController batteryController) { 47 mIconController = iconController; 48 mBatteryController = batteryController; 49 batteryController.addStateChangedCallback(this); 50 } 51 52 public void setFingerprintUnlockController( 53 FingerprintUnlockController fingerprintUnlockController) { 54 mFingerprintUnlockController = fingerprintUnlockController; 55 } 56 57 public void onSystemUiVisibilityChanged(int fullscreenStackVis, int dockedStackVis, int mask, 58 Rect fullscreenStackBounds, Rect dockedStackBounds, boolean sbModeChanged, 59 int statusBarMode) { 60 int oldFullscreen = mFullscreenStackVisibility; 61 int newFullscreen = (oldFullscreen & ~mask) | (fullscreenStackVis & mask); 62 int diffFullscreen = newFullscreen ^ oldFullscreen; 63 int oldDocked = mDockedStackVisibility; 64 int newDocked = (oldDocked & ~mask) | (dockedStackVis & mask); 65 int diffDocked = newDocked ^ oldDocked; 66 if ((diffFullscreen & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0 67 || (diffDocked & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0 68 || sbModeChanged 69 || !mLastFullscreenBounds.equals(fullscreenStackBounds) 70 || !mLastDockedBounds.equals(dockedStackBounds)) { 71 72 mFullscreenLight = isLight(newFullscreen, statusBarMode); 73 mDockedLight = isLight(newDocked, statusBarMode); 74 update(fullscreenStackBounds, dockedStackBounds); 75 } 76 mFullscreenStackVisibility = newFullscreen; 77 mDockedStackVisibility = newDocked; 78 mLastStatusBarMode = statusBarMode; 79 mLastFullscreenBounds.set(fullscreenStackBounds); 80 mLastDockedBounds.set(dockedStackBounds); 81 } 82 83 private boolean isLight(int vis, int statusBarMode) { 84 boolean isTransparentBar = (statusBarMode == MODE_TRANSPARENT 85 || statusBarMode == MODE_LIGHTS_OUT_TRANSPARENT); 86 boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave(); 87 boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0; 88 return allowLight && light; 89 } 90 91 private boolean animateChange() { 92 if (mFingerprintUnlockController == null) { 93 return false; 94 } 95 int unlockMode = mFingerprintUnlockController.getMode(); 96 return unlockMode != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING 97 && unlockMode != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK; 98 } 99 100 private void update(Rect fullscreenStackBounds, Rect dockedStackBounds) { 101 boolean hasDockedStack = !dockedStackBounds.isEmpty(); 102 103 // If both are light or fullscreen is light and there is no docked stack, all icons get 104 // dark. 105 if ((mFullscreenLight && mDockedLight) || (mFullscreenLight && !hasDockedStack)) { 106 mIconController.setIconsDarkArea(null); 107 mIconController.setIconsDark(true, animateChange()); 108 109 } 110 111 // If no one is light or the fullscreen is not light and there is no docked stack, 112 // all icons become white. 113 else if ((!mFullscreenLight && !mDockedLight) || (!mFullscreenLight && !hasDockedStack)) { 114 mIconController.setIconsDark(false, animateChange()); 115 116 } 117 118 // Not the same for every stack, magic! 119 else { 120 Rect bounds = mFullscreenLight ? fullscreenStackBounds : dockedStackBounds; 121 if (bounds.isEmpty()) { 122 mIconController.setIconsDarkArea(null); 123 } else { 124 mIconController.setIconsDarkArea(bounds); 125 } 126 mIconController.setIconsDark(true, animateChange()); 127 } 128 } 129 130 @Override 131 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { 132 133 } 134 135 @Override 136 public void onPowerSaveChanged(boolean isPowerSave) { 137 onSystemUiVisibilityChanged(mFullscreenStackVisibility, mDockedStackVisibility, 138 0 /* mask */, mLastFullscreenBounds, mLastDockedBounds, true /* sbModeChange*/, 139 mLastStatusBarMode); 140 } 141 } 142