diff options
| author | 2022-04-20 19:18:44 +0000 | |
|---|---|---|
| committer | 2022-04-22 17:54:16 +0000 | |
| commit | 1e5c6d9c4e7991fde18993bfccabb4207d8977e8 (patch) | |
| tree | bb0f778be39778ce22213d218c631ffc7561bd0e | |
| parent | f08f61e9f937132237684c4d1b2c7736a8b267ee (diff) | |
[MultiUser] fix async bouncer user
The userswitcher in the bouncer does not update when receiver in the
controller receives the user switcher intent. This change will add a
callback to the aforementioned controller and we can reload the user
switcher upon doing so. With some testing on the device, there does not
seem to be any flickering, but bug is resolved.
Previous CL that was supposed to fix this b/17716871
Bug: 228901381
Test: Manual on device
Change-Id: I7b9fada327db63d744c340f75398c719b20ef392
3 files changed, 76 insertions, 5 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index c0ba51f27fe2..799b98cab524 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -315,6 +315,7 @@ public class KeyguardSecurityContainer extends FrameLayout { Log.i(TAG, "Switching mode from " + modeToString(mCurrentMode) + " to " + modeToString(mode)); mCurrentMode = mode; + mViewMode.onDestroy(); switch (mode) { case MODE_ONE_HANDED: @@ -710,7 +711,6 @@ public class KeyguardSecurityContainer extends FrameLayout { * Enscapsulates the differences between bouncer modes for the container. */ interface ViewMode { - default void init(@NonNull ViewGroup v, @NonNull GlobalSettings globalSettings, @NonNull KeyguardSecurityViewFlipper viewFlipper, @NonNull FalsingManager falsingManager, @@ -738,6 +738,9 @@ public class KeyguardSecurityContainer extends FrameLayout { default int getChildWidthMeasureSpec(int parentWidthMeasureSpec) { return parentWidthMeasureSpec; } + + /** Called when we are setting a new ViewMode */ + default void onDestroy() {}; } /** @@ -781,6 +784,8 @@ public class KeyguardSecurityContainer extends FrameLayout { private UserSwitcherController mUserSwitcherController; private KeyguardUserSwitcherPopupMenu mPopup; private Resources mResources; + private UserSwitcherController.UserSwitchCallback mUserSwitchCallback = + this::setupUserSwitcher; @Override public void init(@NonNull ViewGroup v, @NonNull GlobalSettings globalSettings, @@ -805,6 +810,7 @@ public class KeyguardSecurityContainer extends FrameLayout { mUserSwitcher = mView.findViewById(R.id.user_switcher_header); setupUserSwitcher(); + mUserSwitcherController.addUserSwitchCallback(mUserSwitchCallback); } @Override @@ -813,7 +819,11 @@ public class KeyguardSecurityContainer extends FrameLayout { mPopup.dismiss(); mPopup = null; } - setupUserSwitcher(); + } + + @Override + public void onDestroy() { + mUserSwitcherController.removeUserSwitchCallback(mUserSwitchCallback); } private Drawable findUserIcon(int userId) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index a3f01c21d137..1b685d0aad7a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -88,6 +88,7 @@ import com.android.systemui.util.settings.SecureSettings; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; @@ -161,6 +162,8 @@ public class UserSwitcherController implements Dumpable { private View mView; private String mCreateSupervisedUserPackage; private GlobalSettings mGlobalSettings; + private List<UserSwitchCallback> mUserSwitchCallbacks = + Collections.synchronizedList(new ArrayList<>()); @Inject public UserSwitcherController(Context context, @@ -225,7 +228,8 @@ public class UserSwitcherController implements Dumpable { filter.addAction(Intent.ACTION_USER_STOPPED); filter.addAction(Intent.ACTION_USER_UNLOCKED); mBroadcastDispatcher.registerReceiver( - mReceiver, filter, null /* handler */, UserHandle.SYSTEM); + mReceiver, filter, null /* executor */, + UserHandle.SYSTEM, Context.RECEIVER_EXPORTED, null /* permission */); mSimpleUserSwitcher = shouldUseSimpleUserSwitcher(); @@ -652,6 +656,7 @@ public class UserSwitcherController implements Dumpable { i--; } } + notifyUserSwitchCallbacks(); notifyAdapters(); // Disconnect from the old secondary user's service @@ -1053,6 +1058,33 @@ public class UserSwitcherController implements Dumpable { mActivityStarter.startActivity(intent, true); } + /** + * Add a subscriber to when user switches. + */ + public void addUserSwitchCallback(UserSwitchCallback callback) { + mUserSwitchCallbacks.add(callback); + } + + /** + * Remove a subscriber to when user switches. + */ + public void removeUserSwitchCallback(UserSwitchCallback callback) { + mUserSwitchCallbacks.remove(callback); + } + + /** + * Notify user switch callbacks that user has switched. + */ + private void notifyUserSwitchCallbacks() { + List<UserSwitchCallback> temp; + synchronized (mUserSwitchCallbacks) { + temp = new ArrayList<>(mUserSwitchCallbacks); + } + for (UserSwitchCallback callback : temp) { + callback.onUserSwitched(); + } + } + public static final class UserRecord { public final UserInfo info; public final Bitmap picture; @@ -1233,4 +1265,14 @@ public class UserSwitcherController implements Dumpable { } } } + + /** + * Callback to for when this controller receives the intent to switch users. + */ + public interface UserSwitchCallback { + /** + * Called when user has switched. + */ + void onUserSwitched(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt index e3d2a2951c97..6bd8b98f70e1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy import android.app.IActivityManager import android.app.admin.DevicePolicyManager +import android.content.BroadcastReceiver import android.content.Context import android.content.DialogInterface import android.content.Intent @@ -52,6 +53,10 @@ import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.phone.NotificationShadeWindowView import com.android.systemui.telephony.TelephonyListenerManager import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.capture +import com.android.systemui.util.mockito.nullable import com.android.systemui.util.settings.GlobalSettings import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.time.FakeSystemClock @@ -63,10 +68,8 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt -import org.mockito.ArgumentMatchers.eq import org.mockito.Mock import org.mockito.Mockito.`when` -import org.mockito.Mockito.any import org.mockito.Mockito.doNothing import org.mockito.Mockito.doReturn import org.mockito.Mockito.eq @@ -529,4 +532,20 @@ class UserSwitcherControllerTest : SysuiTestCase() { setupController() assertFalse(userSwitcherController.canCreateSupervisedUser()) } + + @Test + fun addUserSwitchCallback() { + val broadcastReceiverCaptor = argumentCaptor<BroadcastReceiver>() + verify(broadcastDispatcher).registerReceiver( + capture(broadcastReceiverCaptor), + any(), + nullable(), nullable(), anyInt(), nullable()) + + val cb = mock(UserSwitcherController.UserSwitchCallback::class.java) + userSwitcherController.addUserSwitchCallback(cb) + + val intent = Intent(Intent.ACTION_USER_SWITCHED).putExtra(Intent.EXTRA_USER_HANDLE, guestId) + broadcastReceiverCaptor.value.onReceive(context, intent) + verify(cb).onUserSwitched() + } } |