1 /* 2 * Copyright (C) 2021 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 static android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS; 20 import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO; 21 22 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; 23 24 import android.content.res.Configuration; 25 import android.content.res.Resources; 26 import android.database.ContentObserver; 27 import android.hardware.biometrics.BiometricSourceType; 28 import android.os.UserHandle; 29 import android.os.UserManager; 30 import android.provider.Settings; 31 import android.util.MathUtils; 32 import android.view.View; 33 34 import androidx.annotation.NonNull; 35 import androidx.annotation.VisibleForTesting; 36 import androidx.core.animation.Animator; 37 import androidx.core.animation.AnimatorListenerAdapter; 38 import androidx.core.animation.ValueAnimator; 39 40 import com.android.keyguard.CarrierTextController; 41 import com.android.keyguard.KeyguardUpdateMonitor; 42 import com.android.keyguard.KeyguardUpdateMonitorCallback; 43 import com.android.keyguard.logging.KeyguardLogger; 44 import com.android.systemui.R; 45 import com.android.systemui.animation.InterpolatorsAndroidX; 46 import com.android.systemui.battery.BatteryMeterViewController; 47 import com.android.systemui.dagger.qualifiers.Main; 48 import com.android.systemui.plugins.log.LogLevel; 49 import com.android.systemui.plugins.statusbar.StatusBarStateController; 50 import com.android.systemui.shade.NotificationPanelViewController; 51 import com.android.systemui.statusbar.CommandQueue; 52 import com.android.systemui.statusbar.StatusBarState; 53 import com.android.systemui.statusbar.SysuiStatusBarStateController; 54 import com.android.systemui.statusbar.disableflags.DisableStateTracker; 55 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback; 56 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; 57 import com.android.systemui.statusbar.notification.AnimatableProperty; 58 import com.android.systemui.statusbar.notification.PropertyAnimator; 59 import com.android.systemui.statusbar.notification.stack.AnimationProperties; 60 import com.android.systemui.statusbar.notification.stack.StackStateAnimator; 61 import com.android.systemui.statusbar.phone.fragment.StatusBarIconBlocklistKt; 62 import com.android.systemui.statusbar.phone.fragment.StatusBarSystemEventDefaultAnimator; 63 import com.android.systemui.statusbar.policy.BatteryController; 64 import com.android.systemui.statusbar.policy.ConfigurationController; 65 import com.android.systemui.statusbar.policy.KeyguardStateController; 66 import com.android.systemui.statusbar.policy.UserInfoController; 67 import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel; 68 import com.android.systemui.util.ViewController; 69 import com.android.systemui.util.settings.SecureSettings; 70 71 import java.io.PrintWriter; 72 import java.util.ArrayList; 73 import java.util.List; 74 import java.util.concurrent.Executor; 75 76 import javax.inject.Inject; 77 78 import kotlin.Unit; 79 80 /** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */ 81 public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> { 82 private static final String TAG = "KeyguardStatusBarViewController"; 83 private static final AnimationProperties KEYGUARD_HUN_PROPERTIES = 84 new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); 85 86 private float mKeyguardHeadsUpShowingAmount = 0.0f; 87 private final AnimatableProperty mHeadsUpShowingAmountAnimation = AnimatableProperty.from( 88 "KEYGUARD_HEADS_UP_SHOWING_AMOUNT", 89 (view, aFloat) -> { 90 mKeyguardHeadsUpShowingAmount = aFloat; 91 updateViewState(); 92 }, 93 view -> mKeyguardHeadsUpShowingAmount, 94 R.id.keyguard_hun_animator_tag, 95 R.id.keyguard_hun_animator_end_tag, 96 R.id.keyguard_hun_animator_start_tag); 97 98 private final CarrierTextController mCarrierTextController; 99 private final ConfigurationController mConfigurationController; 100 private final SystemStatusAnimationScheduler mAnimationScheduler; 101 private final BatteryController mBatteryController; 102 private final UserInfoController mUserInfoController; 103 private final StatusBarIconController mStatusBarIconController; 104 private final StatusBarIconController.TintedIconManager.Factory mTintedIconManagerFactory; 105 private final BatteryMeterViewController mBatteryMeterViewController; 106 private final NotificationPanelViewController.NotificationPanelViewStateProvider 107 mNotificationPanelViewStateProvider; 108 private final KeyguardStateController mKeyguardStateController; 109 private final KeyguardBypassController mKeyguardBypassController; 110 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; 111 private final BiometricUnlockController mBiometricUnlockController; 112 private final SysuiStatusBarStateController mStatusBarStateController; 113 private final StatusBarContentInsetsProvider mInsetsProvider; 114 private final UserManager mUserManager; 115 private final StatusBarUserChipViewModel mStatusBarUserChipViewModel; 116 private final SecureSettings mSecureSettings; 117 private final CommandQueue mCommandQueue; 118 private final Executor mMainExecutor; 119 private final Object mLock = new Object(); 120 private final KeyguardLogger mLogger; 121 122 private final ConfigurationController.ConfigurationListener mConfigurationListener = 123 new ConfigurationController.ConfigurationListener() { 124 @Override 125 public void onDensityOrFontScaleChanged() { 126 mView.loadDimens(); 127 // The animator is dependent on resources for offsets 128 mSystemEventAnimator = 129 getSystemEventAnimator(mSystemEventAnimator.isAnimationRunning()); 130 } 131 132 @Override 133 public void onThemeChanged() { 134 mView.onOverlayChanged(); 135 KeyguardStatusBarViewController.this.onThemeChanged(); 136 } 137 138 @Override 139 public void onConfigChanged(Configuration newConfig) { 140 updateUserSwitcher(); 141 } 142 }; 143 144 private final SystemStatusAnimationCallback mAnimationCallback = 145 new SystemStatusAnimationCallback() { 146 @NonNull 147 @Override 148 public Animator onSystemEventAnimationFinish(boolean hasPersistentDot) { 149 return mSystemEventAnimator.onSystemEventAnimationFinish(hasPersistentDot); 150 } 151 152 @NonNull 153 @Override 154 public Animator onSystemEventAnimationBegin() { 155 return mSystemEventAnimator.onSystemEventAnimationBegin(); 156 } 157 }; 158 159 private final BatteryController.BatteryStateChangeCallback mBatteryStateChangeCallback = 160 new BatteryController.BatteryStateChangeCallback() { 161 @Override 162 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { 163 mView.onBatteryLevelChanged(charging); 164 } 165 }; 166 167 private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener = 168 (name, picture, userAccount) -> mView.onUserInfoChanged(picture); 169 170 private final ValueAnimator.AnimatorUpdateListener mAnimatorUpdateListener = 171 animation -> { 172 mKeyguardStatusBarAnimateAlpha = 173 (float) ((ValueAnimator) animation).getAnimatedValue(); 174 updateViewState(); 175 }; 176 177 private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback = 178 new KeyguardUpdateMonitorCallback() { 179 @Override 180 public void onBiometricAuthenticated( 181 int userId, 182 BiometricSourceType biometricSourceType, 183 boolean isStrongBiometric) { 184 if (mFirstBypassAttempt 185 && mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed( 186 isStrongBiometric)) { 187 mDelayShowingKeyguardStatusBar = true; 188 } 189 } 190 191 @Override 192 public void onKeyguardVisibilityChanged(boolean visible) { 193 if (visible) { 194 updateUserSwitcher(); 195 } 196 } 197 198 @Override 199 public void onBiometricRunningStateChanged( 200 boolean running, 201 BiometricSourceType biometricSourceType) { 202 boolean keyguardOrShadeLocked = 203 mStatusBarState == KEYGUARD 204 || mStatusBarState == StatusBarState.SHADE_LOCKED; 205 if (!running 206 && mFirstBypassAttempt 207 && keyguardOrShadeLocked 208 && !mDozing 209 && !mDelayShowingKeyguardStatusBar 210 && !mBiometricUnlockController.isBiometricUnlock()) { 211 mFirstBypassAttempt = false; 212 animateKeyguardStatusBarIn(); 213 } 214 } 215 216 @Override 217 public void onFinishedGoingToSleep(int why) { 218 mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled(); 219 mDelayShowingKeyguardStatusBar = false; 220 } 221 }; 222 223 private final StatusBarStateController.StateListener mStatusBarStateListener = 224 new StatusBarStateController.StateListener() { 225 @Override 226 public void onStateChanged(int newState) { 227 mStatusBarState = newState; 228 } 229 }; 230 231 232 private final DisableStateTracker mDisableStateTracker; 233 234 private final List<String> mBlockedIcons = new ArrayList<>(); 235 private final int mNotificationsHeaderCollideDistance; 236 237 private boolean mBatteryListening; 238 private StatusBarIconController.TintedIconManager mTintedIconManager; 239 240 private float mKeyguardStatusBarAnimateAlpha = 1f; 241 /** 242 * If face auth with bypass is running for the first time after you turn on the screen. 243 * (From aod or screen off) 244 */ 245 private boolean mFirstBypassAttempt; 246 /** 247 * If auth happens successfully during {@code mFirstBypassAttempt}, and we should wait until 248 * the keyguard is dismissed to show the status bar. 249 */ 250 private boolean mDelayShowingKeyguardStatusBar; 251 private int mStatusBarState; 252 private boolean mDozing; 253 private boolean mShowingKeyguardHeadsUp; 254 private StatusBarSystemEventDefaultAnimator mSystemEventAnimator; 255 private float mSystemEventAnimatorAlpha = 1; 256 257 /** 258 * The alpha value to be set on the View. If -1, this value is to be ignored. 259 */ 260 private float mExplicitAlpha = -1f; 261 262 @Inject KeyguardStatusBarViewController( KeyguardStatusBarView view, CarrierTextController carrierTextController, ConfigurationController configurationController, SystemStatusAnimationScheduler animationScheduler, BatteryController batteryController, UserInfoController userInfoController, StatusBarIconController statusBarIconController, StatusBarIconController.TintedIconManager.Factory tintedIconManagerFactory, BatteryMeterViewController batteryMeterViewController, NotificationPanelViewController.NotificationPanelViewStateProvider notificationPanelViewStateProvider, KeyguardStateController keyguardStateController, KeyguardBypassController bypassController, KeyguardUpdateMonitor keyguardUpdateMonitor, BiometricUnlockController biometricUnlockController, SysuiStatusBarStateController statusBarStateController, StatusBarContentInsetsProvider statusBarContentInsetsProvider, UserManager userManager, StatusBarUserChipViewModel userChipViewModel, SecureSettings secureSettings, CommandQueue commandQueue, @Main Executor mainExecutor, KeyguardLogger logger )263 public KeyguardStatusBarViewController( 264 KeyguardStatusBarView view, 265 CarrierTextController carrierTextController, 266 ConfigurationController configurationController, 267 SystemStatusAnimationScheduler animationScheduler, 268 BatteryController batteryController, 269 UserInfoController userInfoController, 270 StatusBarIconController statusBarIconController, 271 StatusBarIconController.TintedIconManager.Factory tintedIconManagerFactory, 272 BatteryMeterViewController batteryMeterViewController, 273 NotificationPanelViewController.NotificationPanelViewStateProvider 274 notificationPanelViewStateProvider, 275 KeyguardStateController keyguardStateController, 276 KeyguardBypassController bypassController, 277 KeyguardUpdateMonitor keyguardUpdateMonitor, 278 BiometricUnlockController biometricUnlockController, 279 SysuiStatusBarStateController statusBarStateController, 280 StatusBarContentInsetsProvider statusBarContentInsetsProvider, 281 UserManager userManager, 282 StatusBarUserChipViewModel userChipViewModel, 283 SecureSettings secureSettings, 284 CommandQueue commandQueue, 285 @Main Executor mainExecutor, 286 KeyguardLogger logger 287 ) { 288 super(view); 289 mCarrierTextController = carrierTextController; 290 mConfigurationController = configurationController; 291 mAnimationScheduler = animationScheduler; 292 mBatteryController = batteryController; 293 mUserInfoController = userInfoController; 294 mStatusBarIconController = statusBarIconController; 295 mTintedIconManagerFactory = tintedIconManagerFactory; 296 mBatteryMeterViewController = batteryMeterViewController; 297 mNotificationPanelViewStateProvider = notificationPanelViewStateProvider; 298 mKeyguardStateController = keyguardStateController; 299 mKeyguardBypassController = bypassController; 300 mKeyguardUpdateMonitor = keyguardUpdateMonitor; 301 mBiometricUnlockController = biometricUnlockController; 302 mStatusBarStateController = statusBarStateController; 303 mInsetsProvider = statusBarContentInsetsProvider; 304 mUserManager = userManager; 305 mStatusBarUserChipViewModel = userChipViewModel; 306 mSecureSettings = secureSettings; 307 mCommandQueue = commandQueue; 308 mMainExecutor = mainExecutor; 309 mLogger = logger; 310 311 mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled(); 312 mKeyguardStateController.addCallback( 313 new KeyguardStateController.Callback() { 314 @Override 315 public void onKeyguardFadingAwayChanged() { 316 if (!mKeyguardStateController.isKeyguardFadingAway()) { 317 mFirstBypassAttempt = false; 318 mDelayShowingKeyguardStatusBar = false; 319 } 320 } 321 } 322 ); 323 324 Resources r = getResources(); 325 updateBlockedIcons(); 326 mNotificationsHeaderCollideDistance = r.getDimensionPixelSize( 327 R.dimen.header_notifications_collide_distance); 328 329 mView.setKeyguardUserAvatarEnabled( 330 !mStatusBarUserChipViewModel.getChipEnabled()); 331 mSystemEventAnimator = getSystemEventAnimator(/* isAnimationRunning */ false); 332 333 mDisableStateTracker = new DisableStateTracker( 334 /* mask1= */ DISABLE_SYSTEM_INFO, 335 /* mask2= */ DISABLE2_SYSTEM_ICONS, 336 this::updateViewState 337 ); 338 } 339 340 @Override onInit()341 protected void onInit() { 342 super.onInit(); 343 mCarrierTextController.init(); 344 mBatteryMeterViewController.init(); 345 } 346 347 @Override onViewAttached()348 protected void onViewAttached() { 349 mView.init(mStatusBarUserChipViewModel); 350 mConfigurationController.addCallback(mConfigurationListener); 351 mAnimationScheduler.addCallback(mAnimationCallback); 352 mUserInfoController.addCallback(mOnUserInfoChangedListener); 353 mStatusBarStateController.addCallback(mStatusBarStateListener); 354 mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback); 355 mDisableStateTracker.startTracking(mCommandQueue, mView.getDisplay().getDisplayId()); 356 if (mTintedIconManager == null) { 357 mTintedIconManager = mTintedIconManagerFactory.create( 358 mView.findViewById(R.id.statusIcons), StatusBarLocation.KEYGUARD); 359 mTintedIconManager.setBlockList(getBlockedIcons()); 360 mStatusBarIconController.addIconGroup(mTintedIconManager); 361 } 362 mView.setOnApplyWindowInsetsListener( 363 (view, windowInsets) -> mView.updateWindowInsets(windowInsets, mInsetsProvider)); 364 mSecureSettings.registerContentObserverForUser( 365 Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 366 false, 367 mVolumeSettingObserver, 368 UserHandle.USER_ALL); 369 updateUserSwitcher(); 370 onThemeChanged(); 371 } 372 373 @Override onViewDetached()374 protected void onViewDetached() { 375 mConfigurationController.removeCallback(mConfigurationListener); 376 mAnimationScheduler.removeCallback(mAnimationCallback); 377 mUserInfoController.removeCallback(mOnUserInfoChangedListener); 378 mStatusBarStateController.removeCallback(mStatusBarStateListener); 379 mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback); 380 mDisableStateTracker.stopTracking(mCommandQueue); 381 mSecureSettings.unregisterContentObserver(mVolumeSettingObserver); 382 if (mTintedIconManager != null) { 383 mStatusBarIconController.removeIconGroup(mTintedIconManager); 384 } 385 } 386 387 /** Should be called when the theme changes. */ onThemeChanged()388 public void onThemeChanged() { 389 mView.onThemeChanged(mTintedIconManager); 390 } 391 392 /** Sets whether user switcher is enabled. */ setKeyguardUserSwitcherEnabled(boolean enabled)393 public void setKeyguardUserSwitcherEnabled(boolean enabled) { 394 mView.setKeyguardUserSwitcherEnabled(enabled); 395 } 396 397 /** Sets whether this controller should listen to battery updates. */ setBatteryListening(boolean listening)398 public void setBatteryListening(boolean listening) { 399 if (listening == mBatteryListening) { 400 return; 401 } 402 mBatteryListening = listening; 403 if (mBatteryListening) { 404 mBatteryController.addCallback(mBatteryStateChangeCallback); 405 } else { 406 mBatteryController.removeCallback(mBatteryStateChangeCallback); 407 } 408 } 409 410 /** Set the view to have no top clipping. */ setNoTopClipping()411 public void setNoTopClipping() { 412 mView.setTopClipping(0); 413 } 414 415 /** 416 * Update the view's top clipping based on the value of notificationPanelTop and the view's 417 * current top. 418 * 419 * @param notificationPanelTop the current top of the notification panel view. 420 */ updateTopClipping(int notificationPanelTop)421 public void updateTopClipping(int notificationPanelTop) { 422 mView.setTopClipping(notificationPanelTop - mView.getTop()); 423 } 424 425 /** Sets the dozing state. */ setDozing(boolean dozing)426 public void setDozing(boolean dozing) { 427 mDozing = dozing; 428 } 429 430 /** Animate the keyguard status bar in. */ animateKeyguardStatusBarIn()431 public void animateKeyguardStatusBarIn() { 432 mLogger.log(TAG, LogLevel.DEBUG, "animating status bar in"); 433 if (mDisableStateTracker.isDisabled()) { 434 // If our view is disabled, don't allow us to animate in. 435 return; 436 } 437 mView.setVisibility(View.VISIBLE); 438 mView.setAlpha(0f); 439 ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); 440 anim.addUpdateListener(mAnimatorUpdateListener); 441 anim.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); 442 anim.setInterpolator(InterpolatorsAndroidX.LINEAR_OUT_SLOW_IN); 443 anim.start(); 444 } 445 446 /** Animate the keyguard status bar out. */ animateKeyguardStatusBarOut(long startDelay, long duration)447 public void animateKeyguardStatusBarOut(long startDelay, long duration) { 448 mLogger.log(TAG, LogLevel.DEBUG, "animating status bar out"); 449 ValueAnimator anim = ValueAnimator.ofFloat(mView.getAlpha(), 0f); 450 anim.addUpdateListener(mAnimatorUpdateListener); 451 anim.setStartDelay(startDelay); 452 anim.setDuration(duration); 453 anim.setInterpolator(InterpolatorsAndroidX.LINEAR_OUT_SLOW_IN); 454 anim.addListener(new AnimatorListenerAdapter() { 455 @Override 456 public void onAnimationEnd(Animator animation) { 457 mView.setVisibility(View.INVISIBLE); 458 mView.setAlpha(1f); 459 mKeyguardStatusBarAnimateAlpha = 1f; 460 } 461 }); 462 anim.start(); 463 } 464 465 /** 466 * Updates the {@link KeyguardStatusBarView} state based on what the 467 * {@link NotificationPanelViewController.NotificationPanelViewStateProvider} and other 468 * controllers provide. 469 */ updateViewState()470 public void updateViewState() { 471 if (!isKeyguardShowing()) { 472 return; 473 } 474 475 float alphaQsExpansion = 1 - Math.min( 476 1, mNotificationPanelViewStateProvider.getLockscreenShadeDragProgress() * 2); 477 478 float newAlpha; 479 if (mExplicitAlpha != -1) { 480 newAlpha = mExplicitAlpha; 481 } else { 482 newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion) 483 * mKeyguardStatusBarAnimateAlpha 484 * (1.0f - mKeyguardHeadsUpShowingAmount); 485 } 486 487 if (mSystemEventAnimator.isAnimationRunning()) { 488 newAlpha = Math.min(newAlpha, mSystemEventAnimatorAlpha); 489 } 490 491 boolean hideForBypass = 492 mFirstBypassAttempt && mKeyguardUpdateMonitor.shouldListenForFace() 493 || mDelayShowingKeyguardStatusBar; 494 int newVisibility = 495 newAlpha != 0f 496 && !mDozing 497 && !hideForBypass 498 && !mDisableStateTracker.isDisabled() 499 ? View.VISIBLE : View.INVISIBLE; 500 501 updateViewState(newAlpha, newVisibility); 502 } 503 504 /** 505 * Updates the {@link KeyguardStatusBarView} state based on the provided values. 506 */ updateViewState(float alpha, int visibility)507 public void updateViewState(float alpha, int visibility) { 508 if (mDisableStateTracker.isDisabled()) { 509 visibility = View.INVISIBLE; 510 } 511 mView.setAlpha(alpha); 512 mView.setVisibility(visibility); 513 } 514 515 /** 516 * @return the alpha to be used to fade out the contents on Keyguard (status bar, bottom area) 517 * during swiping up. 518 */ getKeyguardContentsAlpha()519 private float getKeyguardContentsAlpha() { 520 float alpha; 521 if (isKeyguardShowing()) { 522 // When on Keyguard, we hide the header as soon as we expanded close enough to the 523 // header 524 alpha = mNotificationPanelViewStateProvider.getPanelViewExpandedHeight() 525 / (mView.getHeight() + mNotificationsHeaderCollideDistance); 526 } else { 527 // In SHADE_LOCKED, the top card is already really close to the header. Hide it as 528 // soon as we start translating the stack. 529 alpha = mNotificationPanelViewStateProvider.getPanelViewExpandedHeight() 530 / mView.getHeight(); 531 } 532 alpha = MathUtils.saturate(alpha); 533 alpha = (float) Math.pow(alpha, 0.75); 534 return alpha; 535 } 536 537 /** 538 * Updates visibility of the user switcher button based on {@link android.os.UserManager} state. 539 */ updateUserSwitcher()540 private void updateUserSwitcher() { 541 mView.setUserSwitcherEnabled(mUserManager.isUserSwitcherEnabled(getResources().getBoolean( 542 R.bool.qs_show_user_switcher_for_single_user))); 543 } 544 545 @VisibleForTesting updateBlockedIcons()546 void updateBlockedIcons() { 547 List<String> newBlockList = StatusBarIconBlocklistKt 548 .getStatusBarIconBlocklist(getResources(), mSecureSettings); 549 550 synchronized (mLock) { 551 mBlockedIcons.clear(); 552 mBlockedIcons.addAll(newBlockList); 553 } 554 555 mMainExecutor.execute(() -> { 556 if (mTintedIconManager != null) { 557 mTintedIconManager.setBlockList(getBlockedIcons()); 558 } 559 }); 560 } 561 562 @VisibleForTesting getBlockedIcons()563 List<String> getBlockedIcons() { 564 synchronized (mLock) { 565 return new ArrayList<>(mBlockedIcons); 566 } 567 } 568 569 /** 570 Update {@link KeyguardStatusBarView}'s visibility based on whether keyguard is showing and 571 * whether heads up is visible. 572 */ updateForHeadsUp()573 public void updateForHeadsUp() { 574 updateForHeadsUp(true); 575 } 576 updateForHeadsUp(boolean animate)577 void updateForHeadsUp(boolean animate) { 578 boolean showingKeyguardHeadsUp = 579 isKeyguardShowing() && mNotificationPanelViewStateProvider.shouldHeadsUpBeVisible(); 580 if (mShowingKeyguardHeadsUp != showingKeyguardHeadsUp) { 581 mShowingKeyguardHeadsUp = showingKeyguardHeadsUp; 582 if (isKeyguardShowing()) { 583 PropertyAnimator.setProperty( 584 mView, 585 mHeadsUpShowingAmountAnimation, 586 showingKeyguardHeadsUp ? 1.0f : 0.0f, 587 KEYGUARD_HUN_PROPERTIES, 588 animate); 589 } else { 590 PropertyAnimator.applyImmediately(mView, mHeadsUpShowingAmountAnimation, 0.0f); 591 } 592 } 593 } 594 isKeyguardShowing()595 private boolean isKeyguardShowing() { 596 return mStatusBarState == KEYGUARD; 597 } 598 599 /** */ dump(PrintWriter pw, String[] args)600 public void dump(PrintWriter pw, String[] args) { 601 pw.println("KeyguardStatusBarView:"); 602 pw.println(" mBatteryListening: " + mBatteryListening); 603 pw.println(" mExplicitAlpha: " + mExplicitAlpha); 604 pw.println(" alpha: " + mView.getAlpha()); 605 pw.println(" visibility: " + mView.getVisibility()); 606 mView.dump(pw, args); 607 } 608 609 /** 610 * Sets the alpha to be set on the view. 611 * 612 * @param alpha a value between 0 and 1. -1 if the value is to be reset/ignored. 613 */ setAlpha(float alpha)614 public void setAlpha(float alpha) { 615 mExplicitAlpha = alpha; 616 updateViewState(); 617 } 618 619 private final ContentObserver mVolumeSettingObserver = new ContentObserver(null) { 620 @Override 621 public void onChange(boolean selfChange) { 622 updateBlockedIcons(); 623 } 624 }; 625 getSystemEventAnimator(boolean isAnimationRunning)626 private StatusBarSystemEventDefaultAnimator getSystemEventAnimator(boolean isAnimationRunning) { 627 return new StatusBarSystemEventDefaultAnimator(getResources(), (alpha) -> { 628 mSystemEventAnimatorAlpha = alpha; 629 updateViewState(); 630 return Unit.INSTANCE; 631 }, (translationX) -> { 632 mView.setTranslationX(translationX); 633 return Unit.INSTANCE; 634 }, isAnimationRunning); 635 } 636 } 637