1 /* 2 * Copyright (C) 2020 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.keyguard; 18 19 import android.graphics.Rect; 20 import android.util.Slog; 21 22 import com.android.systemui.keyguard.KeyguardUnlockAnimationController; 23 import com.android.systemui.shared.system.smartspace.SmartspaceTransitionController; 24 import com.android.systemui.statusbar.notification.AnimatableProperty; 25 import com.android.systemui.statusbar.notification.PropertyAnimator; 26 import com.android.systemui.statusbar.notification.stack.AnimationProperties; 27 import com.android.systemui.statusbar.notification.stack.StackStateAnimator; 28 import com.android.systemui.statusbar.phone.DozeParameters; 29 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; 30 import com.android.systemui.statusbar.policy.ConfigurationController; 31 import com.android.systemui.statusbar.policy.KeyguardStateController; 32 import com.android.systemui.util.ViewController; 33 34 import java.util.TimeZone; 35 36 import javax.inject.Inject; 37 38 /** 39 * Injectable controller for {@link KeyguardStatusView}. 40 */ 41 public class KeyguardStatusViewController extends ViewController<KeyguardStatusView> { 42 private static final boolean DEBUG = KeyguardConstants.DEBUG; 43 private static final String TAG = "KeyguardStatusViewController"; 44 45 private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = 46 new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); 47 48 private final KeyguardSliceViewController mKeyguardSliceViewController; 49 private final KeyguardClockSwitchController mKeyguardClockSwitchController; 50 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; 51 private final ConfigurationController mConfigurationController; 52 private final DozeParameters mDozeParameters; 53 private final KeyguardVisibilityHelper mKeyguardVisibilityHelper; 54 private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; 55 private final KeyguardStateController mKeyguardStateController; 56 private SmartspaceTransitionController mSmartspaceTransitionController; 57 private final Rect mClipBounds = new Rect(); 58 59 @Inject KeyguardStatusViewController( KeyguardStatusView keyguardStatusView, KeyguardSliceViewController keyguardSliceViewController, KeyguardClockSwitchController keyguardClockSwitchController, KeyguardStateController keyguardStateController, KeyguardUpdateMonitor keyguardUpdateMonitor, ConfigurationController configurationController, DozeParameters dozeParameters, KeyguardUnlockAnimationController keyguardUnlockAnimationController, SmartspaceTransitionController smartspaceTransitionController, UnlockedScreenOffAnimationController unlockedScreenOffAnimationController)60 public KeyguardStatusViewController( 61 KeyguardStatusView keyguardStatusView, 62 KeyguardSliceViewController keyguardSliceViewController, 63 KeyguardClockSwitchController keyguardClockSwitchController, 64 KeyguardStateController keyguardStateController, 65 KeyguardUpdateMonitor keyguardUpdateMonitor, 66 ConfigurationController configurationController, 67 DozeParameters dozeParameters, 68 KeyguardUnlockAnimationController keyguardUnlockAnimationController, 69 SmartspaceTransitionController smartspaceTransitionController, 70 UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) { 71 super(keyguardStatusView); 72 mKeyguardSliceViewController = keyguardSliceViewController; 73 mKeyguardClockSwitchController = keyguardClockSwitchController; 74 mKeyguardUpdateMonitor = keyguardUpdateMonitor; 75 mConfigurationController = configurationController; 76 mDozeParameters = dozeParameters; 77 mKeyguardStateController = keyguardStateController; 78 mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController, 79 dozeParameters, unlockedScreenOffAnimationController, /* animateYPos= */ true); 80 mKeyguardUnlockAnimationController = keyguardUnlockAnimationController; 81 mSmartspaceTransitionController = smartspaceTransitionController; 82 } 83 84 @Override onInit()85 public void onInit() { 86 mKeyguardClockSwitchController.init(); 87 } 88 89 @Override onViewAttached()90 protected void onViewAttached() { 91 mKeyguardUpdateMonitor.registerCallback(mInfoCallback); 92 mConfigurationController.addCallback(mConfigurationListener); 93 mKeyguardStateController.addCallback(mKeyguardStateControllerCallback); 94 } 95 96 @Override onViewDetached()97 protected void onViewDetached() { 98 mKeyguardUpdateMonitor.removeCallback(mInfoCallback); 99 mConfigurationController.removeCallback(mConfigurationListener); 100 mKeyguardStateController.removeCallback(mKeyguardStateControllerCallback); 101 } 102 103 /** 104 * Updates views on doze time tick. 105 */ dozeTimeTick()106 public void dozeTimeTick() { 107 refreshTime(); 108 mKeyguardSliceViewController.refresh(); 109 } 110 111 /** 112 * The amount we're in doze. 113 */ setDarkAmount(float darkAmount)114 public void setDarkAmount(float darkAmount) { 115 mView.setDarkAmount(darkAmount); 116 } 117 118 /** 119 * Set whether or not the lock screen is showing notifications. 120 */ setHasVisibleNotifications(boolean hasVisibleNotifications)121 public void setHasVisibleNotifications(boolean hasVisibleNotifications) { 122 mKeyguardClockSwitchController.setHasVisibleNotifications(hasVisibleNotifications); 123 } 124 125 /** 126 * If we're presenting a custom clock of just the default one. 127 */ hasCustomClock()128 public boolean hasCustomClock() { 129 return mKeyguardClockSwitchController.hasCustomClock(); 130 } 131 132 /** 133 * Set keyguard status view alpha. 134 */ setAlpha(float alpha)135 public void setAlpha(float alpha) { 136 if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) { 137 // If we're capable of performing the SmartSpace shared element transition, and we are 138 // going to (we're swiping to dismiss vs. bringing up the PIN screen), then fade out 139 // everything except for the SmartSpace. 140 if (mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) { 141 mView.setChildrenAlphaExcludingClockView(alpha); 142 mKeyguardClockSwitchController.setChildrenAlphaExcludingSmartspace(alpha); 143 } else if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) { 144 // Otherwise, we can just set the alpha for the entire container. 145 mView.setAlpha(alpha); 146 147 // If we previously unlocked with the shared element transition, some child views 148 // might still have alpha = 0f. Set them back to 1f since we're just using the 149 // parent container's alpha. 150 if (mView.getChildrenAlphaExcludingSmartSpace() < 1f) { 151 mView.setChildrenAlphaExcludingClockView(1f); 152 mKeyguardClockSwitchController.setChildrenAlphaExcludingSmartspace(1f); 153 } 154 } 155 } 156 } 157 158 /** 159 * Set pivot x. 160 */ setPivotX(float pivot)161 public void setPivotX(float pivot) { 162 mView.setPivotX(pivot); 163 } 164 165 /** 166 * Set pivot y. 167 */ setPivotY(float pivot)168 public void setPivotY(float pivot) { 169 mView.setPivotY(pivot); 170 } 171 172 /** 173 * Get the clock text size. 174 */ getClockTextSize()175 public float getClockTextSize() { 176 return mKeyguardClockSwitchController.getClockTextSize(); 177 } 178 179 /** 180 * Get the height of the keyguard status view without the notification icon area, as that's 181 * only visible on AOD. 182 */ getLockscreenHeight()183 public int getLockscreenHeight() { 184 return mView.getHeight() - mKeyguardClockSwitchController.getNotificationIconAreaHeight(); 185 } 186 187 /** 188 * Set whether the view accessibility importance mode. 189 */ setStatusAccessibilityImportance(int mode)190 public void setStatusAccessibilityImportance(int mode) { 191 mView.setImportantForAccessibility(mode); 192 } 193 194 /** 195 * Update position of the view with an optional animation 196 */ updatePosition(int x, int y, float scale, boolean animate)197 public void updatePosition(int x, int y, float scale, boolean animate) { 198 PropertyAnimator.setProperty(mView, AnimatableProperty.Y, y, CLOCK_ANIMATION_PROPERTIES, 199 animate); 200 201 mKeyguardClockSwitchController.updatePosition(x, scale, CLOCK_ANIMATION_PROPERTIES, 202 animate); 203 } 204 205 /** 206 * Set the visibility of the keyguard status view based on some new state. 207 */ setKeyguardStatusViewVisibility( int statusBarState, boolean keyguardFadingAway, boolean goingToFullShade, int oldStatusBarState)208 public void setKeyguardStatusViewVisibility( 209 int statusBarState, 210 boolean keyguardFadingAway, 211 boolean goingToFullShade, 212 int oldStatusBarState) { 213 mKeyguardVisibilityHelper.setViewVisibility( 214 statusBarState, keyguardFadingAway, goingToFullShade, oldStatusBarState); 215 } 216 refreshTime()217 private void refreshTime() { 218 mKeyguardClockSwitchController.refresh(); 219 } 220 221 private final ConfigurationController.ConfigurationListener mConfigurationListener = 222 new ConfigurationController.ConfigurationListener() { 223 @Override 224 public void onLocaleListChanged() { 225 refreshTime(); 226 } 227 228 @Override 229 public void onDensityOrFontScaleChanged() { 230 mKeyguardClockSwitchController.onDensityOrFontScaleChanged(); 231 } 232 }; 233 234 private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { 235 @Override 236 public void onLockScreenModeChanged(int mode) { 237 mKeyguardSliceViewController.updateLockScreenMode(mode); 238 } 239 240 @Override 241 public void onTimeChanged() { 242 refreshTime(); 243 } 244 245 @Override 246 public void onTimeFormatChanged(String timeFormat) { 247 mKeyguardClockSwitchController.refreshFormat(); 248 } 249 250 @Override 251 public void onTimeZoneChanged(TimeZone timeZone) { 252 mKeyguardClockSwitchController.updateTimeZone(timeZone); 253 } 254 255 @Override 256 public void onKeyguardVisibilityChanged(boolean showing) { 257 if (showing) { 258 if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing); 259 refreshTime(); 260 } 261 } 262 263 @Override 264 public void onUserSwitchComplete(int userId) { 265 mKeyguardClockSwitchController.refreshFormat(); 266 } 267 }; 268 269 private KeyguardStateController.Callback mKeyguardStateControllerCallback = 270 new KeyguardStateController.Callback() { 271 @Override 272 public void onKeyguardShowingChanged() { 273 // If we explicitly re-show the keyguard, make sure that all the child views are 274 // visible. They might have been animating out as part of the SmartSpace shared 275 // element transition. 276 if (mKeyguardStateController.isShowing()) { 277 mView.setChildrenAlphaExcludingClockView(1f); 278 } 279 } 280 }; 281 282 /** 283 * Rect that specifies how KSV should be clipped, on its parent's coordinates. 284 */ setClipBounds(Rect clipBounds)285 public void setClipBounds(Rect clipBounds) { 286 if (clipBounds != null) { 287 mClipBounds.set(clipBounds.left, (int) (clipBounds.top - mView.getY()), 288 clipBounds.right, (int) (clipBounds.bottom - mView.getY())); 289 mView.setClipBounds(mClipBounds); 290 } else { 291 mView.setClipBounds(null); 292 } 293 } 294 } 295