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

Commit 0b4f7bd4 authored by Zhen Zhang's avatar Zhen Zhang
Browse files

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
parent fc97abca
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}) {