diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-06-02 19:09:38 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-06-02 19:09:38 +0000 |
commit | ac0ac8b8ac20a79b5f9a822ec329f8b963122555 (patch) | |
tree | fe9dcd42d12a0cb488cdcd86ddc8b31956b04ff2 | |
parent | 1e837f1e91c305f0831b4dca6328999aa6bcf560 (diff) | |
parent | cb16bf0263d4966301e9f079b272686777e39fd4 (diff) | |
download | base-android12-qpr3-s5-release.tar.gz |
Merge cherrypicks of [18231932, 18439684, 18699572] into sparse-8599181-L64200000954895490.android-12.1.0_r9android-12.1.0_r21android12-qpr3-s5-releaseandroid12-qpr3-s3-release
Change-Id: Idc08019a87950410cb7e9907ad0b2e686959f9e6
16 files changed, 87 insertions, 439 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java index 520234bcf050..6b5bec99e674 100644 --- a/core/java/android/hardware/biometrics/BiometricPrompt.java +++ b/core/java/android/hardware/biometrics/BiometricPrompt.java @@ -421,18 +421,6 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan } /** - * Set if BiometricPrompt is being used by the legacy fingerprint manager API. - * @param sensorId sensor id - * @return This builder. - * @hide - */ - @NonNull - public Builder setIsForLegacyFingerprintManager(int sensorId) { - mPromptInfo.setIsForLegacyFingerprintManager(sensorId); - return this; - } - - /** * Creates a {@link BiometricPrompt}. * * @return An instance of {@link BiometricPrompt}. @@ -873,36 +861,28 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan @NonNull @CallbackExecutor Executor executor, @NonNull AuthenticationCallback callback, int userId) { - if (cancel == null) { - throw new IllegalArgumentException("Must supply a cancellation signal"); - } - if (executor == null) { - throw new IllegalArgumentException("Must supply an executor"); - } - if (callback == null) { - throw new IllegalArgumentException("Must supply a callback"); - } - - authenticateInternal(0 /* operationId */, cancel, executor, callback, userId); + authenticateUserForOperation(cancel, executor, callback, userId, 0 /* operationId */); } /** - * Authenticates for the given keystore operation. + * Authenticates for the given user and keystore operation. * * @param cancel An object that can be used to cancel authentication * @param executor An executor to handle callback events * @param callback An object to receive authentication events + * @param userId The user to authenticate * @param operationId The keystore operation associated with authentication * * @return A requestId that can be used to cancel this operation. * * @hide */ - @RequiresPermission(USE_BIOMETRIC) - public long authenticateForOperation( + @RequiresPermission(USE_BIOMETRIC_INTERNAL) + public long authenticateUserForOperation( @NonNull CancellationSignal cancel, @NonNull @CallbackExecutor Executor executor, @NonNull AuthenticationCallback callback, + int userId, long operationId) { if (cancel == null) { throw new IllegalArgumentException("Must supply a cancellation signal"); @@ -914,7 +894,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan throw new IllegalArgumentException("Must supply a callback"); } - return authenticateInternal(operationId, cancel, executor, callback, mContext.getUserId()); + return authenticateInternal(operationId, cancel, executor, callback, userId); } /** @@ -1048,7 +1028,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan private void cancelAuthentication(long requestId) { if (mService != null) { try { - mService.cancelAuthentication(mToken, mContext.getPackageName(), requestId); + mService.cancelAuthentication(mToken, mContext.getOpPackageName(), requestId); } catch (RemoteException e) { Log.e(TAG, "Unable to cancel authentication", e); } @@ -1107,7 +1087,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan } final long authId = mService.authenticate(mToken, operationId, userId, - mBiometricServiceReceiver, mContext.getPackageName(), promptInfo); + mBiometricServiceReceiver, mContext.getOpPackageName(), promptInfo); cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId)); return authId; } catch (RemoteException e) { diff --git a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl index b336a9f21b60..3d9517f29548 100644 --- a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl +++ b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl @@ -19,7 +19,7 @@ package android.hardware.biometrics; * ITestSession callback for FingerprintManager and BiometricManager. * @hide */ -oneway interface ITestSessionCallback { +interface ITestSessionCallback { void onCleanupStarted(int userId); void onCleanupFinished(int userId); } diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java index 2742f0effde6..e6b762a64384 100644 --- a/core/java/android/hardware/biometrics/PromptInfo.java +++ b/core/java/android/hardware/biometrics/PromptInfo.java @@ -46,7 +46,6 @@ public class PromptInfo implements Parcelable { @NonNull private List<Integer> mAllowedSensorIds = new ArrayList<>(); private boolean mAllowBackgroundAuthentication; private boolean mIgnoreEnrollmentState; - private boolean mIsForLegacyFingerprintManager = false; public PromptInfo() { @@ -69,7 +68,6 @@ public class PromptInfo implements Parcelable { mAllowedSensorIds = in.readArrayList(Integer.class.getClassLoader()); mAllowBackgroundAuthentication = in.readBoolean(); mIgnoreEnrollmentState = in.readBoolean(); - mIsForLegacyFingerprintManager = in.readBoolean(); } public static final Creator<PromptInfo> CREATOR = new Creator<PromptInfo>() { @@ -107,15 +105,10 @@ public class PromptInfo implements Parcelable { dest.writeList(mAllowedSensorIds); dest.writeBoolean(mAllowBackgroundAuthentication); dest.writeBoolean(mIgnoreEnrollmentState); - dest.writeBoolean(mIsForLegacyFingerprintManager); } public boolean containsTestConfigurations() { - if (mIsForLegacyFingerprintManager - && mAllowedSensorIds.size() == 1 - && !mAllowBackgroundAuthentication) { - return false; - } else if (!mAllowedSensorIds.isEmpty()) { + if (!mAllowedSensorIds.isEmpty()) { return true; } else if (mAllowBackgroundAuthentication) { return true; @@ -195,8 +188,7 @@ public class PromptInfo implements Parcelable { } public void setAllowedSensorIds(@NonNull List<Integer> sensorIds) { - mAllowedSensorIds.clear(); - mAllowedSensorIds.addAll(sensorIds); + mAllowedSensorIds = sensorIds; } public void setAllowBackgroundAuthentication(boolean allow) { @@ -207,12 +199,6 @@ public class PromptInfo implements Parcelable { mIgnoreEnrollmentState = ignoreEnrollmentState; } - public void setIsForLegacyFingerprintManager(int sensorId) { - mIsForLegacyFingerprintManager = true; - mAllowedSensorIds.clear(); - mAllowedSensorIds.add(sensorId); - } - // Getters public CharSequence getTitle() { @@ -286,8 +272,4 @@ public class PromptInfo implements Parcelable { public boolean isIgnoreEnrollmentState() { return mIgnoreEnrollmentState; } - - public boolean isForLegacyFingerprintManager() { - return mIsForLegacyFingerprintManager; - } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index 7ab214e94230..df20b83a36ca 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -134,7 +134,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, private class BiometricTaskStackListener extends TaskStackListener { @Override public void onTaskStackChanged() { - mHandler.post(AuthController.this::cancelIfOwnerIsNotInForeground); + mHandler.post(AuthController.this::handleTaskStackChanged); } } @@ -181,7 +181,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, } }; - private void cancelIfOwnerIsNotInForeground() { + private void handleTaskStackChanged() { mExecution.assertIsMainThread(); if (mCurrentDialog != null) { try { @@ -193,7 +193,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, final String topPackage = runningTasks.get(0).topActivity.getPackageName(); if (!topPackage.contentEquals(clientPackage) && !Utils.isSystem(mContext, clientPackage)) { - Log.e(TAG, "Evicting client due to: " + topPackage); + Log.w(TAG, "Evicting client due to: " + topPackage); mCurrentDialog.dismissWithoutCallback(true /* animate */); mCurrentDialog = null; mOrientationListener.disable(); @@ -814,10 +814,6 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks, mCurrentDialog = newDialog; mCurrentDialog.show(mWindowManager, savedState); mOrientationListener.enable(); - - if (!promptInfo.isAllowBackgroundAuthentication()) { - mHandler.post(this::cancelIfOwnerIsNotInForeground); - } } private void onDialogDismissed(@DismissedReason int reason) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java index 2b7c984f04b1..08c77146d34c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -555,25 +555,15 @@ public class AuthControllerTest extends SysuiTestCase { } @Test - public void testClientNotified_whenTaskStackChangesDuringShow() throws Exception { - switchTask("other_package"); - showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); - - mTestableLooper.processAllMessages(); - - assertNull(mAuthController.mCurrentDialog); - assertNull(mAuthController.mReceiver); - verify(mDialog1).dismissWithoutCallback(true /* animate */); - verify(mReceiver).onDialogDismissed( - eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL), - eq(null) /* credentialAttestation */); - } - - @Test public void testClientNotified_whenTaskStackChangesDuringAuthentication() throws Exception { showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */); - switchTask("other_package"); + List<ActivityManager.RunningTaskInfo> tasks = new ArrayList<>(); + ActivityManager.RunningTaskInfo taskInfo = mock(ActivityManager.RunningTaskInfo.class); + taskInfo.topActivity = mock(ComponentName.class); + when(taskInfo.topActivity.getPackageName()).thenReturn("other_package"); + tasks.add(taskInfo); + when(mActivityTaskManager.getTasks(anyInt())).thenReturn(tasks); mAuthController.mTaskStackListener.onTaskStackChanged(); mTestableLooper.processAllMessages(); @@ -650,16 +640,6 @@ public class AuthControllerTest extends SysuiTestCase { BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT); } - private void switchTask(String packageName) { - final List<ActivityManager.RunningTaskInfo> tasks = new ArrayList<>(); - final ActivityManager.RunningTaskInfo taskInfo = - mock(ActivityManager.RunningTaskInfo.class); - taskInfo.topActivity = mock(ComponentName.class); - when(taskInfo.topActivity.getPackageName()).thenReturn(packageName); - tasks.add(taskInfo); - when(mActivityTaskManager.getTasks(anyInt())).thenReturn(tasks); - } - private PromptInfo createTestPromptInfo() { PromptInfo promptInfo = new PromptInfo(); diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java index 92c8c9bb57ec..358263df916b 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java @@ -118,7 +118,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> mIsStrongBiometric = isStrongBiometric; mOperationId = operationId; mRequireConfirmation = requireConfirmation; - mActivityTaskManager = getActivityTaskManager(); + mActivityTaskManager = ActivityTaskManager.getInstance(); mBiometricManager = context.getSystemService(BiometricManager.class); mTaskStackListener = taskStackListener; mLockoutTracker = lockoutTracker; @@ -146,10 +146,6 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> return mStartTimeMs; } - protected ActivityTaskManager getActivityTaskManager() { - return ActivityTaskManager.getInstance(); - } - @Override public void binderDied() { final boolean clearListener = !isBiometricPrompt(); @@ -326,50 +322,45 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> sendCancelOnly(listener); } }); - } else { // not authenticated - if (isBackgroundAuth) { - Slog.e(TAG, "cancelling due to background auth"); - cancel(); - } else { - // Allow system-defined limit of number of attempts before giving up - final @LockoutTracker.LockoutMode int lockoutMode = - handleFailedAttempt(getTargetUserId()); - if (lockoutMode != LockoutTracker.LOCKOUT_NONE) { - markAlreadyDone(); - } + } else { + // Allow system-defined limit of number of attempts before giving up + final @LockoutTracker.LockoutMode int lockoutMode = + handleFailedAttempt(getTargetUserId()); + if (lockoutMode != LockoutTracker.LOCKOUT_NONE) { + markAlreadyDone(); + } - final CoexCoordinator coordinator = CoexCoordinator.getInstance(); - coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode, - new CoexCoordinator.Callback() { - @Override - public void sendAuthenticationResult(boolean addAuthTokenIfStrong) { - if (listener != null) { - try { - listener.onAuthenticationFailed(getSensorId()); - } catch (RemoteException e) { - Slog.e(TAG, "Unable to notify listener", e); - } - } - } + final CoexCoordinator coordinator = CoexCoordinator.getInstance(); + coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode, + new CoexCoordinator.Callback() { + @Override + public void sendAuthenticationResult(boolean addAuthTokenIfStrong) { + if (listener != null) { + try { + listener.onAuthenticationFailed(getSensorId()); + } catch (RemoteException e) { + Slog.e(TAG, "Unable to notify listener", e); + } + } + } - @Override - public void sendHapticFeedback() { - if (listener != null && mShouldVibrate) { - vibrateError(); - } - } + @Override + public void sendHapticFeedback() { + if (listener != null && mShouldVibrate) { + vibrateError(); + } + } - @Override - public void handleLifecycleAfterAuth() { - AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */); - } + @Override + public void handleLifecycleAfterAuth() { + AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */); + } - @Override - public void sendAuthenticationCanceled() { - sendCancelOnly(listener); - } - }); - } + @Override + public void sendAuthenticationCanceled() { + sendCancelOnly(listener); + } + }); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java index 3a93d82a68ee..b44f4dc68274 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java @@ -331,12 +331,12 @@ public class FingerprintService extends SystemService { provider.second.getSensorProperties(sensorId); if (!isKeyguard && !Utils.isSettings(getContext(), opPackageName) && sensorProps != null && sensorProps.isAnyUdfpsType()) { + identity = Binder.clearCallingIdentity(); try { return authenticateWithPrompt(operationId, sensorProps, userId, receiver, - opPackageName, ignoreEnrollmentState); - } catch (PackageManager.NameNotFoundException e) { - Slog.e(TAG, "Invalid package", e); - return -1; + ignoreEnrollmentState); + } finally { + Binder.restoreCallingIdentity(identity); } } return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId, @@ -349,15 +349,12 @@ public class FingerprintService extends SystemService { @NonNull final FingerprintSensorPropertiesInternal props, final int userId, final IFingerprintServiceReceiver receiver, - final String opPackageName, - boolean ignoreEnrollmentState) throws PackageManager.NameNotFoundException { + boolean ignoreEnrollmentState) { final Context context = getUiContext(); - final Context promptContext = context.createPackageContextAsUser( - opPackageName, 0 /* flags */, UserHandle.getUserHandleForUid(userId)); final Executor executor = context.getMainExecutor(); - final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(promptContext) + final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(context) .setTitle(context.getString(R.string.biometric_dialog_default_title)) .setSubtitle(context.getString(R.string.fingerprint_dialog_default_subtitle)) .setNegativeButton( @@ -371,7 +368,8 @@ public class FingerprintService extends SystemService { Slog.e(TAG, "Remote exception in negative button onClick()", e); } }) - .setIsForLegacyFingerprintManager(props.sensorId) + .setAllowedSensorIds(new ArrayList<>( + Collections.singletonList(props.sensorId))) .setIgnoreEnrollmentState(ignoreEnrollmentState) .build(); @@ -425,8 +423,8 @@ public class FingerprintService extends SystemService { } }; - return biometricPrompt.authenticateForOperation( - new CancellationSignal(), executor, promptCallback, operationId); + return biometricPrompt.authenticateUserForOperation( + new CancellationSignal(), executor, promptCallback, userId, operationId); } @Override diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 3c2631904f42..0fda3a36b8e9 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -246,7 +246,6 @@ import android.util.Log; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; -import android.util.SparseBooleanArray; import android.util.StatsEvent; import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; @@ -278,7 +277,6 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.internal.util.function.TriPredicate; -import com.android.internal.widget.LockPatternUtils; import com.android.server.DeviceIdleInternal; import com.android.server.EventLogTags; import com.android.server.IoThread; @@ -1890,54 +1888,6 @@ public class NotificationManagerService extends SystemService { private SettingsObserver mSettingsObserver; protected ZenModeHelper mZenModeHelper; - protected class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker { - - SparseBooleanArray mUserInLockDownMode = new SparseBooleanArray(); - boolean mIsInLockDownMode = false; - - StrongAuthTracker(Context context) { - super(context); - } - - private boolean containsFlag(int haystack, int needle) { - return (haystack & needle) != 0; - } - - public boolean isInLockDownMode() { - return mIsInLockDownMode; - } - - @Override - public synchronized void onStrongAuthRequiredChanged(int userId) { - boolean userInLockDownModeNext = containsFlag(getStrongAuthForUser(userId), - STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); - mUserInLockDownMode.put(userId, userInLockDownModeNext); - boolean isInLockDownModeNext = mUserInLockDownMode.indexOfValue(true) != -1; - - if (mIsInLockDownMode == isInLockDownModeNext) { - return; - } - - if (isInLockDownModeNext) { - cancelNotificationsWhenEnterLockDownMode(); - } - - // When the mIsInLockDownMode is true, both notifyPostedLocked and - // notifyRemovedLocked will be dismissed. So we shall call - // cancelNotificationsWhenEnterLockDownMode before we set mIsInLockDownMode - // as true and call postNotificationsWhenExitLockDownMode after we set - // mIsInLockDownMode as false. - mIsInLockDownMode = isInLockDownModeNext; - - if (!isInLockDownModeNext) { - postNotificationsWhenExitLockDownMode(); - } - } - } - - private LockPatternUtils mLockPatternUtils; - private StrongAuthTracker mStrongAuthTracker; - public NotificationManagerService(Context context) { this(context, new NotificationRecordLoggerImpl(), @@ -1961,11 +1911,6 @@ public class NotificationManagerService extends SystemService { } @VisibleForTesting - void setStrongAuthTracker(StrongAuthTracker strongAuthTracker) { - mStrongAuthTracker = strongAuthTracker; - } - - @VisibleForTesting void setKeyguardManager(KeyguardManager keyguardManager) { mKeyguardManager = keyguardManager; } @@ -2152,8 +2097,6 @@ public class NotificationManagerService extends SystemService { ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); mUiHandler = new Handler(UiThread.get().getLooper()); - mLockPatternUtils = new LockPatternUtils(getContext()); - mStrongAuthTracker = new StrongAuthTracker(getContext()); String[] extractorNames; try { extractorNames = resources.getStringArray(R.array.config_notificationSignalExtractors); @@ -2629,7 +2572,6 @@ public class NotificationManagerService extends SystemService { bubbsExtractor.setShortcutHelper(mShortcutHelper); } registerNotificationPreferencesPullers(); - mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker); } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { // This observer will force an update when observe is called, causing us to // bind to listener services. @@ -9175,29 +9117,6 @@ public class NotificationManagerService extends SystemService { } } - private void cancelNotificationsWhenEnterLockDownMode() { - synchronized (mNotificationLock) { - int numNotifications = mNotificationList.size(); - for (int i = 0; i < numNotifications; i++) { - NotificationRecord rec = mNotificationList.get(i); - mListeners.notifyRemovedLocked(rec, REASON_CANCEL_ALL, - rec.getStats()); - } - - } - } - - private void postNotificationsWhenExitLockDownMode() { - synchronized (mNotificationLock) { - int numNotifications = mNotificationList.size(); - for (int i = 0; i < numNotifications; i++) { - NotificationRecord rec = mNotificationList.get(i); - mListeners.notifyPostedLocked(rec, rec); - } - - } - } - private void updateNotificationPulse() { synchronized (mNotificationLock) { updateLightsLocked(); @@ -9433,10 +9352,6 @@ public class NotificationManagerService extends SystemService { rankings.toArray(new NotificationListenerService.Ranking[0])); } - boolean isInLockDownMode() { - return mStrongAuthTracker.isInLockDownMode(); - } - boolean hasCompanionDevice(ManagedServiceInfo info) { if (mCompanionManager == null) { mCompanionManager = getCompanionManager(); @@ -10488,12 +10403,8 @@ public class NotificationManagerService extends SystemService { * targetting <= O_MR1 */ @GuardedBy("mNotificationLock") - void notifyPostedLocked(NotificationRecord r, NotificationRecord old, + private void notifyPostedLocked(NotificationRecord r, NotificationRecord old, boolean notifyAllListeners) { - if (isInLockDownMode()) { - return; - } - try { // Lazily initialized snapshots of the notification. StatusBarNotification sbn = r.getSbn(); @@ -10591,10 +10502,6 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") public void notifyRemovedLocked(NotificationRecord r, int reason, NotificationStats notificationStats) { - if (isInLockDownMode()) { - return; - } - final StatusBarNotification sbn = r.getSbn(); // make a copy in case changes are made to the underlying Notification object @@ -10640,10 +10547,6 @@ public class NotificationManagerService extends SystemService { */ @GuardedBy("mNotificationLock") public void notifyRankingUpdateLocked(List<NotificationRecord> changedHiddenNotifications) { - if (isInLockDownMode()) { - return; - } - boolean isHiddenRankingUpdate = changedHiddenNotifications != null && changedHiddenNotifications.size() > 0; // TODO (b/73052211): if the ranking update changed the notification type, diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index b184d5c62008..42c6dd43ebce 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -4193,17 +4193,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ @VisibleForTesting SurfaceControl computeImeParent() { - if (mImeLayeringTarget != null && mImeInputTarget != null - && mImeLayeringTarget.mActivityRecord != mImeInputTarget.mActivityRecord) { - // Do not change parent if the window hasn't requested IME. - return null; - } // Attach it to app if the target is part of an app and such app is covering the entire // screen. If it's not covering the entire screen the IME might extend beyond the apps // bounds. if (shouldImeAttachedToApp()) { + if (mImeLayeringTarget.mActivityRecord != mImeInputTarget.mActivityRecord) { + // Do not change parent if the window hasn't requested IME. + return null; + } return mImeLayeringTarget.mActivityRecord.getSurfaceControl(); } + // Otherwise, we just attach it to where the display area policy put it. return mImeWindowsContainer.getParent() != null ? mImeWindowsContainer.getParent().getSurfaceControl() : null; diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 5124841bcbbb..10ae152c3365 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -265,12 +265,14 @@ class InsetsPolicy { return state; } } else if (w.mActivityRecord != null && w.mActivityRecord.mImeInsetsFrozenUntilStartInput) { - // During switching tasks with gestural navigation, before the next IME input target - // starts the input, we should adjust and freeze the last IME visibility of the window - // in case delivering obsoleted IME insets state during transitioning. + // During switching tasks with gestural navigation, if the IME is attached to + // one app window on that time, even the next app window is behind the IME window, + // conceptually the window should not receive the IME insets if the next window is + // not eligible IME requester and ready to show IME on top of it. + final boolean shouldImeAttachedToApp = mDisplayContent.shouldImeAttachedToApp(); final InsetsSource originalImeSource = originalState.peekSource(ITYPE_IME); - if (originalImeSource != null) { + if (shouldImeAttachedToApp && originalImeSource != null) { final boolean imeVisibility = w.mActivityRecord.mLastImeShown || w.getRequestedVisibility(ITYPE_IME); final InsetsState state = copyState ? new InsetsState(originalState) diff --git a/services/tests/uiservicestests/AndroidManifest.xml b/services/tests/uiservicestests/AndroidManifest.xml index e8e3a8f84f21..767857bf2de8 100644 --- a/services/tests/uiservicestests/AndroidManifest.xml +++ b/services/tests/uiservicestests/AndroidManifest.xml @@ -33,7 +33,6 @@ <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" /> <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT"/> <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" /> - <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" /> <application android:debuggable="true"> <uses-library android:name="android.test.runner" /> diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java index eb9847f7eb7e..7c0f29dce1ab 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java @@ -24,14 +24,15 @@ import static com.android.server.notification.NotificationManagerService.Notific import static com.google.common.truth.Truth.assertThat; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -46,11 +47,10 @@ import android.os.Bundle; import android.os.UserHandle; import android.service.notification.NotificationListenerFilter; import android.service.notification.NotificationListenerService; -import android.service.notification.NotificationStats; -import android.service.notification.StatusBarNotification; import android.testing.TestableContext; import android.util.ArraySet; import android.util.Pair; +import android.util.Slog; import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; import android.util.Xml; @@ -61,13 +61,11 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.mockito.internal.util.reflection.FieldSetter; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.util.List; public class NotificationListenersTest extends UiServiceTestCase { @@ -376,66 +374,4 @@ public class NotificationListenersTest extends UiServiceTestCase { verify(mContext).sendBroadcastAsUser( any(), eq(UserHandle.of(userId)), nullable(String.class)); } - - @Test - public void testNotifyPostedLockedInLockdownMode() { - NotificationRecord r = mock(NotificationRecord.class); - NotificationRecord old = mock(NotificationRecord.class); - - // before the lockdown mode - when(mNm.isInLockDownMode()).thenReturn(false); - mListeners.notifyPostedLocked(r, old, true); - mListeners.notifyPostedLocked(r, old, false); - verify(r, atLeast(2)).getSbn(); - - // in the lockdown mode - reset(r); - reset(old); - when(mNm.isInLockDownMode()).thenReturn(true); - mListeners.notifyPostedLocked(r, old, true); - mListeners.notifyPostedLocked(r, old, false); - verify(r, never()).getSbn(); - } - - @Test - public void testnotifyRankingUpdateLockedInLockdownMode() { - List chn = mock(List.class); - - // before the lockdown mode - when(mNm.isInLockDownMode()).thenReturn(false); - mListeners.notifyRankingUpdateLocked(chn); - verify(chn, atLeast(1)).size(); - - // in the lockdown mode - reset(chn); - when(mNm.isInLockDownMode()).thenReturn(true); - mListeners.notifyRankingUpdateLocked(chn); - verify(chn, never()).size(); - } - - @Test - public void testNotifyRemovedLockedInLockdownMode() throws NoSuchFieldException { - NotificationRecord r = mock(NotificationRecord.class); - NotificationStats rs = mock(NotificationStats.class); - StatusBarNotification sbn = mock(StatusBarNotification.class); - FieldSetter.setField(mNm, - NotificationManagerService.class.getDeclaredField("mHandler"), - mock(NotificationManagerService.WorkerHandler.class)); - - // before the lockdown mode - when(mNm.isInLockDownMode()).thenReturn(false); - when(r.getSbn()).thenReturn(sbn); - mListeners.notifyRemovedLocked(r, 0, rs); - mListeners.notifyRemovedLocked(r, 0, rs); - verify(r, atLeast(2)).getSbn(); - - // in the lockdown mode - reset(r); - reset(rs); - when(mNm.isInLockDownMode()).thenReturn(true); - when(r.getSbn()).thenReturn(sbn); - mListeners.notifyRemovedLocked(r, 0, rs); - mListeners.notifyRemovedLocked(r, 0, rs); - verify(r, never()).getSbn(); - } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 9a221a8f2bf9..b98401e76cc2 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -58,13 +58,10 @@ import static android.service.notification.Adjustment.KEY_USER_SENTIMENT; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING; -import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; -import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; - import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; @@ -226,6 +223,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; @@ -411,26 +409,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { interface NotificationAssistantAccessGrantedCallback { void onGranted(ComponentName assistant, int userId, boolean granted, boolean userSet); } - - class StrongAuthTrackerFake extends NotificationManagerService.StrongAuthTracker { - private int mGetStrongAuthForUserReturnValue = 0; - StrongAuthTrackerFake(Context context) { - super(context); - } - - public void setGetStrongAuthForUserReturnValue(int val) { - mGetStrongAuthForUserReturnValue = val; - } - - @Override - public int getStrongAuthForUser(int userId) { - return mGetStrongAuthForUserReturnValue; - } - } } - TestableNotificationManagerService.StrongAuthTrackerFake mStrongAuthTracker; - private class TestableToastCallback extends ITransientNotification.Stub { @Override public void show(IBinder windowToken) { @@ -550,9 +530,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.setAudioManager(mAudioManager); - mStrongAuthTracker = mService.new StrongAuthTrackerFake(mContext); - mService.setStrongAuthTracker(mStrongAuthTracker); - mShortcutHelper = mService.getShortcutHelper(); mShortcutHelper.setLauncherApps(mLauncherApps); mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal); @@ -8377,44 +8354,4 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } } } - - @Test - public void testStrongAuthTracker_isInLockDownMode() { - mStrongAuthTracker.setGetStrongAuthForUserReturnValue( - STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); - mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId()); - assertTrue(mStrongAuthTracker.isInLockDownMode()); - mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0); - mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId()); - assertFalse(mStrongAuthTracker.isInLockDownMode()); - } - - @Test - public void testCancelAndPostNotificationsWhenEnterAndExitLockDownMode() { - // post 2 notifications from 2 packages - NotificationRecord pkgA = new NotificationRecord(mContext, - generateSbn("a", 1000, 9, 0), mTestNotificationChannel); - mService.addNotification(pkgA); - NotificationRecord pkgB = new NotificationRecord(mContext, - generateSbn("b", 1001, 9, 0), mTestNotificationChannel); - mService.addNotification(pkgB); - - // when entering the lockdown mode, cancel the 2 notifications. - mStrongAuthTracker.setGetStrongAuthForUserReturnValue( - STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); - mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId()); - assertTrue(mStrongAuthTracker.isInLockDownMode()); - - // the notifyRemovedLocked function is called twice due to REASON_LOCKDOWN. - ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class); - verify(mListeners, times(2)).notifyRemovedLocked(any(), captor.capture(), any()); - assertEquals(REASON_CANCEL_ALL, captor.getValue().intValue()); - - // exit lockdown mode. - mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0); - mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId()); - - // the notifyPostedLocked function is called twice. - verify(mListeners, times(2)).notifyPostedLocked(any(), any()); - } } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 32cee44ce6ff..b770b3e3a55b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -3065,11 +3065,11 @@ public class ActivityRecordTests extends WindowTestsBase { // Simulate app re-start input or turning screen off/on then unlocked by un-secure // keyguard to back to the app, expect IME insets is not frozen - mDisplayContent.updateImeInputAndControlTarget(app); - assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput); imeSource.setFrame(new Rect(100, 400, 500, 500)); app.getInsetsState().addSource(imeSource); app.getInsetsState().setSourceVisible(ITYPE_IME, true); + mDisplayContent.updateImeInputAndControlTarget(app); + assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput); // Verify when IME is visible and the app can receive the right IME insets from policy. makeWindowVisibleAndDrawn(app, mImeWindow); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 9c0c213c3efe..f3c1ec5b200e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1075,21 +1075,6 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); } - @UseTestDisplay(addWindows = W_ACTIVITY) - @Test - public void testComputeImeParent_inputTargetNotUpdate() throws Exception { - WindowState app1 = createWindow(null, TYPE_BASE_APPLICATION, "app1"); - WindowState app2 = createWindow(null, TYPE_BASE_APPLICATION, "app2"); - doReturn(true).when(mDisplayContent).shouldImeAttachedToApp(); - mDisplayContent.setImeLayeringTarget(app1); - mDisplayContent.setImeInputTarget(app1); - assertEquals(app1.mActivityRecord.getSurfaceControl(), mDisplayContent.computeImeParent()); - mDisplayContent.setImeLayeringTarget(app2); - // Expect null means no change IME parent when the IME layering target not yet - // request IME to be the input target. - assertNull(mDisplayContent.computeImeParent()); - } - @Test public void testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved() throws Exception { final DisplayContent dc = createNewDisplay(); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 03b818843aa2..7d501356d469 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -931,47 +931,6 @@ public class WindowStateTests extends WindowTestsBase { @UseTestDisplay(addWindows = { W_ACTIVITY }) @Test - public void testAdjustImeInsetsVisibilityWhenSwitchingApps_toAppInMultiWindowMode() { - final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); - final WindowState app2 = createWindow(null, WINDOWING_MODE_MULTI_WINDOW, - ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app2"); - final WindowState imeWindow = createWindow(null, TYPE_APPLICATION, "imeWindow"); - spyOn(imeWindow); - doReturn(true).when(imeWindow).isVisible(); - mDisplayContent.mInputMethodWindow = imeWindow; - - final InsetsStateController controller = mDisplayContent.getInsetsStateController(); - controller.getImeSourceProvider().setWindow(imeWindow, null, null); - - // Simulate app2 in multi-window mode is going to background to switch to the fullscreen - // app which requests IME with updating all windows Insets State when IME is above app. - app2.mActivityRecord.mImeInsetsFrozenUntilStartInput = true; - mDisplayContent.setImeLayeringTarget(app); - mDisplayContent.setImeInputTarget(app); - assertTrue(mDisplayContent.shouldImeAttachedToApp()); - controller.getImeSourceProvider().scheduleShowImePostLayout(app); - controller.getImeSourceProvider().getSource().setVisible(true); - controller.updateAboveInsetsState(imeWindow, false); - - // Expect app windows behind IME can receive IME insets visible, - // but not for app2 in background. - assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible()); - assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible()); - - // Simulate app plays closing transition to app2. - // And app2 is now IME layering target but not yet to be the IME input target. - mDisplayContent.setImeLayeringTarget(app2); - app.mActivityRecord.commitVisibility(false, false); - assertTrue(app.mActivityRecord.mLastImeShown); - assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput); - - // Verify the IME insets is still visible on app, but not for app2 during task switching. - assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible()); - assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible()); - } - - @UseTestDisplay(addWindows = {W_ACTIVITY}) - @Test public void testUpdateImeControlTargetWhenLeavingMultiWindow() { WindowState app = createWindow(null, TYPE_BASE_APPLICATION, mAppWindow.mToken, "app"); |