Create public API for policy transparency outside of Settings

The new DPM.createAdminSupportIntent() returns an intent that shows the
"This action was disabled by your admin"-dialog from settings.
This enables apps to inform the user about the cause of restricted
functionality.

A new extra for the intent allows to specialize the dialog for different
restricted features, instead of a generic message for all features.

Bug: 31215663
Test: runtest -c com.android.server.devicepolicy.DevicePolicyManagerTest frameworks-services

Change-Id: I3de7aeec0f88b8f013a63957aec803cd123fbedc
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 5d4c3cf..c29668f 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -1950,6 +1950,81 @@
         }
     }
 
+    public void testCreateAdminSupportIntent() throws Exception {
+        // Setup device owner.
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        setupDeviceOwner();
+
+        // Nonexisting permission returns null
+        Intent intent = dpm.createAdminSupportIntent("disallow_nothing");
+        assertNull(intent);
+
+        // Existing permission that is not set returns null
+        intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
+        assertNull(intent);
+
+        // Existing permission that is not set by device/profile owner returns null
+        when(mContext.userManager.hasUserRestriction(
+                eq(UserManager.DISALLOW_ADJUST_VOLUME),
+                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
+                .thenReturn(true);
+        intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
+        assertNull(intent);
+
+        // Permission that is set by device owner returns correct intent
+        when(mContext.userManager.getUserRestrictionSource(
+                eq(UserManager.DISALLOW_ADJUST_VOLUME),
+                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
+                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+        intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
+        assertNotNull(intent);
+        assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction());
+        assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
+                intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
+        assertEquals(admin1,
+                (ComponentName) intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN));
+        assertEquals(UserManager.DISALLOW_ADJUST_VOLUME,
+                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
+
+        // Try with POLICY_DISABLE_CAMERA and POLICY_DISABLE_SCREEN_CAPTURE, which are not
+        // user restrictions
+
+        // Camera is not disabled
+        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
+        assertNull(intent);
+
+        // Camera is disabled
+        dpm.setCameraDisabled(admin1, true);
+        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
+        assertNotNull(intent);
+        assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA,
+                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
+
+        // Screen capture is not disabled
+        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
+        assertNull(intent);
+
+        // Screen capture is disabled
+        dpm.setScreenCaptureDisabled(admin1, true);
+        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
+        assertNotNull(intent);
+        assertEquals(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE,
+                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
+
+        // Same checks for different user
+        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+        // Camera should be disabled by device owner
+        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
+        assertNotNull(intent);
+        assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA,
+                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
+        assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
+                intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
+        // ScreenCapture should not be disabled by device owner
+        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
+        assertNull(intent);
+    }
+
     /**
      * Test for:
      * {@link DevicePolicyManager#setAffiliationIds}