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.keyguard; 18 19 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; 20 21 import android.view.View; 22 import android.view.ViewPropertyAnimator; 23 24 import com.android.systemui.animation.Interpolators; 25 import com.android.systemui.statusbar.StatusBarState; 26 import com.android.systemui.statusbar.notification.AnimatableProperty; 27 import com.android.systemui.statusbar.notification.PropertyAnimator; 28 import com.android.systemui.statusbar.notification.stack.AnimationProperties; 29 import com.android.systemui.statusbar.notification.stack.StackStateAnimator; 30 import com.android.systemui.statusbar.phone.DozeParameters; 31 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; 32 import com.android.systemui.statusbar.policy.KeyguardStateController; 33 34 /** 35 * Helper class for updating visibility of keyguard views based on keyguard and status bar state. 36 * This logic is shared by both the keyguard status view and the keyguard user switcher. 37 */ 38 public class KeyguardVisibilityHelper { 39 40 private View mView; 41 private final KeyguardStateController mKeyguardStateController; 42 private final DozeParameters mDozeParameters; 43 private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; 44 private boolean mAnimateYPos; 45 private boolean mKeyguardViewVisibilityAnimating; 46 private boolean mLastOccludedState = false; 47 private final AnimationProperties mAnimationProperties = new AnimationProperties(); 48 KeyguardVisibilityHelper(View view, KeyguardStateController keyguardStateController, DozeParameters dozeParameters, UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, boolean animateYPos)49 public KeyguardVisibilityHelper(View view, 50 KeyguardStateController keyguardStateController, 51 DozeParameters dozeParameters, 52 UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, 53 boolean animateYPos) { 54 mView = view; 55 mKeyguardStateController = keyguardStateController; 56 mDozeParameters = dozeParameters; 57 mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController; 58 mAnimateYPos = animateYPos; 59 } 60 isVisibilityAnimating()61 public boolean isVisibilityAnimating() { 62 return mKeyguardViewVisibilityAnimating; 63 } 64 65 /** 66 * Set the visibility of a keyguard view based on some new state. 67 */ setViewVisibility( int statusBarState, boolean keyguardFadingAway, boolean goingToFullShade, int oldStatusBarState)68 public void setViewVisibility( 69 int statusBarState, 70 boolean keyguardFadingAway, 71 boolean goingToFullShade, 72 int oldStatusBarState) { 73 mView.animate().cancel(); 74 boolean isOccluded = mKeyguardStateController.isOccluded(); 75 mKeyguardViewVisibilityAnimating = false; 76 if ((!keyguardFadingAway && oldStatusBarState == KEYGUARD 77 && statusBarState != KEYGUARD) || goingToFullShade) { 78 mKeyguardViewVisibilityAnimating = true; 79 mView.animate() 80 .alpha(0f) 81 .setStartDelay(0) 82 .setDuration(160) 83 .setInterpolator(Interpolators.ALPHA_OUT) 84 .withEndAction( 85 mAnimateKeyguardStatusViewGoneEndRunnable); 86 if (keyguardFadingAway) { 87 mView.animate() 88 .setStartDelay(mKeyguardStateController.getKeyguardFadingAwayDelay()) 89 .setDuration(mKeyguardStateController.getShortenedFadingAwayDuration()) 90 .start(); 91 } 92 } else if (oldStatusBarState == StatusBarState.SHADE_LOCKED && statusBarState == KEYGUARD) { 93 mView.setVisibility(View.VISIBLE); 94 mKeyguardViewVisibilityAnimating = true; 95 mView.setAlpha(0f); 96 mView.animate() 97 .alpha(1f) 98 .setStartDelay(0) 99 .setDuration(320) 100 .setInterpolator(Interpolators.ALPHA_IN) 101 .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable); 102 } else if (statusBarState == KEYGUARD) { 103 if (keyguardFadingAway) { 104 mKeyguardViewVisibilityAnimating = true; 105 ViewPropertyAnimator animator = mView.animate() 106 .alpha(0) 107 .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN) 108 .withEndAction(mAnimateKeyguardStatusViewInvisibleEndRunnable); 109 if (mAnimateYPos) { 110 float target = mView.getY() - mView.getHeight() * 0.05f; 111 int delay = 0; 112 int duration = 125; 113 // We animate the Y property separately using the PropertyAnimator, as the panel 114 // view also needs to update the end position. 115 mAnimationProperties.setDuration(duration).setDelay(delay); 116 PropertyAnimator.cancelAnimation(mView, AnimatableProperty.Y); 117 PropertyAnimator.setProperty(mView, AnimatableProperty.Y, target, 118 mAnimationProperties, 119 true /* animate */); 120 animator.setDuration(duration) 121 .setStartDelay(delay); 122 } 123 animator.start(); 124 } else if (mUnlockedScreenOffAnimationController.shouldAnimateInKeyguard()) { 125 mKeyguardViewVisibilityAnimating = true; 126 127 // Ask the screen off animation controller to animate the keyguard visibility for us 128 // since it may need to be cancelled due to keyguard lifecycle events. 129 mUnlockedScreenOffAnimationController.animateInKeyguard( 130 mView, mAnimateKeyguardStatusViewVisibleEndRunnable); 131 } else if (mLastOccludedState && !isOccluded) { 132 // An activity was displayed over the lock screen, and has now gone away 133 mView.setVisibility(View.VISIBLE); 134 mView.setAlpha(0f); 135 136 mView.animate() 137 .setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP) 138 .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) 139 .alpha(1f) 140 .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable) 141 .start(); 142 } else { 143 mView.setVisibility(View.VISIBLE); 144 mView.setAlpha(1f); 145 } 146 } else { 147 mView.setVisibility(View.GONE); 148 mView.setAlpha(1f); 149 } 150 151 mLastOccludedState = isOccluded; 152 } 153 154 private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = () -> { 155 mKeyguardViewVisibilityAnimating = false; 156 mView.setVisibility(View.INVISIBLE); 157 }; 158 159 private final Runnable mAnimateKeyguardStatusViewGoneEndRunnable = () -> { 160 mKeyguardViewVisibilityAnimating = false; 161 mView.setVisibility(View.GONE); 162 }; 163 164 private final Runnable mAnimateKeyguardStatusViewVisibleEndRunnable = () -> { 165 mKeyguardViewVisibilityAnimating = false; 166 }; 167 } 168