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