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

Commit 9df61d54 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Kill app if cross profile app op gets revoked" into rvc-dev am: 45c68542

Change-Id: Ic0ba4cf7e880e080149fe1cc0293bba860797a39
parents e0dcd303 45c68542
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionManager;
import android.stats.devicepolicy.DevicePolicyEnums;
import android.text.TextUtils;
import android.util.Slog;
@@ -458,6 +459,10 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
                    + packageName + " on user ID " + userId);
            return;
        }

        final boolean hadPermission = hasInteractAcrossProfilesPermission(
                packageName, uid, PermissionChecker.PID_UNKNOWN);

        final int callingUid = mInjector.getCallingUid();
        if (isPermissionGranted(
                Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES, callingUid)) {
@@ -472,6 +477,22 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
        }
        sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(userId));
        maybeLogSetInteractAcrossProfilesAppOp(packageName, newMode, userId, logMetrics, uid);
        maybeKillUid(packageName, uid, hadPermission);
    }

    /**
     * Kills the process represented by the given UID if it has lost the permission to
     * interact across profiles.
     */
    private void maybeKillUid(
            String packageName, int uid, boolean hadPermission) {
        if (!hadPermission) {
            return;
        }
        if (hasInteractAcrossProfilesPermission(packageName, uid, PermissionChecker.PID_UNKNOWN)) {
            return;
        }
        mInjector.killUid(packageName, uid);
    }

    private void maybeLogSetInteractAcrossProfilesAppOp(
@@ -774,6 +795,18 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
                String permission, int uid, int owningUid, boolean exported) {
            return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported);
        }

        @Override
        public void killUid(String packageName, int uid) {
            try {
                ActivityManager.getService().killApplication(
                        packageName,
                        UserHandle.getAppId(uid),
                        UserHandle.getUserId(uid),
                        PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED);
            } catch (RemoteException ignored) {
            }
        }
    }

    @VisibleForTesting
@@ -813,6 +846,8 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
        void sendBroadcastAsUser(Intent intent, UserHandle user);

        int checkComponentPermission(String permission, int uid, int owningUid, boolean exported);

        void killUid(String packageName, int uid);
    }

    class LocalService extends CrossProfileAppsInternal {
+34 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.os.Process;
import android.os.UserHandle;
@@ -106,6 +107,7 @@ public class CrossProfileAppsServiceImplRoboTest {
            new CrossProfileAppsServiceImpl(mContext, mInjector);
    private final Map<UserHandle, Set<Intent>> mSentUserBroadcasts = new HashMap<>();
    private final Map<Integer, List<ApplicationInfo>> installedApplications = new HashMap<>();
    private final Set<Integer> mKilledUids = new HashSet<>();

    @Mock private PackageManagerInternal mPackageManagerInternal;
    @Mock private IPackageManager mIPackageManager;
@@ -388,6 +390,33 @@ public class CrossProfileAppsServiceImplRoboTest {
        assertThat(receivedManifestCanInteractAcrossProfilesChangedBroadcast()).isTrue();
    }

    @Test
    public void setInteractAcrossProfilesAppOp_toAllowed_doesNotKillApp() {
        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
        assertThat(mKilledUids).isEmpty();
    }

    @Test
    public void setInteractAcrossProfilesAppOp_toDisallowed_killsAppsInBothProfiles() {
        shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);

        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_DEFAULT);

        assertThat(mKilledUids).contains(WORK_PROFILE_UID);
        assertThat(mKilledUids).contains(PERSONAL_PROFILE_UID);
    }

    private PermissionInfo createCrossProfilesPermissionInfo() {
        PermissionInfo permissionInfo = new PermissionInfo();
        permissionInfo.name = Manifest.permission.INTERACT_ACROSS_PROFILES;
        permissionInfo.protectionLevel = PermissionInfo.PROTECTION_FLAG_APPOP;
        return permissionInfo;
    }

    @Test
    public void canConfigureInteractAcrossProfiles_packageNotInstalledInProfile_returnsFalse() {
        mockUninstallCrossProfileAppFromWorkProfile();
@@ -678,5 +707,10 @@ public class CrossProfileAppsServiceImplRoboTest {
            // ShadowActivityThread with Robolectric. This method is currently not supported there.
            return mContext.checkPermission(permission, Process.myPid(), uid);
        }

        @Override
        public void killUid(String packageName, int uid) {
            mKilledUids.add(uid);
        }
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -32,8 +32,10 @@ import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionManager;
import android.platform.test.annotations.Presubmit;
import android.util.SparseArray;

@@ -692,5 +694,17 @@ public class CrossProfileAppsServiceImplTest {
                String permission, int uid, int owningUid, boolean exported) {
            return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported);
        }

        @Override
        public void killUid(String packageName, int uid) {
            try {
                ActivityManager.getService().killApplication(
                        packageName,
                        UserHandle.getAppId(uid),
                        UserHandle.getUserId(uid),
                        PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED);
            } catch (RemoteException ignored) {
            }
        }
    }
}