From aafeb8261385eec5da43a6c5a1f382a41cf79f51 Mon Sep 17 00:00:00 2001 From: Robin Lee Date: Mon, 30 Jan 2023 15:14:06 +0000 Subject: [PATCH] Revert "Refactor the OnUserUnlock code out of RecentsAnimationDeviceState and" This reverts commit 2a58ddb89ffb0e9a69ae4385ebf6fcd13bc42e52. Reason for revert: b/266987957 Change-Id: I4a4a1f01a693d703f4dc87e8169fbf374729d274 --- .../RecentsAnimationDeviceState.java | 51 ++++++++++- .../quickstep/TouchInteractionService.java | 26 +++--- .../android/launcher3/util/LockedUserState.kt | 57 ------------ .../launcher3/util/LockedUserStateTest.kt | 88 ------------------- 4 files changed, 61 insertions(+), 161 deletions(-) delete mode 100644 src/com/android/launcher3/util/LockedUserState.kt delete mode 100644 tests/src/com/android/launcher3/util/LockedUserStateTest.kt diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java index 1f522c11e9..9a23557fdf 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java @@ -17,6 +17,7 @@ package com.android.quickstep; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.content.Intent.ACTION_USER_UNLOCKED; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.launcher3.util.DisplayController.CHANGE_ALL; @@ -51,8 +52,10 @@ import android.content.Context; import android.graphics.Region; import android.inputmethodservice.InputMethodService; import android.net.Uri; +import android.os.Process; import android.os.RemoteException; import android.os.SystemProperties; +import android.os.UserManager; import android.provider.Settings; import android.view.MotionEvent; @@ -62,9 +65,9 @@ import androidx.annotation.NonNull; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener; import com.android.launcher3.util.DisplayController.Info; -import com.android.launcher3.util.LockedUserState; import com.android.launcher3.util.NavigationMode; import com.android.launcher3.util.SettingsCache; +import com.android.launcher3.util.SimpleBroadcastReceiver; import com.android.quickstep.TopTaskTracker.CachedTaskInfo; import com.android.quickstep.util.NavBarPosition; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -108,6 +111,15 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { private final boolean mIsOneHandedModeSupported; private boolean mPipIsActive; + private boolean mIsUserUnlocked; + private final ArrayList mUserUnlockedActions = new ArrayList<>(); + private final SimpleBroadcastReceiver mUserUnlockedReceiver = new SimpleBroadcastReceiver(i -> { + if (ACTION_USER_UNLOCKED.equals(i.getAction())) { + mIsUserUnlocked = true; + notifyUserUnlocked(); + } + }); + private int mGestureBlockingTaskId = -1; private @NonNull Region mExclusionRegion = new Region(); private SystemGestureExclusionListenerCompat mExclusionListener; @@ -133,6 +145,14 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { runOnDestroy(mRotationTouchHelper::destroy); } + // Register for user unlocked if necessary + mIsUserUnlocked = context.getSystemService(UserManager.class) + .isUserUnlocked(Process.myUserHandle()); + if (!mIsUserUnlocked) { + mUserUnlockedReceiver.register(mContext, ACTION_USER_UNLOCKED); + } + runOnDestroy(() -> mUserUnlockedReceiver.unregisterReceiverSafely(mContext)); + // Register for exclusion updates mExclusionListener = new SystemGestureExclusionListenerCompat(mDisplayId) { @Override @@ -291,6 +311,25 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { return mDisplayId; } + /** + * Adds a callback for when a user is unlocked. If the user is already unlocked, this listener + * will be called back immediately. + */ + public void runOnUserUnlocked(Runnable action) { + if (mIsUserUnlocked) { + action.run(); + } else { + mUserUnlockedActions.add(action); + } + } + + /** + * @return whether the user is unlocked. + */ + public boolean isUserUnlocked() { + return mIsUserUnlocked; + } + /** * @return whether the user has completed setup wizard */ @@ -298,6 +337,14 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { return mIsUserSetupComplete; } + private void notifyUserUnlocked() { + for (Runnable action : mUserUnlockedActions) { + action.run(); + } + mUserUnlockedActions.clear(); + mUserUnlockedReceiver.unregisterReceiverSafely(mContext); + } + /** * Sets the task id where gestures should be blocked */ @@ -542,7 +589,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { pw.println(" assistantAvailable=" + mAssistantAvailable); pw.println(" assistantDisabled=" + QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)); - pw.println(" isUserUnlocked=" + LockedUserState.get(mContext).isUserUnlocked()); + pw.println(" isUserUnlocked=" + mIsUserUnlocked); pw.println(" isOneHandedModeEnabled=" + mIsOneHandedModeEnabled); pw.println(" isSwipeToNotificationEnabled=" + mIsSwipeToNotificationEnabled); pw.println(" deferredGestureRegion=" + mDeferredGestureRegion.getBounds()); diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 1b8a93c7ed..61caef2724 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -88,7 +88,6 @@ import com.android.launcher3.tracing.LauncherTraceProto; import com.android.launcher3.tracing.TouchInteractionServiceProto; import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper; import com.android.launcher3.util.DisplayController; -import com.android.launcher3.util.LockedUserState; import com.android.launcher3.util.OnboardingPrefs; import com.android.launcher3.util.TraceHelper; import com.android.quickstep.inputconsumers.AccessibilityInputConsumer; @@ -412,8 +411,8 @@ public class TouchInteractionService extends Service mRotationTouchHelper = mDeviceState.getRotationTouchHelper(); // Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized. - LockedUserState.get(this).runOnUserUnlocked(this::onUserUnlocked); - LockedUserState.get(this).runOnUserUnlocked(mTaskbarManager::onUserUnlocked); + mDeviceState.runOnUserUnlocked(this::onUserUnlocked); + mDeviceState.runOnUserUnlocked(mTaskbarManager::onUserUnlocked); mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged); ProtoTracer.INSTANCE.get(this).add(this); @@ -483,7 +482,7 @@ public class TouchInteractionService extends Service } private void resetHomeBounceSeenOnQuickstepEnabledFirstTime() { - if (!LockedUserState.get(this).isUserUnlocked() || mDeviceState.isButtonNavMode()) { + if (!mDeviceState.isUserUnlocked() || mDeviceState.isButtonNavMode()) { // Skip if not yet unlocked (can't read user shared prefs) or if the current navigation // mode doesn't have gestures return; @@ -526,7 +525,7 @@ public class TouchInteractionService extends Service @UiThread private void onSystemUiFlagsChanged(int lastSysUIFlags) { - if (LockedUserState.get(this).isUserUnlocked()) { + if (mDeviceState.isUserUnlocked()) { int systemUiStateFlags = mDeviceState.getSystemUiStateFlags(); SystemUiProxy.INSTANCE.get(this).setLastSystemUiStateFlags(systemUiStateFlags); mOverviewComponentObserver.onSystemUiStateChanged(); @@ -571,7 +570,7 @@ public class TouchInteractionService extends Service @UiThread private void onAssistantVisibilityChanged() { - if (LockedUserState.get(this).isUserUnlocked()) { + if (mDeviceState.isUserUnlocked()) { mOverviewComponentObserver.getActivityInterface().onAssistantVisibilityChanged( mDeviceState.getAssistantVisibility()); } @@ -581,7 +580,7 @@ public class TouchInteractionService extends Service public void onDestroy() { Log.d(TAG, "Touch service destroyed: user=" + getUserId()); sIsInitialized = false; - if (LockedUserState.get(this).isUserUnlocked()) { + if (mDeviceState.isUserUnlocked()) { mInputConsumer.unregisterInputConsumer(); mOverviewComponentObserver.onDestroy(); } @@ -615,7 +614,7 @@ public class TouchInteractionService extends Service TestLogging.recordMotionEvent( TestProtocol.SEQUENCE_TIS, "TouchInteractionService.onInputEvent", event); - if (!LockedUserState.get(this).isUserUnlocked()) { + if (!mDeviceState.isUserUnlocked()) { return; } @@ -637,8 +636,7 @@ public class TouchInteractionService extends Service mGestureState = newGestureState; mConsumer = newConsumer(prevGestureState, mGestureState, event); mUncheckedConsumer = mConsumer; - } else if (LockedUserState.get(this).isUserUnlocked() - && mDeviceState.isFullyGesturalNavMode() + } else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode() && mDeviceState.canTriggerAssistantAction(event)) { mGestureState = createGestureState(mGestureState); // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we @@ -758,7 +756,7 @@ public class TouchInteractionService extends Service boolean canStartSystemGesture = mDeviceState.canStartSystemGesture(); - if (!LockedUserState.get(this).isUserUnlocked()) { + if (!mDeviceState.isUserUnlocked()) { CompoundString reasonString = newCompoundString("device locked"); InputConsumer consumer; if (canStartSystemGesture) { @@ -1105,7 +1103,7 @@ public class TouchInteractionService extends Service } private void preloadOverview(boolean fromInit, boolean forSUWAllSet) { - if (!LockedUserState.get(this).isUserUnlocked()) { + if (!mDeviceState.isUserUnlocked()) { return; } @@ -1137,7 +1135,7 @@ public class TouchInteractionService extends Service @Override public void onConfigurationChanged(Configuration newConfig) { - if (!LockedUserState.get(this).isUserUnlocked()) { + if (!mDeviceState.isUserUnlocked()) { return; } final BaseActivityInterface activityInterface = @@ -1178,7 +1176,7 @@ public class TouchInteractionService extends Service } else { // Dump everything FeatureFlags.dump(pw); - if (LockedUserState.get(this).isUserUnlocked()) { + if (mDeviceState.isUserUnlocked()) { PluginManagerWrapper.INSTANCE.get(getBaseContext()).dump(pw); } mDeviceState.dump(pw); diff --git a/src/com/android/launcher3/util/LockedUserState.kt b/src/com/android/launcher3/util/LockedUserState.kt deleted file mode 100644 index 7b49583b86..0000000000 --- a/src/com/android/launcher3/util/LockedUserState.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.android.launcher3.util - -import android.content.Context -import android.content.Intent -import android.os.Process -import android.os.UserManager -import androidx.annotation.VisibleForTesting - -class LockedUserState(private val mContext: Context) : SafeCloseable { - var isUserUnlocked: Boolean - private set - private val mUserUnlockedActions: RunnableList = RunnableList() - - @VisibleForTesting - val mUserUnlockedReceiver = SimpleBroadcastReceiver { - if (Intent.ACTION_USER_UNLOCKED == it.action) { - isUserUnlocked = true - notifyUserUnlocked() - } - } - - init { - isUserUnlocked = - mContext - .getSystemService(UserManager::class.java)!! - .isUserUnlocked(Process.myUserHandle()) - if (isUserUnlocked) { - notifyUserUnlocked() - } else { - mUserUnlockedReceiver.register(mContext, Intent.ACTION_USER_UNLOCKED) - } - } - - private fun notifyUserUnlocked() { - mUserUnlockedActions.executeAllAndDestroy() - mUserUnlockedReceiver.unregisterReceiverSafely(mContext) - } - - /** Stops the receiver from listening for ACTION_USER_UNLOCK broadcasts. */ - override fun close() { - mUserUnlockedReceiver.unregisterReceiverSafely(mContext) - } - - /** - * Adds a `Runnable` to be executed when a user is unlocked. If the user is already unlocked, - * this runnable will run immediately because RunnableList will already have been destroyed. - */ - fun runOnUserUnlocked(action: Runnable) { - mUserUnlockedActions.add(action) - } - - companion object { - @VisibleForTesting val INSTANCE = MainThreadInitializedObject { LockedUserState(it) } - - @JvmStatic fun get(context: Context): LockedUserState = INSTANCE.get(context) - } -} diff --git a/tests/src/com/android/launcher3/util/LockedUserStateTest.kt b/tests/src/com/android/launcher3/util/LockedUserStateTest.kt deleted file mode 100644 index 84156e7101..0000000000 --- a/tests/src/com/android/launcher3/util/LockedUserStateTest.kt +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3.util - -import android.content.Context -import android.content.Intent -import android.os.Process -import android.os.UserManager -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.SmallTest -import com.google.common.truth.Truth.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyZeroInteractions -import org.mockito.Mockito.`when` -import org.mockito.MockitoAnnotations - -/** Unit tests for {@link LockedUserUtil} */ -@SmallTest -@RunWith(AndroidJUnit4::class) -class LockedUserStateTest { - - @Mock lateinit var userManager: UserManager - @Mock lateinit var context: Context - - @Before - fun setup() { - MockitoAnnotations.initMocks(this) - `when`(context.getSystemService(UserManager::class.java)).thenReturn(userManager) - } - - @Test - fun runOnUserUnlocked_runs_action_immediately_if_already_unlocked() { - `when`(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(true) - LockedUserState.INSTANCE.initializeForTesting(LockedUserState(context)) - val action: Runnable = mock() - - LockedUserState.get(context).runOnUserUnlocked(action) - verify(action).run() - } - - @Test - fun runOnUserUnlocked_waits_to_run_action_until_user_is_unlocked() { - `when`(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(false) - LockedUserState.INSTANCE.initializeForTesting(LockedUserState(context)) - val action: Runnable = mock() - - LockedUserState.get(context).runOnUserUnlocked(action) - verifyZeroInteractions(action) - - LockedUserState.get(context) - .mUserUnlockedReceiver - .onReceive(context, Intent(Intent.ACTION_USER_UNLOCKED)) - - verify(action).run() - } - - @Test - fun isUserUnlocked_returns_true_when_user_is_unlocked() { - `when`(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(true) - LockedUserState.INSTANCE.initializeForTesting(LockedUserState(context)) - assertThat(LockedUserState.get(context).isUserUnlocked).isTrue() - } - - @Test - fun isUserUnlocked_returns_false_when_user_is_locked() { - `when`(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(false) - LockedUserState.INSTANCE.initializeForTesting(LockedUserState(context)) - assertThat(LockedUserState.get(context).isUserUnlocked).isFalse() - } -}