summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author kholoud mohamed <kholoudm@google.com> 2020-03-18 12:49:32 +0000
committer Kholoud Mohamed <kholoudm@google.com> 2020-03-23 17:23:17 +0000
commit2459a08f86b6d4794a8e95a08b77c4984f9a080a (patch)
tree96e90428ddba50098bbfb93dbb6cd3846afca4fd
parent8c6b17b1ad1c1d2d6687b95d71cf85639d99e0fb (diff)
Add new hidden API in CrossProfileApps and other minor changes
* Added a new hidden API canUserAttemptToConfigureInteractAcrossProfiles to be used in settings. * Changed canRequestToInteractAcrossProfiles to return true when app is not whitelisted by the admin or installed in the other profile, this enables the app to navigate the user to the cross profile settings page were more information about why they can't grant the permission will be provided. Bug: 149742043 Test: atest CrossProfileAppsServiceImplRoboTest Test: atest CrossProfileAppsPermissionHostSideTest Test: CrossProfileAppsTest Change-Id: I9c7734d7ab0c7436d84a27604146ff539e1cb26a
-rw-r--r--core/java/android/content/pm/CrossProfileApps.java29
-rw-r--r--core/java/android/content/pm/ICrossProfileApps.aidl1
-rw-r--r--services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java24
-rw-r--r--services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java32
4 files changed, 75 insertions, 11 deletions
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 179fc5c661a5..6ba811e077ac 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -268,15 +268,17 @@ public class CrossProfileApps {
}
/**
- * Returns whether the calling package can request user consent to interact across profiles.
+ * Returns whether the calling package can request to navigate the user to
+ * the relevant settings page to request user consent to interact across profiles.
*
- * <p>If {@code true}, user consent can be obtained via {@link
+ * <p>If {@code true}, the navigation intent can be obtained via {@link
* #createRequestInteractAcrossProfilesIntent()}. The package can then listen to {@link
* #ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED} broadcasts.
*
* <p>Specifically, returns whether the following are all true:
* <ul>
- * <li>{@link #getTargetUserProfiles()} returns a non-empty list for the calling user.</li>
+ * <li>{@code UserManager#getEnabledProfileIds(int)} ()} returns at least one other profile for
+ * the calling user.</li>
* <li>The calling app has requested</li>
* {@code android.Manifest.permission.INTERACT_ACROSS_PROFILES} in its manifest.
* <li>The calling package has either been whitelisted by default by the OEM or has been
@@ -285,6 +287,10 @@ public class CrossProfileApps {
* </li>
* </ul>
*
+ * <p>Note that in order for the user to be able to grant the consent, the requesting package
+ * must be whitelisted by the admin or the OEM and installed in the other profile. If this is
+ * not the case the user will be shown a message explaining why they can't grant the consent.
+ *
* <p>Note that user consent could already be granted if given a return value of {@code true}.
* The package's current ability to interact across profiles can be checked with {@link
* #canInteractAcrossProfiles()}.
@@ -422,6 +428,23 @@ public class CrossProfileApps {
}
/**
+ * Returns {@code true} if the given package has requested
+ * {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES} and the user has at least one
+ * other profile in the same profile group.
+ *
+ * <p>This differs from {@link #canConfigureInteractAcrossProfiles(String)} since it will
+ * not return {@code false} if the app is not whitelisted or not installed in the other profile.
+ *
+ * @hide
+ */
+ public boolean canUserAttemptToConfigureInteractAcrossProfiles(String packageName) {
+ try {
+ return mService.canUserAttemptToConfigureInteractAcrossProfiles(packageName);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+ /**
* For each of the packages defined in {@code previousCrossProfilePackages} but not included in
* {@code newCrossProfilePackages}, resets the app-op for {@link android.Manifest.permission
* #INTERACT_ACROSS_PROFILES} back to its default value if it can no longer be configured by
diff --git a/core/java/android/content/pm/ICrossProfileApps.aidl b/core/java/android/content/pm/ICrossProfileApps.aidl
index 4cecb30990e6..9b0dae221538 100644
--- a/core/java/android/content/pm/ICrossProfileApps.aidl
+++ b/core/java/android/content/pm/ICrossProfileApps.aidl
@@ -38,5 +38,6 @@ interface ICrossProfileApps {
boolean canRequestInteractAcrossProfiles(in String callingPackage);
void setInteractAcrossProfilesAppOp(in String packageName, int newMode);
boolean canConfigureInteractAcrossProfiles(in String packageName);
+ boolean canUserAttemptToConfigureInteractAcrossProfiles(in String packageName);
void resetInteractAcrossProfilesAppOps(in List<String> packageNames);
}
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index 83da38195053..7069818e3894 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -249,16 +249,13 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
}
private boolean canRequestInteractAcrossProfilesUnchecked(String packageName) {
- List<UserHandle> targetUserProfiles =
- getTargetUserProfilesUnchecked(packageName, mInjector.getCallingUserId());
- if (targetUserProfiles.isEmpty()) {
- return false;
- }
- if (!hasRequestedAppOpPermission(
- AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName)) {
+ final int[] enabledProfileIds =
+ mInjector.getUserManager().getEnabledProfileIds(mInjector.getCallingUserId());
+ if (enabledProfileIds.length < 2) {
return false;
}
- return isCrossProfilePackageWhitelisted(packageName);
+ return hasRequestedAppOpPermission(
+ AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName);
}
private boolean hasRequestedAppOpPermission(String permission, String packageName) {
@@ -540,6 +537,17 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
return isCrossProfilePackageWhitelisted(packageName);
}
+ @Override
+ public boolean canUserAttemptToConfigureInteractAcrossProfiles(String packageName) {
+ final int[] profileIds = mInjector.getUserManager().getProfileIds(
+ mInjector.getCallingUserId(), /* enabledOnly= */ false);
+ if (profileIds.length < 2) {
+ return false;
+ }
+ return hasRequestedAppOpPermission(
+ AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName);
+ }
+
private boolean hasOtherProfileWithPackageInstalled(String packageName, @UserIdInt int userId) {
return mInjector.withCleanCallingIdentity(() -> {
final int[] profileIds =
diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
index fa0febd7f20f..acdb68142178 100644
--- a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
+++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
@@ -419,6 +419,38 @@ public class CrossProfileAppsServiceImplRoboTest {
.isTrue();
}
+ @Test
+ public void canUserAttemptToConfigureInteractAcrossProfiles_packageNotInstalledInProfile_returnsTrue() {
+ mockUninstallCrossProfileAppFromWorkProfile();
+ assertThat(mCrossProfileAppsServiceImpl
+ .canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
+ .isTrue();
+ }
+
+ @Test
+ public void canUserAttemptToConfigureInteractAcrossProfiles_packageDoesNotRequestInteractAcrossProfiles_returnsFalse()
+ throws Exception {
+ mockCrossProfileAppDoesNotRequestInteractAcrossProfiles();
+ assertThat(mCrossProfileAppsServiceImpl
+ .canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
+ .isFalse();
+ }
+
+ @Test
+ public void canUserAttemptToConfigureInteractAcrossProfiles_packageNotWhitelisted_returnsTrue() {
+ mockCrossProfileAppNotWhitelisted();
+ assertThat(mCrossProfileAppsServiceImpl
+ .canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
+ .isTrue();
+ }
+
+ @Test
+ public void canUserAttemptToConfigureInteractAcrossProfiles_returnsTrue() {
+ assertThat(mCrossProfileAppsServiceImpl
+ .canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
+ .isTrue();
+ }
+
private void explicitlySetInteractAcrossProfilesAppOp(@Mode int mode) {
explicitlySetInteractAcrossProfilesAppOp(PERSONAL_PROFILE_UID, mode);
}