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