Merge "Add hidden API to clear all cross-profile app-ops" into rvc-dev

This commit is contained in:
Alex Kershaw
2020-03-26 10:52:39 +00:00
committed by Android (Google) Code Review
4 changed files with 67 additions and 1 deletions

View File

@@ -487,6 +487,34 @@ public class CrossProfileApps {
}
}
/**
* Clears the app-op for {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES} back to
* its default value for every package on the device.
*
* <p>This method can be used to ensure that app-op state is not left around on existing users
* for previously-configured profiles.
*
* <p>If the caller does not have the {@link android.Manifest.permission
* #CONFIGURE_INTERACT_ACROSS_PROFILES} permission, then they must have the permissions that
* would have been required to call {@link android.app.AppOpsManager#setMode(int, int, String,
* int)}, which includes {@link android.Manifest.permission#MANAGE_APP_OPS_MODES}.
*
* <p>Also requires either {@link android.Manifest.permission#INTERACT_ACROSS_USERS} or {@link
* android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}.
*
* @hide
*/
@RequiresPermission(
allOf={android.Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES,
android.Manifest.permission.INTERACT_ACROSS_USERS})
public void clearInteractAcrossProfilesAppOps() {
try {
mService.clearInteractAcrossProfilesAppOps();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
private void verifyCanAccessUser(UserHandle userHandle) {
if (!getTargetUserProfiles().contains(userHandle)) {
throw new SecurityException("Not allowed to access " + userHandle);

View File

@@ -40,4 +40,5 @@ interface ICrossProfileApps {
boolean canConfigureInteractAcrossProfiles(in String packageName);
boolean canUserAttemptToConfigureInteractAcrossProfiles(in String packageName);
void resetInteractAcrossProfilesAppOps(in List<String> packageNames);
void clearInteractAcrossProfilesAppOps();
}

View File

@@ -64,6 +64,7 @@ import com.android.server.wm.ActivityTaskManagerInternal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
private static final String TAG = "CrossProfileAppsService";
@@ -447,7 +448,7 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
final int uid = mInjector.getPackageManager()
.getPackageUidAsUser(packageName, /* flags= */ 0, userId);
if (currentModeEquals(newMode, packageName, uid)) {
Slog.w(TAG, "Attempt to set mode to existing value of " + newMode + " for "
Slog.i(TAG, "Attempt to set mode to existing value of " + newMode + " for "
+ packageName + " on user ID " + userId);
return;
}
@@ -577,6 +578,24 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
setInteractAcrossProfilesAppOp(packageName, AppOpsManager.opToDefaultMode(op));
}
@Override
public void clearInteractAcrossProfilesAppOps() {
final int defaultMode =
AppOpsManager.opToDefaultMode(
AppOpsManager.permissionToOp(Manifest.permission.INTERACT_ACROSS_PROFILES));
findAllPackageNames()
.forEach(packageName -> setInteractAcrossProfilesAppOp(packageName, defaultMode));
}
private List<String> findAllPackageNames() {
return mInjector.getPackageManagerInternal()
.getInstalledApplications(
/* flags= */ 0, mInjector.getCallingUserId(), mInjector.getCallingUid())
.stream()
.map(applicationInfo -> applicationInfo.packageName)
.collect(Collectors.toList());
}
CrossProfileAppsInternal getLocalService() {
return mLocalService;
}

View File

@@ -17,6 +17,7 @@
package com.android.server.pm;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.OP_INTERACT_ACROSS_PROFILES;
import static android.content.Intent.FLAG_RECEIVER_FOREGROUND;
import static android.content.Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND;
@@ -104,6 +105,7 @@ public class CrossProfileAppsServiceImplRoboTest {
private final CrossProfileAppsServiceImpl mCrossProfileAppsServiceImpl =
new CrossProfileAppsServiceImpl(mContext, mInjector);
private final Map<UserHandle, Set<Intent>> mSentUserBroadcasts = new HashMap<>();
private final Map<Integer, List<ApplicationInfo>> installedApplications = new HashMap<>();
@Mock private PackageManagerInternal mPackageManagerInternal;
@Mock private IPackageManager mIPackageManager;
@@ -112,12 +114,18 @@ public class CrossProfileAppsServiceImplRoboTest {
@Before
public void initializeMocks() throws Exception {
MockitoAnnotations.initMocks(this);
initializeInstalledApplicationsMock();
mockCrossProfileAppInstalledAndEnabledOnEachProfile();
mockCrossProfileAppRequestsInteractAcrossProfiles();
mockCrossProfileAppRegistersBroadcastReceiver();
mockCrossProfileAppWhitelisted();
}
private void initializeInstalledApplicationsMock() {
when(mPackageManagerInternal.getInstalledApplications(anyInt(), anyInt(), eq(CALLING_UID)))
.thenAnswer(invocation -> installedApplications.get(invocation.getArgument(1)));
}
private void mockCrossProfileAppInstalledAndEnabledOnEachProfile() {
// They are enabled by default, so we simply have to ensure that a package info with an
// application info is returned.
@@ -138,11 +146,14 @@ public class CrossProfileAppsServiceImplRoboTest {
when(mPackageManagerInternal.getPackage(uid))
.thenReturn(((ParsedPackage) PackageImpl.forTesting(CROSS_PROFILE_APP_PACKAGE_NAME)
.hideAsParsed()).hideAsFinal());
installedApplications.putIfAbsent(userId, new ArrayList<>());
installedApplications.get(userId).add(packageInfo.applicationInfo);
}
private PackageInfo buildTestPackageInfo() {
PackageInfo packageInfo = new PackageInfo();
packageInfo.applicationInfo = new ApplicationInfo();
packageInfo.applicationInfo.packageName = CROSS_PROFILE_APP_PACKAGE_NAME;
return packageInfo;
}
@@ -451,6 +462,13 @@ public class CrossProfileAppsServiceImplRoboTest {
.isTrue();
}
@Test
public void clearInteractAcrossProfilesAppOps() {
explicitlySetInteractAcrossProfilesAppOp(MODE_ALLOWED);
mCrossProfileAppsServiceImpl.clearInteractAcrossProfilesAppOps();
assertThat(getCrossProfileAppOp()).isEqualTo(MODE_DEFAULT);
}
private void explicitlySetInteractAcrossProfilesAppOp(@Mode int mode) {
explicitlySetInteractAcrossProfilesAppOp(PERSONAL_PROFILE_UID, mode);
}