Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bfd1baa authored by Zhen Zhang's avatar Zhen Zhang Committed by Android (Google) Code Review
Browse files

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

parents 48c3e229 0b4f7bd4
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -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);
        }
+33 −0
Original line number Diff line number Diff line
@@ -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}) {