diff options
| author | 2019-12-12 19:53:16 +0000 | |
|---|---|---|
| committer | 2019-12-12 19:53:16 +0000 | |
| commit | 6137064d412ff6c63a2f6058363c098fc2d0c7b1 (patch) | |
| tree | 07184376a0557c46475de17396dd59384bfe2118 | |
| parent | c8bc76efff28708bceda138a1062efb63f1e93a3 (diff) | |
| parent | 434a224cb3db6acc8979ace4c7c030d1a0644aac (diff) | |
Merge "Add admin consent cross-profile package APIs"
5 files changed, 124 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt index a84ae5dbe992..824aac51c63a 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6739,6 +6739,7 @@ package android.app.admin { method @Nullable public java.util.Set<java.lang.String> getCrossProfileCalendarPackages(@NonNull android.content.ComponentName); method public boolean getCrossProfileCallerIdDisabled(@NonNull android.content.ComponentName); method public boolean getCrossProfileContactsSearchDisabled(@NonNull android.content.ComponentName); + method @NonNull public java.util.Set<java.lang.String> getCrossProfilePackages(@NonNull android.content.ComponentName); method @NonNull public java.util.List<java.lang.String> getCrossProfileWidgetProviders(@NonNull android.content.ComponentName); method public int getCurrentFailedPasswordAttempts(); method @Nullable public java.util.List<java.lang.String> getDelegatePackages(@NonNull android.content.ComponentName, @NonNull String); @@ -6856,6 +6857,7 @@ package android.app.admin { method public void setCrossProfileCalendarPackages(@NonNull android.content.ComponentName, @Nullable java.util.Set<java.lang.String>); method public void setCrossProfileCallerIdDisabled(@NonNull android.content.ComponentName, boolean); method public void setCrossProfileContactsSearchDisabled(@NonNull android.content.ComponentName, boolean); + method public void setCrossProfilePackages(@NonNull android.content.ComponentName, @NonNull java.util.Set<java.lang.String>); method public void setDefaultSmsApplication(@NonNull android.content.ComponentName, @NonNull String); method public void setDelegatedScopes(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.List<java.lang.String>); method public void setDeviceOwnerLockScreenInfo(@NonNull android.content.ComponentName, CharSequence); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 915e4572c035..63eb7ceae8b2 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -11085,6 +11085,53 @@ public class DevicePolicyManager { } /** + * Sets the set of package names that are allowed to request user consent for cross-profile + * communication. + * + * <p>Assumes that the caller is a profile owner and is the given {@code admin}. + * + * <p>Previous calls are overridden by each subsequent call to this method. + * + * @param admin the {@link DeviceAdminReceiver} this request is associated with + * @param packageNames the new cross-profile package names + */ + public void setCrossProfilePackages( + @NonNull ComponentName admin, @NonNull Set<String> packageNames) { + throwIfParentInstance("setCrossProfilePackages"); + if (mService != null) { + try { + mService.setCrossProfilePackages(admin, new ArrayList<>(packageNames)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Returns the set of package names that the admin has previously set as allowed to request user + * consent for cross-profile communication, via {@link + * #setCrossProfilePackages(ComponentName, Set)}. + * + * <p>Assumes that the caller is a profile owner and is the given {@code admin}. + * + * @param admin the {@link DeviceAdminReceiver} this request is associated with + * @return the set of package names the admin has previously set as allowed to request user + * consent for cross-profile communication, via {@link + * #setCrossProfilePackages(ComponentName, Set)} + */ + public @NonNull Set<String> getCrossProfilePackages(@NonNull ComponentName admin) { + throwIfParentInstance("getCrossProfilePackages"); + if (mService != null) { + try { + return new ArraySet<>(mService.getCrossProfilePackages(admin)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return Collections.emptySet(); + } + + /** * Returns whether the device is being used as a managed kiosk. These requirements are as * follows: * <ul> diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 34246fa808bd..ff1ecd558400 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -438,6 +438,9 @@ interface IDevicePolicyManager { boolean isPackageAllowedToAccessCalendarForUser(String packageName, int userHandle); List<String> getCrossProfileCalendarPackagesForUser(int userHandle); + void setCrossProfilePackages(in ComponentName admin, in List<String> packageNames); + List<String> getCrossProfilePackages(in ComponentName admin); + boolean isManagedKiosk(); boolean isUnattendedManagedKiosk(); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index ee0449d95e00..eb1753bdbee7 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -990,6 +990,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { "cross-profile-calendar-packages"; private static final String TAG_CROSS_PROFILE_CALENDAR_PACKAGES_NULL = "cross-profile-calendar-packages-null"; + private static final String TAG_CROSS_PROFILE_PACKAGES = "cross-profile-packages"; DeviceAdminInfo info; @@ -1104,6 +1105,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // is whitelisted. List<String> mCrossProfileCalendarPackages = Collections.emptyList(); + // The whitelist of packages that the admin has enabled to be able to request consent from + // the user to communicate cross-profile. By default, no packages are whitelisted, which is + // represented as an empty list. + List<String> mCrossProfilePackages = Collections.emptyList(); + ActiveAdmin(DeviceAdminInfo _info, boolean parent) { info = _info; isParent = parent; @@ -1329,6 +1335,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { writePackageListToXml(out, TAG_CROSS_PROFILE_CALENDAR_PACKAGES, mCrossProfileCalendarPackages); } + writePackageListToXml(out, TAG_CROSS_PROFILE_PACKAGES, mCrossProfilePackages); } void writeTextToXml(XmlSerializer out, String tag, String text) throws IOException { @@ -1560,6 +1567,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mCrossProfileCalendarPackages = readPackageList(parser, tag); } else if (TAG_CROSS_PROFILE_CALENDAR_PACKAGES_NULL.equals(tag)) { mCrossProfileCalendarPackages = null; + } else if (TAG_CROSS_PROFILE_PACKAGES.equals(tag)) { + mCrossProfilePackages = readPackageList(parser, tag); } else { Slog.w(LOG_TAG, "Unknown admin tag: " + tag); XmlUtils.skipCurrentTag(parser); @@ -1783,6 +1792,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pw.print("mCrossProfileCalendarPackages="); pw.println(mCrossProfileCalendarPackages); } + pw.print("mCrossProfilePackages="); + pw.println(mCrossProfilePackages); } } @@ -14645,6 +14656,35 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override + public void setCrossProfilePackages(ComponentName who, List<String> packageNames) { + if (!mHasFeature) { + return; + } + Preconditions.checkNotNull(who, "ComponentName is null"); + Preconditions.checkNotNull(packageNames, "Package names is null"); + synchronized (getLockObject()) { + final ActiveAdmin admin = + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + admin.mCrossProfilePackages = packageNames; + saveSettingsLocked(mInjector.userHandleGetCallingUserId()); + } + } + + @Override + public List<String> getCrossProfilePackages(ComponentName who) { + if (!mHasFeature) { + return Collections.emptyList(); + } + Preconditions.checkNotNull(who, "ComponentName is null"); + + synchronized (getLockObject()) { + final ActiveAdmin admin = getActiveAdminForCallerLocked( + who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + return admin.mCrossProfilePackages; + } + } + + @Override public boolean isManagedKiosk() { if (!mHasFeature) { return false; diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 43d8f927a57e..3f09f579369e 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -5548,6 +5548,38 @@ public class DevicePolicyManagerTest extends DpmTestBase { mServiceContext.binder.restoreCallingIdentity(ident); } + public void testGetCrossProfilePackages_notSet_returnsEmpty() { + setAsProfileOwner(admin1); + assertTrue(dpm.getCrossProfilePackages(admin1).isEmpty()); + } + + public void testGetCrossProfilePackages_notSet_dpmsReinitialized_returnsEmpty() { + setAsProfileOwner(admin1); + + initializeDpms(); + + assertTrue(dpm.getCrossProfilePackages(admin1).isEmpty()); + } + + public void testGetCrossProfilePackages_whenSet_returnsEqual() { + setAsProfileOwner(admin1); + Set<String> packages = Collections.singleton("TEST_PACKAGE"); + + dpm.setCrossProfilePackages(admin1, packages); + + assertEquals(packages, dpm.getCrossProfilePackages(admin1)); + } + + public void testGetCrossProfilePackages_whenSet_dpmsReinitialized_returnsEqual() { + setAsProfileOwner(admin1); + Set<String> packages = Collections.singleton("TEST_PACKAGE"); + + dpm.setCrossProfilePackages(admin1, packages); + initializeDpms(); + + assertEquals(packages, dpm.getCrossProfilePackages(admin1)); + } + // admin1 is the outgoing DPC, adminAnotherPakcage is the incoming one. private void assertDeviceOwnershipRevertedWithFakeTransferMetadata() throws Exception { writeFakeTransferMetadataFile(UserHandle.USER_SYSTEM, |