Merge "Unbind background users' components in ManagedServices on user switched"

This commit is contained in:
Zhen Zhang
2020-10-12 16:13:11 +00:00
committed by Android (Google) Code Review
2 changed files with 57 additions and 1 deletions

View File

@@ -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);
}

View File

@@ -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}) {