Merge "[MultiUser] fix async bouncer user" into tm-dev am: ab9ea4a88e am: 20cca28444
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17870576
Change-Id: I6b037b2118574647b59dc7967416f051e58a42b5
Ignore-AOSP-First: this is an automerge
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index f435579..fd7a6e6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -315,6 +315,7 @@
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 @@
* 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 @@
default int getChildWidthMeasureSpec(int parentWidthMeasureSpec) {
return parentWidthMeasureSpec;
}
+
+ /** Called when we are setting a new ViewMode */
+ default void onDestroy() {};
}
/**
@@ -781,6 +784,8 @@
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 @@
mUserSwitcher = mView.findViewById(R.id.user_switcher_header);
setupUserSwitcher();
+ mUserSwitcherController.addUserSwitchCallback(mUserSwitchCallback);
}
@Override
@@ -813,7 +819,11 @@
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 5eff8cd..6af8e9e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -90,6 +90,7 @@
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;
@@ -165,6 +166,8 @@
private View mView;
private String mCreateSupervisedUserPackage;
private GlobalSettings mGlobalSettings;
+ private List<UserSwitchCallback> mUserSwitchCallbacks =
+ Collections.synchronizedList(new ArrayList<>());
@Inject
public UserSwitcherController(Context context,
@@ -230,7 +233,8 @@
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();
@@ -673,6 +677,7 @@
i--;
}
}
+ notifyUserSwitchCallbacks();
notifyAdapters();
// Disconnect from the old secondary user's service
@@ -1134,6 +1139,33 @@
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;
@@ -1383,4 +1415,14 @@
}
}
}
+
+ /**
+ * 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 152815f..e0bf9e7 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
@@ -19,6 +19,7 @@
import android.app.IActivityManager
import android.app.NotificationManager
import android.app.admin.DevicePolicyManager
+import android.content.BroadcastReceiver
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
@@ -55,6 +56,10 @@
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
@@ -66,10 +71,8 @@
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
@@ -561,4 +564,20 @@
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()
+ }
}