Implement DISALLOW_SHARE_INTO_MANAGED_PROFILE
Add a user restriction to allow profile owners to enforce a stronger
isolation of managed profile by preventing users sharing data into
the profile. This is achieved by disabling a subset of built-in cross
profile intent filters added by ManagedProvisioning during profile
inflation.
Implementation wise, DevicePolicyManagerService listens for the restriction
change and notifies ManagedProvisioning to modify the built-in intent
filters. This is needed since ManagedProvisioning has ground truth of all
built-in intent filters and manages them. It also has the advantage that
ManagedProvisioning only needs to run when a policy change happens.
Test: cts-tradefed run cts-dev -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.ManagedProfileTest#testDisallowSharingIntoProfileFromPersonal
Test: cts-tradefed run cts-dev -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.ManagedProfileTest#testDisallowSharingIntoProfileFromProfile
Bug: 63911046
Change-Id: Ia6d12a5086627d1280325cd19d6e3a0752dae633
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 57030e4..1df0ff2 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -87,6 +87,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.devicepolicy.DevicePolicyManagerService.RestrictionsListener;
import com.android.server.pm.UserRestrictionsUtils;
import org.hamcrest.BaseMatcher;
@@ -4020,6 +4021,8 @@
dpm.setPasswordMinimumNumeric(admin1, 1);
dpm.setPasswordMinimumSymbols(admin1, 0);
+ reset(mContext.spiedContext);
+
PasswordMetrics passwordMetricsNoSymbols = new PasswordMetrics(
DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 9,
8, 2,
@@ -4069,9 +4072,16 @@
dpm.setActivePasswordState(passwordMetrics, userHandle);
dpm.reportPasswordChanged(userHandle);
+ // Drain ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED broadcasts as part of
+ // reportPasswordChanged()
+ verify(mContext.spiedContext, times(3)).sendBroadcastAsUser(
+ MockUtils.checkIntentAction(
+ DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+ MockUtils.checkUserHandle(userHandle));
+
final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED);
intent.setComponent(admin1);
- intent.putExtra(Intent.EXTRA_USER, UserHandle.of(mContext.binder.callingUid));
+ intent.putExtra(Intent.EXTRA_USER, UserHandle.of(userHandle));
verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
MockUtils.checkIntent(intent),
@@ -4482,6 +4492,45 @@
verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(null, caller);
}
+ public void testDisallowSharingIntoProfileSetRestriction() {
+ Bundle restriction = new Bundle();
+ restriction.putBoolean(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, true);
+
+ mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+ RestrictionsListener listener = new RestrictionsListener(mContext);
+ listener.onUserRestrictionsChanged(DpmMockContext.CALLER_USER_HANDLE, restriction,
+ new Bundle());
+ verifyDataSharingChangedBroadcast();
+ }
+
+ public void testDisallowSharingIntoProfileClearRestriction() {
+ Bundle restriction = new Bundle();
+ restriction.putBoolean(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, true);
+
+ mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+ RestrictionsListener listener = new RestrictionsListener(mContext);
+ listener.onUserRestrictionsChanged(DpmMockContext.CALLER_USER_HANDLE, new Bundle(),
+ restriction);
+ verifyDataSharingChangedBroadcast();
+ }
+
+ public void testDisallowSharingIntoProfileUnchanged() {
+ RestrictionsListener listener = new RestrictionsListener(mContext);
+ listener.onUserRestrictionsChanged(DpmMockContext.CALLER_USER_HANDLE, new Bundle(),
+ new Bundle());
+ verify(mContext.spiedContext, never()).sendBroadcastAsUser(any(), any());
+ }
+
+ private void verifyDataSharingChangedBroadcast() {
+ Intent expectedIntent = new Intent(
+ DevicePolicyManager.ACTION_DATA_SHARING_RESTRICTION_CHANGED);
+ expectedIntent.setPackage("com.android.managedprovisioning");
+ expectedIntent.putExtra(Intent.EXTRA_USER_ID, DpmMockContext.CALLER_USER_HANDLE);
+ verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
+ MockUtils.checkIntent(expectedIntent),
+ MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
+ }
+
private void verifyCanGetOwnerInstalledCaCerts(
final ComponentName caller, final DpmMockContext callerContext) throws Exception {
final String alias = "cert";
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
index 288a8be..dec962e 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
@@ -91,7 +91,8 @@
@Override
public boolean matches(Object item) {
if (item == null) return false;
- return intent.filterEquals((Intent) item);
+ if (!intent.filterEquals((Intent) item)) return false;
+ return intent.getExtras().kindofEquals(((Intent) item).getExtras());
}
@Override
public void describeTo(Description description) {