Merge "Revert "Refactor the OnUserUnlock code out of RecentsAnimationDeviceState and"" into tm-qpr-dev am: 8989f839f5
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/21142878
Change-Id: I0b9740a98594304cca9603dc53583655dc6db976
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 1f522c1..9a23557 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -17,6 +17,7 @@
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.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 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 @@
private final boolean mIsOneHandedModeSupported;
private boolean mPipIsActive;
+ private boolean mIsUserUnlocked;
+ private final ArrayList<Runnable> 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 @@
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
@@ -292,12 +312,39 @@
}
/**
+ * 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
*/
public boolean isUserSetupComplete() {
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 @@
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 1b8a93c..61caef2 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.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 @@
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 @@
}
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 @@
@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 @@
@UiThread
private void onAssistantVisibilityChanged() {
- if (LockedUserState.get(this).isUserUnlocked()) {
+ if (mDeviceState.isUserUnlocked()) {
mOverviewComponentObserver.getActivityInterface().onAssistantVisibilityChanged(
mDeviceState.getAssistantVisibility());
}
@@ -581,7 +580,7 @@
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 @@
TestLogging.recordMotionEvent(
TestProtocol.SEQUENCE_TIS, "TouchInteractionService.onInputEvent", event);
- if (!LockedUserState.get(this).isUserUnlocked()) {
+ if (!mDeviceState.isUserUnlocked()) {
return;
}
@@ -637,8 +636,7 @@
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 @@
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 @@
}
private void preloadOverview(boolean fromInit, boolean forSUWAllSet) {
- if (!LockedUserState.get(this).isUserUnlocked()) {
+ if (!mDeviceState.isUserUnlocked()) {
return;
}
@@ -1137,7 +1135,7 @@
@Override
public void onConfigurationChanged(Configuration newConfig) {
- if (!LockedUserState.get(this).isUserUnlocked()) {
+ if (!mDeviceState.isUserUnlocked()) {
return;
}
final BaseActivityInterface activityInterface =
@@ -1178,7 +1176,7 @@
} 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 7b49583..0000000
--- 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 84156e7..0000000
--- 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()
- }
-}