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

Commit 584ec88b authored by David Lin's avatar David Lin Committed by Android (Google) Code Review
Browse files

Merge "Check for NLS bind permission when rebinding services" into 24D1-dev

parents 30b0a909 677343f4
Loading
Loading
Loading
Loading
+47 −4
Original line number Diff line number Diff line
@@ -942,6 +942,23 @@ abstract public class ManagedServices {
        return false;
    }

    protected boolean isPackageOrComponentAllowedWithPermission(ComponentName component,
            int userId) {
        if (!(isPackageOrComponentAllowed(component.flattenToString(), userId)
                || isPackageOrComponentAllowed(component.getPackageName(), userId))) {
            return false;
        }
        return componentHasBindPermission(component, userId);
    }

    private boolean componentHasBindPermission(ComponentName component, int userId) {
        ServiceInfo info = getServiceInfo(component, userId);
        if (info == null) {
            return false;
        }
        return mConfig.bindPermission.equals(info.permission);
    }

    boolean isPackageOrComponentUserSet(String pkgOrComponent, int userId) {
        synchronized (mApproved) {
            ArraySet<String> services = mUserSetServices.get(userId);
@@ -1003,6 +1020,7 @@ abstract public class ManagedServices {
                    for (int uid : uidList) {
                        if (isPackageAllowed(pkgName, UserHandle.getUserId(uid))) {
                            anyServicesInvolved = true;
                            trimApprovedListsForInvalidServices(pkgName, UserHandle.getUserId(uid));
                        }
                    }
                }
@@ -1135,8 +1153,7 @@ abstract public class ManagedServices {

        synchronized (mMutex) {
            if (enabled) {
                if (isPackageOrComponentAllowed(component.flattenToString(), userId)
                        || isPackageOrComponentAllowed(component.getPackageName(), userId)) {
                if (isPackageOrComponentAllowedWithPermission(component, userId)) {
                    registerServiceLocked(component, userId);
                } else {
                    Slog.d(TAG, component + " no longer has permission to be bound");
@@ -1270,6 +1287,33 @@ abstract public class ManagedServices {
        return removed;
    }

    private void trimApprovedListsForInvalidServices(String packageName, int userId) {
        synchronized (mApproved) {
            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
            if (approvedByType == null) {
                return;
            }
            for (int i = 0; i < approvedByType.size(); i++) {
                final ArraySet<String> approved = approvedByType.valueAt(i);
                for (int j = approved.size() - 1; j >= 0; j--) {
                    final String approvedPackageOrComponent = approved.valueAt(j);
                    if (TextUtils.equals(getPackageName(approvedPackageOrComponent), packageName)) {
                        final ComponentName component = ComponentName.unflattenFromString(
                                approvedPackageOrComponent);
                        if (component != null && !componentHasBindPermission(component, userId)) {
                            approved.removeAt(j);
                            if (DEBUG) {
                                Slog.v(TAG, "Removing " + approvedPackageOrComponent
                                        + " from approved list; no bind permission found "
                                        + mConfig.bindPermission);
                            }
                        }
                    }
                }
            }
        }
    }

    protected String getPackageName(String packageOrComponent) {
        final ComponentName component = ComponentName.unflattenFromString(packageOrComponent);
        if (component != null) {
@@ -1519,8 +1563,7 @@ abstract public class ManagedServices {
    void reregisterService(final ComponentName cn, final int userId) {
        // If rebinding a package that died, ensure it still has permission
        // after the rebind delay
        if (isPackageOrComponentAllowed(cn.getPackageName(), userId)
                || isPackageOrComponentAllowed(cn.flattenToString(), userId)) {
        if (isPackageOrComponentAllowedWithPermission(cn, userId)) {
            registerService(cn, userId);
        }
    }
+57 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -885,6 +886,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
            return true;
        });

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

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

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

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

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

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

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

        service.reregisterService(cn, 0);
@@ -1151,6 +1156,58 @@ public class ManagedServicesTest extends UiServiceTestCase {
        }
    }

    @Test
    public void testUpgradeAppNoPermissionNoRebind() 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 bind permission
        when(mIpm.getServiceInfo(any(), anyLong(), anyInt())).thenAnswer(
                (Answer<ServiceInfo>) invocation -> {
                    ComponentName invocationCn = invocation.getArgument(0);
                    if (invocationCn != null) {
                        ServiceInfo serviceInfo = new ServiceInfo();
                        serviceInfo.packageName = invocationCn.getPackageName();
                        serviceInfo.name = invocationCn.getClassName();
                        if (invocationCn.equals(unapprovedComponent)) {
                            serviceInfo.permission = "none";
                        } else {
                            serviceInfo.permission = service.getConfig().bindPermission;
                        }
                        serviceInfo.metaData = null;
                        return serviceInfo;
                    }
                    return null;
                }
        );

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