Merge "Kill app if cross profile app op gets revoked" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
45c68542f9
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user