Unbind background users' components in ManagedServices on user switched
Include background users' components to the set of service components to unbind on user switched. These components will be bound again when their user becomes foreground user. Added unit test Bug: 167633441 Test: atest ManagedServicesTest Change-Id: Ibc81cc35205075187c22fd3a4ed82b373f211038
This commit is contained in:
@@ -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<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
|
||||
|
||||
synchronized (mMutex) {
|
||||
final Set<ManagedServiceInfo> removableBoundServices = getRemovableConnectedServices();
|
||||
for (ManagedServiceInfo info : removableBoundServices) {
|
||||
if (info.userid != currentUser) {
|
||||
Set<ComponentName> toUnbind =
|
||||
componentsToUnbind.get(info.userid, new ArraySet<>());
|
||||
toUnbind.add(info.component);
|
||||
componentsToUnbind.put(info.userid, toUnbind);
|
||||
}
|
||||
}
|
||||
}
|
||||
unbindFromServices(componentsToUnbind);
|
||||
}
|
||||
|
||||
protected void unbindFromServices(SparseArray<Set<ComponentName>> 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);
|
||||
}
|
||||
|
||||
@@ -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}) {
|
||||
|
||||
Reference in New Issue
Block a user