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.annotation.CallSuper; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.content.res.ColorStateList; 23 import android.content.res.Resources; 24 import android.telephony.TelephonyManager; 25 import android.text.TextUtils; 26 import android.util.Log; 27 import android.view.inputmethod.InputMethodManager; 28 29 import com.android.internal.util.LatencyTracker; 30 import com.android.internal.widget.LockPatternUtils; 31 import com.android.keyguard.KeyguardSecurityModel.SecurityMode; 32 import com.android.systemui.R; 33 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor; 34 import com.android.systemui.bouncer.ui.BouncerMessageView; 35 import com.android.systemui.bouncer.ui.binder.BouncerMessageViewBinder; 36 import com.android.systemui.classifier.FalsingCollector; 37 import com.android.systemui.dagger.qualifiers.Main; 38 import com.android.systemui.flags.FeatureFlags; 39 import com.android.systemui.flags.Flags; 40 import com.android.systemui.log.BouncerLogger; 41 import com.android.systemui.statusbar.policy.DevicePostureController; 42 import com.android.systemui.util.ViewController; 43 import com.android.systemui.util.concurrency.DelayableExecutor; 44 45 import javax.inject.Inject; 46 47 48 /** Controller for a {@link KeyguardSecurityView}. */ 49 public abstract class KeyguardInputViewController<T extends KeyguardInputView> 50 extends ViewController<T> implements KeyguardSecurityView { 51 52 private final SecurityMode mSecurityMode; 53 private final KeyguardSecurityCallback mKeyguardSecurityCallback; 54 private final EmergencyButton mEmergencyButton; 55 private final EmergencyButtonController mEmergencyButtonController; 56 private boolean mPaused; 57 protected KeyguardMessageAreaController<BouncerKeyguardMessageArea> mMessageAreaController; 58 59 // The following is used to ignore callbacks from SecurityViews that are no longer current 60 // (e.g. face unlock). This avoids unwanted asynchronous events from messing with the 61 // state for the current security method. 62 private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {}; 63 private final FeatureFlags mFeatureFlags; 64 KeyguardInputViewController(T view, SecurityMode securityMode, KeyguardSecurityCallback keyguardSecurityCallback, EmergencyButtonController emergencyButtonController, @Nullable KeyguardMessageAreaController.Factory messageAreaControllerFactory, FeatureFlags featureFlags)65 protected KeyguardInputViewController(T view, SecurityMode securityMode, 66 KeyguardSecurityCallback keyguardSecurityCallback, 67 EmergencyButtonController emergencyButtonController, 68 @Nullable KeyguardMessageAreaController.Factory messageAreaControllerFactory, 69 FeatureFlags featureFlags) { 70 super(view); 71 mSecurityMode = securityMode; 72 mKeyguardSecurityCallback = keyguardSecurityCallback; 73 mEmergencyButton = view == null ? null : view.findViewById(R.id.emergency_call_button); 74 mEmergencyButtonController = emergencyButtonController; 75 mFeatureFlags = featureFlags; 76 if (messageAreaControllerFactory != null) { 77 try { 78 BouncerKeyguardMessageArea kma = view.requireViewById(R.id.bouncer_message_area); 79 mMessageAreaController = messageAreaControllerFactory.create(kma); 80 mMessageAreaController.init(); 81 mMessageAreaController.setIsVisible(true); 82 } catch (IllegalArgumentException exception) { 83 Log.e("KeyguardInputViewController", 84 "Ensure that a BouncerKeyguardMessageArea is included in the layout"); 85 } 86 } 87 } 88 89 @Override onInit()90 protected void onInit() { 91 mEmergencyButtonController.init(); 92 } 93 94 @Override 95 @CallSuper onViewAttached()96 protected void onViewAttached() { 97 updateMessageAreaVisibility(); 98 if (TextUtils.isEmpty(mMessageAreaController.getMessage()) 99 && getInitialMessageResId() != 0) { 100 mMessageAreaController.setMessage( 101 mView.getResources().getString(getInitialMessageResId()), 102 /* animate= */ false); 103 } 104 } 105 updateMessageAreaVisibility()106 private void updateMessageAreaVisibility() { 107 if (mMessageAreaController == null) return; 108 if (mFeatureFlags.isEnabled(Flags.REVAMPED_BOUNCER_MESSAGES)) { 109 mMessageAreaController.disable(); 110 } else { 111 mMessageAreaController.setIsVisible(true); 112 } 113 } 114 115 116 @Override onViewDetached()117 protected void onViewDetached() { 118 } 119 getSecurityMode()120 SecurityMode getSecurityMode() { 121 return mSecurityMode; 122 } 123 getKeyguardSecurityCallback()124 protected KeyguardSecurityCallback getKeyguardSecurityCallback() { 125 if (mPaused) { 126 return mNullCallback; 127 } 128 129 return mKeyguardSecurityCallback; 130 } 131 132 @Override reset()133 public void reset() { 134 mMessageAreaController.setMessage("", false); 135 } 136 137 @Override onPause()138 public void onPause() { 139 mPaused = true; 140 } 141 142 @Override onResume(int reason)143 public void onResume(int reason) { 144 mPaused = false; 145 } 146 147 @Override showPromptReason(int reason)148 public void showPromptReason(int reason) { 149 } 150 151 @Override showMessage(CharSequence message, ColorStateList colorState, boolean animated)152 public void showMessage(CharSequence message, ColorStateList colorState, boolean animated) { 153 } 154 startAppearAnimation()155 public void startAppearAnimation() { 156 mView.startAppearAnimation(); 157 } 158 startDisappearAnimation(Runnable finishRunnable)159 public boolean startDisappearAnimation(Runnable finishRunnable) { 160 return mView.startDisappearAnimation(finishRunnable); 161 } 162 163 @Override getTitle()164 public CharSequence getTitle() { 165 return mView.getTitle(); 166 } 167 168 /** Finds the index of this view in the suppplied parent view. */ getIndexIn(KeyguardSecurityViewFlipper view)169 public int getIndexIn(KeyguardSecurityViewFlipper view) { 170 return view.indexOfChild(mView); 171 } 172 173 /** Determines the message to show in the bouncer when it first appears. */ getInitialMessageResId()174 protected abstract int getInitialMessageResId(); 175 176 /** 177 * Binds the {@link KeyguardInputView#getBouncerMessageView()} view with the provided context. 178 */ bindMessageView( @onNull BouncerMessageInteractor bouncerMessageInteractor, KeyguardMessageAreaController.Factory messageAreaControllerFactory, BouncerLogger bouncerLogger, FeatureFlags featureFlags)179 public void bindMessageView( 180 @NonNull BouncerMessageInteractor bouncerMessageInteractor, 181 KeyguardMessageAreaController.Factory messageAreaControllerFactory, 182 BouncerLogger bouncerLogger, 183 FeatureFlags featureFlags) { 184 BouncerMessageView bouncerMessageView = (BouncerMessageView) mView.getBouncerMessageView(); 185 if (bouncerMessageView != null) { 186 BouncerMessageViewBinder.bind(bouncerMessageView, 187 bouncerMessageInteractor, 188 messageAreaControllerFactory, 189 bouncerLogger, 190 featureFlags); 191 } 192 } 193 194 /** Factory for a {@link KeyguardInputViewController}. */ 195 public static class Factory { 196 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; 197 private final LockPatternUtils mLockPatternUtils; 198 private final LatencyTracker mLatencyTracker; 199 private final KeyguardMessageAreaController.Factory mMessageAreaControllerFactory; 200 private final InputMethodManager mInputMethodManager; 201 private final DelayableExecutor mMainExecutor; 202 private final Resources mResources; 203 private final LiftToActivateListener mLiftToActivateListener; 204 private final TelephonyManager mTelephonyManager; 205 private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory; 206 private final FalsingCollector mFalsingCollector; 207 private final DevicePostureController mDevicePostureController; 208 private final KeyguardViewController mKeyguardViewController; 209 private final FeatureFlags mFeatureFlags; 210 211 @Inject Factory(KeyguardUpdateMonitor keyguardUpdateMonitor, LockPatternUtils lockPatternUtils, LatencyTracker latencyTracker, KeyguardMessageAreaController.Factory messageAreaControllerFactory, InputMethodManager inputMethodManager, @Main DelayableExecutor mainExecutor, @Main Resources resources, LiftToActivateListener liftToActivateListener, TelephonyManager telephonyManager, FalsingCollector falsingCollector, EmergencyButtonController.Factory emergencyButtonControllerFactory, DevicePostureController devicePostureController, KeyguardViewController keyguardViewController, FeatureFlags featureFlags)212 public Factory(KeyguardUpdateMonitor keyguardUpdateMonitor, 213 LockPatternUtils lockPatternUtils, 214 LatencyTracker latencyTracker, 215 KeyguardMessageAreaController.Factory messageAreaControllerFactory, 216 InputMethodManager inputMethodManager, @Main DelayableExecutor mainExecutor, 217 @Main Resources resources, LiftToActivateListener liftToActivateListener, 218 TelephonyManager telephonyManager, FalsingCollector falsingCollector, 219 EmergencyButtonController.Factory emergencyButtonControllerFactory, 220 DevicePostureController devicePostureController, 221 KeyguardViewController keyguardViewController, 222 FeatureFlags featureFlags) { 223 mKeyguardUpdateMonitor = keyguardUpdateMonitor; 224 mLockPatternUtils = lockPatternUtils; 225 mLatencyTracker = latencyTracker; 226 mMessageAreaControllerFactory = messageAreaControllerFactory; 227 mInputMethodManager = inputMethodManager; 228 mMainExecutor = mainExecutor; 229 mResources = resources; 230 mLiftToActivateListener = liftToActivateListener; 231 mTelephonyManager = telephonyManager; 232 mEmergencyButtonControllerFactory = emergencyButtonControllerFactory; 233 mFalsingCollector = falsingCollector; 234 mDevicePostureController = devicePostureController; 235 mKeyguardViewController = keyguardViewController; 236 mFeatureFlags = featureFlags; 237 } 238 239 /** Create a new {@link KeyguardInputViewController}. */ create(KeyguardInputView keyguardInputView, SecurityMode securityMode, KeyguardSecurityCallback keyguardSecurityCallback)240 public KeyguardInputViewController create(KeyguardInputView keyguardInputView, 241 SecurityMode securityMode, KeyguardSecurityCallback keyguardSecurityCallback) { 242 EmergencyButtonController emergencyButtonController = 243 mEmergencyButtonControllerFactory.create( 244 keyguardInputView.findViewById(R.id.emergency_call_button)); 245 246 if (keyguardInputView instanceof KeyguardPatternView) { 247 return new KeyguardPatternViewController((KeyguardPatternView) keyguardInputView, 248 mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, 249 keyguardSecurityCallback, mLatencyTracker, mFalsingCollector, 250 emergencyButtonController, mMessageAreaControllerFactory, 251 mDevicePostureController, mFeatureFlags); 252 } else if (keyguardInputView instanceof KeyguardPasswordView) { 253 return new KeyguardPasswordViewController((KeyguardPasswordView) keyguardInputView, 254 mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, 255 keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker, 256 mInputMethodManager, emergencyButtonController, mMainExecutor, mResources, 257 mFalsingCollector, mKeyguardViewController, 258 mFeatureFlags); 259 } else if (keyguardInputView instanceof KeyguardPINView) { 260 return new KeyguardPinViewController((KeyguardPINView) keyguardInputView, 261 mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, 262 keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker, 263 mLiftToActivateListener, emergencyButtonController, mFalsingCollector, 264 mDevicePostureController, mFeatureFlags); 265 } else if (keyguardInputView instanceof KeyguardSimPinView) { 266 return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView, 267 mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, 268 keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker, 269 mLiftToActivateListener, mTelephonyManager, mFalsingCollector, 270 emergencyButtonController, mFeatureFlags); 271 } else if (keyguardInputView instanceof KeyguardSimPukView) { 272 return new KeyguardSimPukViewController((KeyguardSimPukView) keyguardInputView, 273 mKeyguardUpdateMonitor, securityMode, mLockPatternUtils, 274 keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker, 275 mLiftToActivateListener, mTelephonyManager, mFalsingCollector, 276 emergencyButtonController, mFeatureFlags); 277 } 278 279 throw new RuntimeException("Unable to find controller for " + keyguardInputView); 280 } 281 } 282 } 283