diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 74b7bd76b0471..4040f4189698d 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -833,6 +833,7 @@ abstract public class ManagedServices { public void onUserSwitched(int user) { if (DEBUG) Slog.d(TAG, "onUserSwitched u=" + user); + unbindOtherUserServices(user); rebindServices(true, user); } @@ -1219,6 +1220,27 @@ abstract public class ManagedServices { bindToServices(componentsToBind); } + /** + * Called when user switched to unbind all services from other users. + */ + @VisibleForTesting + void unbindOtherUserServices(int currentUser) { + final SparseArray> componentsToUnbind = new SparseArray<>(); + + synchronized (mMutex) { + final Set removableBoundServices = getRemovableConnectedServices(); + for (ManagedServiceInfo info : removableBoundServices) { + if (info.userid != currentUser) { + Set toUnbind = + componentsToUnbind.get(info.userid, new ArraySet<>()); + toUnbind.add(info.component); + componentsToUnbind.put(info.userid, toUnbind); + } + } + } + unbindFromServices(componentsToUnbind); + } + protected void unbindFromServices(SparseArray> componentsToUnbind) { for (int i = 0; i < componentsToUnbind.size(); i++) { final int userId = componentsToUnbind.keyAt(i); @@ -1264,7 +1286,8 @@ abstract public class ManagedServices { /** * Version of registerService that takes the name of a service component to bind to. */ - private void registerService(final ComponentName name, final int userid) { + @VisibleForTesting + void registerService(final ComponentName name, final int userid) { synchronized (mMutex) { registerServiceLocked(name, userid); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java index d7e431f3bb51c..e304083dfd27e 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -689,6 +689,39 @@ public class ManagedServicesTest extends UiServiceTestCase { verifyExpectedBoundEntries(service, false); } + @Test + public void unbindOtherUserServices() throws PackageManager.NameNotFoundException { + Context context = mock(Context.class); + PackageManager pm = mock(PackageManager.class); + ApplicationInfo ai = new ApplicationInfo(); + ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; + + when(context.getPackageName()).thenReturn(mContext.getPackageName()); + when(context.getUserId()).thenReturn(mContext.getUserId()); + when(context.getPackageManager()).thenReturn(pm); + when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai); + + ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm, + APPROVAL_BY_COMPONENT); + ComponentName cn = ComponentName.unflattenFromString("a/a"); + + when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> { + Object[] args = invocation.getArguments(); + ServiceConnection sc = (ServiceConnection) args[1]; + sc.onServiceConnected(cn, mock(IBinder.class)); + return true; + }); + + service.registerService(cn, 0); + service.registerService(cn, 10); + service.registerService(cn, 11); + service.unbindOtherUserServices(11); + + assertFalse(service.isBound(cn, 0)); + assertFalse(service.isBound(cn, 10)); + assertTrue(service.isBound(cn, 11)); + } + @Test public void testPackageUninstall_packageNoLongerInApprovedList() throws Exception { for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {