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

Commit 81fa7414 authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Revert "Check for NLS service intent filter when rebinding services"" into main

parents 2d24f84d d227173b
Loading
Loading
Loading
Loading
+10 −26
Original line number Diff line number Diff line
@@ -106,8 +106,7 @@ abstract public class ManagedServices {
    protected final String TAG = getClass().getSimpleName().replace('$', '.');
    protected final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    protected static final int ON_BINDING_DIED_REBIND_DELAY_MS = 10000;
    protected static final int ON_BINDING_DIED_REBIND_MSG = 1234;
    private static final int ON_BINDING_DIED_REBIND_DELAY_MS = 10000;
    protected static final String ENABLED_SERVICES_SEPARATOR = ":";
    private static final String DB_VERSION_1 = "1";
    private static final String DB_VERSION_2 = "2";
@@ -857,13 +856,7 @@ abstract public class ManagedServices {
            String approvedItem = getApprovedValue(pkgOrComponent);

            if (approvedItem != null) {
                final ComponentName component = ComponentName.unflattenFromString(approvedItem);
                if (enabled) {
                    if (component != null && !isValidService(component, userId)) {
                        Log.e(TAG, "Skip allowing " + mConfig.caption + " " + pkgOrComponent
                                + " (userSet: " + userSet + ") for invalid service");
                        return;
                    }
                    approved.add(approvedItem);
                } else {
                    approved.remove(approvedItem);
@@ -961,7 +954,7 @@ abstract public class ManagedServices {
                || isPackageOrComponentAllowed(component.getPackageName(), userId))) {
            return false;
        }
        return isValidService(component, userId);
        return componentHasBindPermission(component, userId);
    }

    private boolean componentHasBindPermission(ComponentName component, int userId) {
@@ -1313,12 +1306,11 @@ abstract public class ManagedServices {
                    if (TextUtils.equals(getPackageName(approvedPackageOrComponent), packageName)) {
                        final ComponentName component = ComponentName.unflattenFromString(
                                approvedPackageOrComponent);
                        if (component != null && !isValidService(component, userId)) {
                        if (component != null && !componentHasBindPermission(component, userId)) {
                            approved.removeAt(j);
                            if (DEBUG) {
                                Slog.v(TAG, "Removing " + approvedPackageOrComponent
                                        + " from approved list; no bind permission or "
                                        + "service interface filter found "
                                        + " from approved list; no bind permission found "
                                        + mConfig.bindPermission);
                            }
                        }
@@ -1337,11 +1329,6 @@ abstract public class ManagedServices {
        }
    }

    protected boolean isValidService(ComponentName component, int userId) {
        return componentHasBindPermission(component, userId) && queryPackageForServices(
                component.getPackageName(), userId).contains(component);
    }

    protected boolean isValidEntry(String packageOrComponent, int userId) {
        return hasMatchingServices(packageOrComponent, userId);
    }
@@ -1499,25 +1486,23 @@ abstract public class ManagedServices {
     * Called when user switched to unbind all services from other users.
     */
    @VisibleForTesting
    void unbindOtherUserServices(int switchedToUser) {
    void unbindOtherUserServices(int currentUser) {
        TimingsTraceAndSlog t = new TimingsTraceAndSlog();
        t.traceBegin("ManagedServices.unbindOtherUserServices_current" + switchedToUser);
        unbindServicesImpl(switchedToUser, true /* allExceptUser */);
        t.traceBegin("ManagedServices.unbindOtherUserServices_current" + currentUser);
        unbindServicesImpl(currentUser, true /* allExceptUser */);
        t.traceEnd();
    }

    void unbindUserServices(int removedUser) {
    void unbindUserServices(int user) {
        TimingsTraceAndSlog t = new TimingsTraceAndSlog();
        t.traceBegin("ManagedServices.unbindUserServices" + removedUser);
        unbindServicesImpl(removedUser, false /* allExceptUser */);
        t.traceBegin("ManagedServices.unbindUserServices" + user);
        unbindServicesImpl(user, false /* allExceptUser */);
        t.traceEnd();
    }

    void unbindServicesImpl(int user, boolean allExceptUser) {
        final SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
        synchronized (mMutex) {
            // Remove enqueued rebinds to avoid rebinding services for a switched user
            mHandler.removeMessages(ON_BINDING_DIED_REBIND_MSG);
            final Set<ManagedServiceInfo> removableBoundServices = getRemovableConnectedServices();
            for (ManagedServiceInfo info : removableBoundServices) {
                if ((allExceptUser && (info.userid != user))
@@ -1712,7 +1697,6 @@ abstract public class ManagedServices {
                            mServicesRebinding.add(servicesBindingTag);
                            mHandler.postDelayed(() ->
                                    reregisterService(name, userid),
                                    ON_BINDING_DIED_REBIND_MSG,
                                    ON_BINDING_DIED_REBIND_DELAY_MS);
                        } else {
                            Slog.v(TAG, getCaption() + " not rebinding in user " + userid
+9 −197
Original line number Diff line number Diff line
@@ -63,13 +63,11 @@ import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
import android.testing.TestableLooper;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -84,7 +82,6 @@ import com.android.server.UiServiceTestCase;

import com.google.android.collect.Lists;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -106,7 +103,6 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;


public class ManagedServicesTest extends UiServiceTestCase {

    @Mock
@@ -119,7 +115,6 @@ public class ManagedServicesTest extends UiServiceTestCase {
    private ManagedServices.UserProfiles mUserProfiles;
    @Mock private DevicePolicyManager mDpm;
    Object mLock = new Object();
    private TestableLooper mTestableLooper;

    UserInfo mZero = new UserInfo(0, "zero", 0);
    UserInfo mTen = new UserInfo(10, "ten", 0);
@@ -147,7 +142,6 @@ public class ManagedServicesTest extends UiServiceTestCase {
    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mTestableLooper = new TestableLooper(Looper.getMainLooper());

        mContext.setMockPackageManager(mPm);
        mContext.addMockSystemService(Context.USER_SERVICE, mUm);
@@ -205,11 +199,6 @@ public class ManagedServicesTest extends UiServiceTestCase {
                mIpm, APPROVAL_BY_COMPONENT);
    }

    @After
    public void tearDown() throws Exception {
        mTestableLooper.destroy();
    }

    @Test
    public void testBackupAndRestore_migration() throws Exception {
        for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
@@ -899,7 +888,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
            return true;
        });

        mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>());
        mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>());
        service.addApprovedList("a", 0, true);

        service.reregisterService(cn, 0);
@@ -930,7 +919,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
            return true;
        });

        mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>());
        mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>());
        service.addApprovedList("a", 0, false);

        service.reregisterService(cn, 0);
@@ -961,7 +950,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
            return true;
        });

        mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>());
        mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>());
        service.addApprovedList("a/a", 0, true);

        service.reregisterService(cn, 0);
@@ -992,7 +981,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
            return true;
        });

        mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>());
        mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>());
        service.addApprovedList("a/a", 0, false);

        service.reregisterService(cn, 0);
@@ -1063,77 +1052,6 @@ public class ManagedServicesTest extends UiServiceTestCase {
        assertTrue(service.isBound(cn, 11));
    }

    @Test
    public void registerService_bindingDied_rebindIsClearedOnUserSwitch() throws Exception {
        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(mPkg);
        when(context.getUserId()).thenReturn(mUser.getIdentifier());
        when(context.getPackageManager()).thenReturn(pm);
        when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);

        ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
                APPROVAL_BY_PACKAGE);
        service = spy(service);
        ComponentName cn = ComponentName.unflattenFromString("a/a");

        // Trigger onBindingDied for component when registering
        //  => will schedule a rebind in 10 seconds
        when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
            Object[] args = invocation.getArguments();
            ServiceConnection sc = (ServiceConnection) args[1];
            sc.onBindingDied(cn);
            return true;
        });
        service.registerService(cn, 0);
        assertThat(service.isBound(cn, 0)).isFalse();

        // Switch to user 10
        service.onUserSwitched(10);

        // Check that the scheduled rebind for user 0 was cleared
        mTestableLooper.moveTimeForward(ManagedServices.ON_BINDING_DIED_REBIND_DELAY_MS);
        mTestableLooper.processAllMessages();
        verify(service, never()).reregisterService(any(), anyInt());
    }

    @Test
    public void registerService_bindingDied_rebindIsExecutedAfterTimeout() throws Exception {
        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(mPkg);
        when(context.getUserId()).thenReturn(mUser.getIdentifier());
        when(context.getPackageManager()).thenReturn(pm);
        when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);

        ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
                APPROVAL_BY_PACKAGE);
        service = spy(service);
        ComponentName cn = ComponentName.unflattenFromString("a/a");

        // Trigger onBindingDied for component when registering
        //  => will schedule a rebind in 10 seconds
        when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
            Object[] args = invocation.getArguments();
            ServiceConnection sc = (ServiceConnection) args[1];
            sc.onBindingDied(cn);
            return true;
        });
        service.registerService(cn, 0);
        assertThat(service.isBound(cn, 0)).isFalse();

        // Check that the scheduled rebind is run
        mTestableLooper.moveTimeForward(ManagedServices.ON_BINDING_DIED_REBIND_DELAY_MS);
        mTestableLooper.processAllMessages();
        verify(service, times(1)).reregisterService(eq(cn), eq(0));
    }

    @Test
    public void testPackageUninstall_packageNoLongerInApprovedList() throws Exception {
        for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
@@ -1292,64 +1210,6 @@ public class ManagedServicesTest extends UiServiceTestCase {
        assertTrue(service.isComponentEnabledForCurrentProfiles(approvedComponent));
    }

    @Test
    public void testUpgradeAppNoIntentFilterNoRebind() throws Exception {
        Context context = spy(getContext());
        doReturn(true).when(context).bindServiceAsUser(any(), any(), anyInt(), any());

        ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles,
                mIpm, APPROVAL_BY_COMPONENT);

        List<String> packages = new ArrayList<>();
        packages.add("package");
        addExpectedServices(service, packages, 0);

        final ComponentName unapprovedComponent = ComponentName.unflattenFromString("package/C1");
        final ComponentName approvedComponent = ComponentName.unflattenFromString("package/C2");

        // Both components are approved initially
        mExpectedPrimaryComponentNames.clear();
        mExpectedPrimaryPackages.clear();
        mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2");
        mExpectedSecondaryComponentNames.clear();
        mExpectedSecondaryPackages.clear();

        loadXml(service);

        //Component package/C1 loses serviceInterface intent filter
        ManagedServices.Config config = service.getConfig();
        when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt()))
                .thenAnswer(new Answer<List<ResolveInfo>>() {
                    @Override
                    public List<ResolveInfo> answer(InvocationOnMock invocationOnMock)
                            throws Throwable {
                        Object[] args = invocationOnMock.getArguments();
                        Intent invocationIntent = (Intent) args[0];
                        if (invocationIntent != null) {
                            if (invocationIntent.getAction().equals(config.serviceInterface)
                                    && packages.contains(invocationIntent.getPackage())) {
                                List<ResolveInfo> dummyServices = new ArrayList<>();
                                ResolveInfo resolveInfo = new ResolveInfo();
                                ServiceInfo serviceInfo = new ServiceInfo();
                                serviceInfo.packageName = invocationIntent.getPackage();
                                serviceInfo.name = approvedComponent.getClassName();
                                serviceInfo.permission = service.getConfig().bindPermission;
                                resolveInfo.serviceInfo = serviceInfo;
                                dummyServices.add(resolveInfo);
                                return dummyServices;
                            }
                        }
                        return new ArrayList<>();
                    }
                });

        // Trigger package update
        service.onPackagesChanged(false, new String[]{"package"}, new int[]{0});

        assertFalse(service.isComponentEnabledForCurrentProfiles(unapprovedComponent));
        assertTrue(service.isComponentEnabledForCurrentProfiles(approvedComponent));
    }

    @Test
    public void testSetPackageOrComponentEnabled() throws Exception {
        for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
@@ -1363,21 +1223,6 @@ public class ManagedServicesTest extends UiServiceTestCase {
                            "user10package1/K", "user10.3/Component", "user10package2/L",
                            "user10.4/Component"}));

            // mock permissions for services
            PackageManager pm = mock(PackageManager.class);
            when(getContext().getPackageManager()).thenReturn(pm);
            List<ComponentName> enabledComponents = List.of(
                    ComponentName.unflattenFromString("package/Comp"),
                    ComponentName.unflattenFromString("package/C2"),
                    ComponentName.unflattenFromString("again/M4"),
                    ComponentName.unflattenFromString("user10package/B"),
                    ComponentName.unflattenFromString("user10/Component"),
                    ComponentName.unflattenFromString("user10package1/K"),
                    ComponentName.unflattenFromString("user10.3/Component"),
                    ComponentName.unflattenFromString("user10package2/L"),
                    ComponentName.unflattenFromString("user10.4/Component"));
            mockServiceInfoWithMetaData(enabledComponents, service, pm, new ArrayMap<>());

            for (int userId : expectedEnabled.keySet()) {
                ArrayList<String> expectedForUser = expectedEnabled.get(userId);
                for (int i = 0; i < expectedForUser.size(); i++) {
@@ -2099,7 +1944,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
        metaDataAutobindAllow.putBoolean(META_DATA_DEFAULT_AUTOBIND, true);
        metaDatas.put(cn_allowed, metaDataAutobindAllow);

        mockServiceInfoWithMetaData(componentNames, service, pm, metaDatas);
        mockServiceInfoWithMetaData(componentNames, service, metaDatas);

        service.addApprovedList(cn_allowed.flattenToString(), 0, true);
        service.addApprovedList(cn_disallowed.flattenToString(), 0, true);
@@ -2144,7 +1989,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
        metaDataAutobindDisallow.putBoolean(META_DATA_DEFAULT_AUTOBIND, false);
        metaDatas.put(cn_disallowed, metaDataAutobindDisallow);

        mockServiceInfoWithMetaData(componentNames, service, pm, metaDatas);
        mockServiceInfoWithMetaData(componentNames, service, metaDatas);

        service.addApprovedList(cn_disallowed.flattenToString(), 0, true);

@@ -2183,7 +2028,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
        metaDataAutobindDisallow.putBoolean(META_DATA_DEFAULT_AUTOBIND, false);
        metaDatas.put(cn_disallowed, metaDataAutobindDisallow);

        mockServiceInfoWithMetaData(componentNames, service, pm, metaDatas);
        mockServiceInfoWithMetaData(componentNames, service, metaDatas);

        service.addApprovedList(cn_disallowed.flattenToString(), 0, true);

@@ -2254,8 +2099,8 @@ public class ManagedServicesTest extends UiServiceTestCase {
    }

    private void mockServiceInfoWithMetaData(List<ComponentName> componentNames,
            ManagedServices service, PackageManager packageManager,
            ArrayMap<ComponentName, Bundle> metaDatas) throws RemoteException {
            ManagedServices service, ArrayMap<ComponentName, Bundle> metaDatas)
            throws RemoteException {
        when(mIpm.getServiceInfo(any(), anyLong(), anyInt())).thenAnswer(
                (Answer<ServiceInfo>) invocation -> {
                    ComponentName invocationCn = invocation.getArgument(0);
@@ -2270,39 +2115,6 @@ public class ManagedServicesTest extends UiServiceTestCase {
                    return null;
                }
        );

        // add components to queryIntentServicesAsUser response
        final List<String> packages = new ArrayList<>();
        for (ComponentName cn: componentNames) {
            packages.add(cn.getPackageName());
        }
        ManagedServices.Config config = service.getConfig();
        when(packageManager.queryIntentServicesAsUser(any(), anyInt(), anyInt())).
                thenAnswer(new Answer<List<ResolveInfo>>() {
                @Override
                public List<ResolveInfo> answer(InvocationOnMock invocationOnMock)
                    throws Throwable {
                    Object[] args = invocationOnMock.getArguments();
                    Intent invocationIntent = (Intent) args[0];
                    if (invocationIntent != null) {
                        if (invocationIntent.getAction().equals(config.serviceInterface)
                            && packages.contains(invocationIntent.getPackage())) {
                            List<ResolveInfo> dummyServices = new ArrayList<>();
                            for (ComponentName cn: componentNames) {
                                ResolveInfo resolveInfo = new ResolveInfo();
                                ServiceInfo serviceInfo = new ServiceInfo();
                                serviceInfo.packageName = invocationIntent.getPackage();
                                serviceInfo.name = cn.getClassName();
                                serviceInfo.permission = service.getConfig().bindPermission;
                                resolveInfo.serviceInfo = serviceInfo;
                                dummyServices.add(resolveInfo);
                            }
                            return dummyServices;
                        }
                    }
                    return new ArrayList<>();
                }
            });
    }

    private void resetComponentsAndPackages() {
+0 −10
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;

import static org.junit.Assert.assertNull;

import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.any;
@@ -194,8 +193,6 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
    public void testWriteXml_userTurnedOffNAS() throws Exception {
        int userId = ActivityManager.getCurrentUser();

        doReturn(true).when(mAssistants).isValidService(eq(mCn), eq(userId));

        mAssistants.loadDefaultsFromConfig(true);

        mAssistants.setPackageOrComponentEnabled(mCn.flattenToString(), userId, true,
@@ -401,10 +398,6 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
    public void testSetPackageOrComponentEnabled_onlyOnePackage() throws Exception {
        ComponentName component1 = ComponentName.unflattenFromString("package/Component1");
        ComponentName component2 = ComponentName.unflattenFromString("package/Component2");

        doReturn(true).when(mAssistants).isValidService(eq(component1), eq(mZero.id));
        doReturn(true).when(mAssistants).isValidService(eq(component2), eq(mZero.id));

        mAssistants.setPackageOrComponentEnabled(component1.flattenToString(), mZero.id, true,
                true, true);
        verify(mNm, never()).setNotificationAssistantAccessGrantedForUserInternal(
@@ -550,7 +543,6 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
    public void testSetAdjustmentTypeSupportedState() throws Exception {
        int userId = ActivityManager.getCurrentUser();

        doReturn(true).when(mAssistants).isValidService(eq(mCn), eq(userId));
        mAssistants.loadDefaultsFromConfig(true);
        mAssistants.setPackageOrComponentEnabled(mCn.flattenToString(), userId, true,
                true, true);
@@ -574,7 +566,6 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
    public void testSetAdjustmentTypeSupportedState_readWriteXml_entries() throws Exception {
        int userId = ActivityManager.getCurrentUser();

        doReturn(true).when(mAssistants).isValidService(eq(mCn), eq(userId));
        mAssistants.loadDefaultsFromConfig(true);
        mAssistants.setPackageOrComponentEnabled(mCn.flattenToString(), userId, true,
                true, true);
@@ -598,7 +589,6 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
    public void testSetAdjustmentTypeSupportedState_readWriteXml_empty() throws Exception {
        int userId = ActivityManager.getCurrentUser();

        doReturn(true).when(mAssistants).isValidService(eq(mCn), eq(userId));
        mAssistants.loadDefaultsFromConfig(true);
        mAssistants.setPackageOrComponentEnabled(mCn.flattenToString(), userId, true,
                true, true);