summaryrefslogtreecommitdiff
path: root/services/robotests/src
diff options
context:
space:
mode:
authorAlex Kershaw <alexkershaw@google.com>2020-01-15 20:00:05 +0000
committerAlex Kershaw <alexkershaw@google.com>2020-01-22 13:20:24 +0000
commit4b0197d8ba2cacaed1a2b6a774c78774fdeeffdc (patch)
treee3933f538532e6aee103e81a1ef0b8171bd0aa9c /services/robotests/src
parenta263d01c447f4bf5d946dfb4361ad78a5ecce7b1 (diff)
Reset unset app-ops when the admin sets cross-profile packages.
When the admin unsets cross-profile packages, reset the INTERACT_ACROSS_PROFILES app-op back to the default if it is no longer configurable by the user. Other minor changes: - Remove the explicit app-op permission check from setInteractAcrossProfilesAppOp, since AppOpManager performs that check when required. - Fix the broadcasting logic in CrossProfileAppsServiceImpl to correctly set the component and flags. Bug: 136249261 Bug: 148010178 Test: atest CtsDevicePolicyManagerTestCases:com.android.cts.devicepolicy.ManagedProfileCrossProfileTest Change-Id: Ib8b5f331fb92fc475bc95ad039adf93fac04da37
Diffstat (limited to 'services/robotests/src')
-rw-r--r--services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java116
-rw-r--r--services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java10
2 files changed, 104 insertions, 22 deletions
diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
index 96ff9c1ba726..1a7b1d3f6039 100644
--- a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
+++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
@@ -18,6 +18,8 @@ package com.android.server.pm;
import static android.app.AppOpsManager.MODE_ALLOWED;
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;
import static android.content.Intent.FLAG_RECEIVER_REGISTERED_ONLY;
import static android.content.pm.CrossProfileApps.ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED;
@@ -37,11 +39,13 @@ import android.app.AppOpsManager.Mode;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.ContextWrapper;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.ResolveInfo;
import android.content.pm.parsing.AndroidPackage;
import android.content.pm.parsing.PackageImpl;
import android.os.Process;
@@ -70,6 +74,7 @@ import org.robolectric.shadow.api.Shadow;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -106,6 +111,7 @@ public class CrossProfileAppsServiceImplRoboTest {
MockitoAnnotations.initMocks(this);
mockCrossProfileAppInstalledAndEnabledOnEachProfile();
mockCrossProfileAppRequestsInteractAcrossProfiles();
+ mockCrossProfileAppRegistersBroadcastReceiver();
mockCrossProfileAppWhitelisted();
}
@@ -113,19 +119,21 @@ public class CrossProfileAppsServiceImplRoboTest {
// They are enabled by default, so we simply have to ensure that a package info with an
// application info is returned.
final PackageInfo packageInfo = buildTestPackageInfo();
+ mockCrossProfileAppInstalledOnProfile(
+ packageInfo, PERSONAL_PROFILE_USER_ID, PERSONAL_PROFILE_UID);
+ mockCrossProfileAppInstalledOnProfile(packageInfo, WORK_PROFILE_USER_ID, WORK_PROFILE_UID);
+ }
+
+ private void mockCrossProfileAppInstalledOnProfile(
+ PackageInfo packageInfo, @UserIdInt int userId, int uid) {
when(mPackageManagerInternal.getPackageInfo(
eq(CROSS_PROFILE_APP_PACKAGE_NAME),
/* flags= */ anyInt(),
/* filterCallingUid= */ anyInt(),
- eq(PERSONAL_PROFILE_USER_ID)))
+ eq(userId)))
.thenReturn(packageInfo);
- when(mPackageManagerInternal.getPackageInfo(
- eq(CROSS_PROFILE_APP_PACKAGE_NAME),
- /* flags= */ anyInt(),
- /* filterCallingUid= */ anyInt(),
- eq(WORK_PROFILE_USER_ID)))
- .thenReturn(packageInfo);
- mockCrossProfileAndroidPackage(PackageImpl.forParsing(CROSS_PROFILE_APP_PACKAGE_NAME));
+ when(mPackageManagerInternal.getPackage(uid))
+ .thenReturn(PackageImpl.forParsing(CROSS_PROFILE_APP_PACKAGE_NAME));
}
private PackageInfo buildTestPackageInfo() {
@@ -140,6 +148,31 @@ public class CrossProfileAppsServiceImplRoboTest {
.thenReturn(new String[] {CROSS_PROFILE_APP_PACKAGE_NAME});
}
+ private void mockCrossProfileAppRegistersBroadcastReceiver() {
+ final ShadowApplicationPackageManager shadowApplicationPackageManager =
+ Shadow.extract(mPackageManager);
+ final Intent baseIntent =
+ new Intent(ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED)
+ .setPackage(CROSS_PROFILE_APP_PACKAGE_NAME);
+ final Intent manifestIntent =
+ new Intent(baseIntent)
+ .setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+ | Intent.FLAG_RECEIVER_FOREGROUND);
+ final Intent registeredIntent =
+ new Intent(baseIntent).setFlags(FLAG_RECEIVER_REGISTERED_ONLY);
+ final List<ResolveInfo> resolveInfos = Lists.newArrayList(buildTestResolveInfo());
+ shadowApplicationPackageManager.setResolveInfosForIntent(manifestIntent, resolveInfos);
+ shadowApplicationPackageManager.setResolveInfosForIntent(registeredIntent, resolveInfos);
+ }
+
+ private ResolveInfo buildTestResolveInfo() {
+ final ResolveInfo resolveInfo = new ResolveInfo();
+ resolveInfo.activityInfo = new ActivityInfo();
+ resolveInfo.activityInfo.packageName = CROSS_PROFILE_APP_PACKAGE_NAME;
+ resolveInfo.activityInfo.name = CROSS_PROFILE_APP_PACKAGE_NAME + ".Receiver";
+ return resolveInfo;
+ }
+
private void mockCrossProfileAppWhitelisted() {
when(mDevicePolicyManagerInternal.getAllCrossProfilePackages())
.thenReturn(Lists.newArrayList(CROSS_PROFILE_APP_PACKAGE_NAME));
@@ -191,16 +224,6 @@ public class CrossProfileAppsServiceImplRoboTest {
}
@Test
- public void setInteractAcrossProfilesAppOp_missingManageAppOpsModes_throwsSecurityException() {
- denyPermissions(Manifest.permission.MANAGE_APP_OPS_MODES);
- try {
- mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
- CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
- fail();
- } catch (SecurityException expected) {}
- }
-
- @Test
public void setInteractAcrossProfilesAppOp_setsAppOp() {
mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
@@ -294,6 +317,54 @@ public class CrossProfileAppsServiceImplRoboTest {
assertThat(receivedManifestCanInteractAcrossProfilesChangedBroadcast()).isTrue();
}
+ @Test
+ public void canConfigureInteractAcrossProfiles_packageNotInstalledInProfile_returnsFalse() {
+ mockUninstallCrossProfileAppFromWorkProfile();
+ assertThat(mCrossProfileAppsServiceImpl
+ .canConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
+ .isFalse();
+ }
+
+ private void mockUninstallCrossProfileAppFromWorkProfile() {
+ when(mPackageManagerInternal.getPackageInfo(
+ eq(CROSS_PROFILE_APP_PACKAGE_NAME),
+ /* flags= */ anyInt(),
+ /* filterCallingUid= */ anyInt(),
+ eq(WORK_PROFILE_USER_ID)))
+ .thenReturn(null);
+ when(mPackageManagerInternal.getPackage(WORK_PROFILE_UID)).thenReturn(null);
+ }
+
+ @Test
+ public void canConfigureInteractAcrossProfiles_packageDoesNotRequestInteractAcrossProfiles_returnsFalse()
+ throws Exception {
+ mockCrossProfileAppDoesNotRequestInteractAcrossProfiles();
+ assertThat(mCrossProfileAppsServiceImpl
+ .canConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
+ .isFalse();
+ }
+
+ private void mockCrossProfileAppDoesNotRequestInteractAcrossProfiles() throws Exception {
+ final String permissionName = Manifest.permission.INTERACT_ACROSS_PROFILES;
+ when(mIPackageManager.getAppOpPermissionPackages(permissionName))
+ .thenReturn(new String[] {});
+ }
+
+ @Test
+ public void canConfigureInteractAcrossProfiles_packageNotWhitelisted_returnsFalse() {
+ mockCrossProfileAppNotWhitelisted();
+ assertThat(mCrossProfileAppsServiceImpl
+ .canConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
+ .isFalse();
+ }
+
+ @Test
+ public void canConfigureInteractAcrossProfiles_returnsTrue() {
+ assertThat(mCrossProfileAppsServiceImpl
+ .canConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
+ .isTrue();
+ }
+
private void explicitlySetInteractAcrossProfilesAppOp(@Mode int mode) {
explicitlySetInteractAcrossProfilesAppOp(PERSONAL_PROFILE_UID, mode);
}
@@ -311,7 +382,6 @@ public class CrossProfileAppsServiceImplRoboTest {
shadowOf(mContext).denyPermissions(Process.myPid(), CALLING_UID, permissions);
}
-
private @Mode int getCrossProfileAppOp() {
return getCrossProfileAppOp(PERSONAL_PROFILE_UID);
}
@@ -365,10 +435,12 @@ public class CrossProfileAppsServiceImplRoboTest {
}
private boolean isBroadcastManifestCanInteractAcrossProfilesChanged(Intent intent) {
- // The manifest check is negative since the FLAG_RECEIVER_REGISTERED_ONLY flag means that
- // manifest receivers can NOT receive the broadcast.
return isBroadcastCanInteractAcrossProfilesChanged(intent)
- && (intent.getFlags() & FLAG_RECEIVER_REGISTERED_ONLY) == 0;
+ && (intent.getFlags() & FLAG_RECEIVER_REGISTERED_ONLY) == 0
+ && (intent.getFlags() & FLAG_RECEIVER_INCLUDE_BACKGROUND) != 0
+ && (intent.getFlags() & FLAG_RECEIVER_FOREGROUND) != 0
+ && intent.getComponent() != null
+ && intent.getComponent().getPackageName().equals(CROSS_PROFILE_APP_PACKAGE_NAME);
}
private void declareCrossProfileAttributeOnCrossProfileApp(boolean value) {
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
index 1443eabf07d5..aea36e555ad7 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowApplicationPackageManager.java
@@ -19,7 +19,10 @@ package com.android.server.testing.shadows;
import static android.content.pm.PackageManager.NameNotFoundException;
import android.app.ApplicationPackageManager;
+import android.content.Intent;
import android.content.pm.PackageInfo;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
import android.util.ArrayMap;
import org.robolectric.annotation.Implements;
@@ -100,6 +103,13 @@ public class ShadowApplicationPackageManager
return sPackageUids.get(packageName);
}
+ @Override
+ protected List<ResolveInfo> queryBroadcastReceiversAsUser(
+ Intent intent, int flags, UserHandle userHandle) {
+ // Currently does not handle multi-user.
+ return queryBroadcastReceivers(intent, flags);
+ }
+
/** Clear package state. */
@Resetter
public static void reset() {