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