Show all apps that requested cross profile permission

show all apps that requested the permission, show the admin
restricted dialog if the app is not whitelisted by the admin,
and show a link to install the app if the app is missing in one
of the profiles.

Bug: 149742043
Test: make RunSettingsRoboTests ROBOTEST_FILTER=InteractAcrossProfilesPreferenceControllerTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=InteractAcrossProfilesControllerTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=InteractAcrossProfilesSettingsTest
Test: make RunSettingsRoboTests ROBOTEST_FILTER=InteractAcrossProfilesDetailsTest

Change-Id: I2bc86b9966a2e14a12ee8f4b7f1b75f866ed98e3
This commit is contained in:
kholoud mohamed
2020-03-18 17:00:50 +00:00
parent 6f16992d3c
commit 4d0edf369f
9 changed files with 428 additions and 148 deletions

View File

@@ -22,14 +22,18 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.CrossProfileApps;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.os.Process;
import android.content.pm.UserInfo;
import android.os.UserManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -37,6 +41,9 @@ import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class InteractAcrossProfilesDetailsTest {
private static final int PERSONAL_PROFILE_ID = 0;
private static final int WORK_PROFILE_ID = 10;
private static final int PACKAGE_UID = 0;
private static final String CROSS_PROFILE_PACKAGE_NAME = "crossProfilePackage";
public static final String INTERACT_ACROSS_PROFILES_PERMISSION =
"android.permission.INTERACT_ACROSS_PROFILES";
@@ -44,29 +51,53 @@ public class InteractAcrossProfilesDetailsTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
private final PackageManager mPackageManager = mContext.getPackageManager();
private final InteractAcrossProfilesDetails mFragment = new InteractAcrossProfilesDetails();
private final UserManager mUserManager = mContext.getSystemService(UserManager.class);
private final CrossProfileApps mCrossProfileApps = mContext.getSystemService(
CrossProfileApps.class);
@Test
public void getPreferenceSummary_appOpAllowed_returnsAllowed() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
shadowOf(mCrossProfileApps).addCrossProfilePackage(
CROSS_PROFILE_PACKAGE_NAME);
String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
shadowOf(mAppOpsManager).setMode(
appOp, Process.myUid(), CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
appOp, PACKAGE_UID, CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
assertThat(mFragment.getPreferenceSummary(
mContext, CROSS_PROFILE_PACKAGE_NAME, Process.myUid()))
assertThat(InteractAcrossProfilesDetails.getPreferenceSummary(
mContext, CROSS_PROFILE_PACKAGE_NAME))
.isEqualTo(mContext.getString(R.string.app_permission_summary_allowed));
}
@Test
public void getPreferenceSummary_appOpNotAllowed_returnsNotAllowed() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
shadowOf(mCrossProfileApps).addCrossProfilePackage(
CROSS_PROFILE_PACKAGE_NAME);
String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
shadowOf(mAppOpsManager).setMode(
appOp, Process.myUid(), CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_IGNORED);
appOp, PACKAGE_UID, CROSS_PROFILE_PACKAGE_NAME, AppOpsManager.MODE_IGNORED);
shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
assertThat(mFragment.getPreferenceSummary(
mContext, CROSS_PROFILE_PACKAGE_NAME, Process.myUid()))
assertThat(InteractAcrossProfilesDetails.getPreferenceSummary(
mContext, CROSS_PROFILE_PACKAGE_NAME))
.isEqualTo(mContext.getString(R.string.app_permission_summary_not_allowed));
}

View File

@@ -21,12 +21,15 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.content.pm.CrossProfileApps;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -36,25 +39,34 @@ public class InteractAcrossProfilesPreferenceControllerTest {
private static final String CROSS_PROFILE_PACKAGE_NAME = "crossProfilePackage";
private static final String NOT_CROSS_PROFILE_PACKAGE_NAME = "notCrossProfilePackage";
public static final String INTERACT_ACROSS_PROFILES_PERMISSION =
"android.permission.INTERACT_ACROSS_PROFILES";
private static final int PROFILE_ID = 0;
private final Context mContext = ApplicationProvider.getApplicationContext();
private final CrossProfileApps mCrossProfileApps =
mContext.getSystemService(CrossProfileApps.class);
private final PackageManager mPackageManager = mContext.getPackageManager();
private final InteractAcrossProfilesDetailsPreferenceController mController =
new InteractAcrossProfilesDetailsPreferenceController(mContext, "test_key");
@Test
public void getAvailabilityStatus_crossProfilePackage_returnsAvailable() {
public void getAvailabilityStatus_requestedCrossProfilePermission_returnsAvailable() {
mController.setPackageName(CROSS_PROFILE_PACKAGE_NAME);
shadowOf(mCrossProfileApps).addCrossProfilePackage(CROSS_PROFILE_PACKAGE_NAME);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PROFILE_ID, ImmutableList.of(CROSS_PROFILE_PACKAGE_NAME));
PackageInfo packageInfo = shadowOf(mPackageManager).getInternalMutablePackageInfo(
CROSS_PROFILE_PACKAGE_NAME);
packageInfo.requestedPermissions = new String[]{
INTERACT_ACROSS_PROFILES_PERMISSION};
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_notCrossProfilePackage_returnsDisabled() {
public void getAvailabilityStatus_notRequestedCrossProfilePermission_returnsDisabled() {
mController.setPackageName(NOT_CROSS_PROFILE_PACKAGE_NAME);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PROFILE_ID, ImmutableList.of(NOT_CROSS_PROFILE_PACKAGE_NAME));
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.DISABLED_FOR_USER);

View File

@@ -18,14 +18,17 @@ package com.android.settings.applications.specialaccess.interactacrossprofiles;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.CrossProfileApps;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Pair;
@@ -68,49 +71,56 @@ public class InteractAcrossProfilesSettingsTest {
private final CrossProfileApps mCrossProfileApps =
mContext.getSystemService(CrossProfileApps.class);
private final AppOpsManager mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
private final InteractAcrossProfilesSettings mFragment = new InteractAcrossProfilesSettings();
@Test
public void collectConfigurableApps_fromPersonal_returnsPersonalPackages() {
public void collectConfigurableApps_fromPersonal_returnsCombinedPackages() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, 0/* profileFlags */);
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, WORK_PROFILE_INSTALLED_PACKAGES);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(WORK_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(WORK_PROFILE_ID, WORK_CROSS_PROFILE_PACKAGE);
List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
List<Pair<ApplicationInfo, UserHandle>> apps =
InteractAcrossProfilesSettings.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps.size()).isEqualTo(1);
assertThat(apps.get(0).first.packageName).isEqualTo(PERSONAL_CROSS_PROFILE_PACKAGE);
assertThat(apps.size()).isEqualTo(2);
assertTrue(apps.stream().anyMatch(
app -> app.first.packageName.equals(PERSONAL_CROSS_PROFILE_PACKAGE)));
assertTrue(apps.stream().anyMatch(
app -> app.first.packageName.equals(WORK_CROSS_PROFILE_PACKAGE)));
}
@Test
public void collectConfigurableApps_fromWork_returnsPersonalPackages() {
public void collectConfigurableApps_fromWork_returnsCombinedPackages() {
shadowOf(mUserManager).addUser(
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, 0/* profileFlags */);
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
ShadowProcess.setUid(WORK_UID);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, WORK_PROFILE_INSTALLED_PACKAGES);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(WORK_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(WORK_PROFILE_ID, WORK_CROSS_PROFILE_PACKAGE);
List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
List<Pair<ApplicationInfo, UserHandle>> apps =
InteractAcrossProfilesSettings.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps.size()).isEqualTo(1);
assertThat(apps.get(0).first.packageName).isEqualTo(PERSONAL_CROSS_PROFILE_PACKAGE);
assertThat(apps.size()).isEqualTo(2);
assertTrue(apps.stream().anyMatch(
app -> app.first.packageName.equals(PERSONAL_CROSS_PROFILE_PACKAGE)));
assertTrue(apps.stream().anyMatch(
app -> app.first.packageName.equals(WORK_CROSS_PROFILE_PACKAGE)));
}
@Test
@@ -119,10 +129,11 @@ public class InteractAcrossProfilesSettingsTest {
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
List<Pair<ApplicationInfo, UserHandle>> apps = mFragment.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
List<Pair<ApplicationInfo, UserHandle>> apps =
InteractAcrossProfilesSettings.collectConfigurableApps(
mPackageManager, mUserManager, mCrossProfileApps);
assertThat(apps).isEmpty();
}
@@ -133,11 +144,14 @@ public class InteractAcrossProfilesSettingsTest {
PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
shadowOf(mUserManager).addProfile(
PERSONAL_PROFILE_ID, WORK_PROFILE_ID,
"work-profile"/* profileName */, 0/* profileFlags */);
"work-profile"/* profileName */, UserInfo.FLAG_MANAGED_PROFILE);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
PERSONAL_PROFILE_ID, PERSONAL_PROFILE_INSTALLED_PACKAGES);
shadowOf(mPackageManager).setInstalledPackagesForUserId(
WORK_PROFILE_ID, WORK_PROFILE_INSTALLED_PACKAGES);
installCrossProfilePackage(PERSONAL_PROFILE_ID, PERSONAL_CROSS_PROFILE_PACKAGE);
installCrossProfilePackage(WORK_PROFILE_ID, WORK_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_CROSS_PROFILE_PACKAGE);
shadowOf(mCrossProfileApps).addCrossProfilePackage(PERSONAL_NON_CROSS_PROFILE_PACKAGE);
String appOp = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES_PERMISSION);
shadowOf(mAppOpsManager).setMode(
appOp, PACKAGE_UID, PERSONAL_CROSS_PROFILE_PACKAGE, AppOpsManager.MODE_ALLOWED);
@@ -145,12 +159,19 @@ public class InteractAcrossProfilesSettingsTest {
appOp, PACKAGE_UID, PERSONAL_NON_CROSS_PROFILE_PACKAGE, AppOpsManager.MODE_IGNORED);
shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
int numOfApps = mFragment.getNumberOfEnabledApps(
int numOfApps = InteractAcrossProfilesSettings.getNumberOfEnabledApps(
mContext, mPackageManager, mUserManager, mCrossProfileApps);
assertThat(numOfApps).isEqualTo(1);
}
private void installCrossProfilePackage(int profileId, String packageName) {
PackageInfo personalPackageInfo = shadowOf(mPackageManager).getInternalMutablePackageInfo(
packageName);
personalPackageInfo.requestedPermissions = new String[]{
INTERACT_ACROSS_PROFILES_PERMISSION};
}
private PermissionInfo createCrossProfilesPermissionInfo() {
PermissionInfo permissionInfo = new PermissionInfo();
permissionInfo.name = INTERACT_ACROSS_PROFILES_PERMISSION;