Merge "Kill app if cross profile app op gets revoked" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-05-15 14:06:16 +00:00
committed by Android (Google) Code Review
3 changed files with 83 additions and 0 deletions

View File

@@ -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 {

View File

@@ -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);
}
}
}

View File

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