Merge "Add settings and reset operations for demo users" into oc-dr1-dev
am: 88710dead0

Change-Id: I7b3aae902eebd27590e4799408e941ee7761b834
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 73bb13a..d249b0a9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2384,6 +2384,9 @@
             BroadcastReceiver result) {
         Intent intent = new Intent(action);
         intent.setComponent(admin.info.getComponent());
+        if (UserManager.isDeviceInDemoMode(mContext)) {
+            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        }
         if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) {
             intent.putExtra("expiration", admin.passwordExpirationDate);
         }
@@ -8183,23 +8186,6 @@
                 return null;
             }
 
-            final UserInfo userInfo = getUserInfo(userHandle);
-            if (userInfo != null && userInfo.isDemo()) {
-                try {
-                    final ApplicationInfo ai = mIPackageManager.getApplicationInfo(adminPkg,
-                            PackageManager.MATCH_DISABLED_COMPONENTS, userHandle);
-                    final boolean isSystemApp =
-                            ai != null && (ai.flags & (ApplicationInfo.FLAG_SYSTEM
-                                    | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
-                    if (isSystemApp) {
-                        mIPackageManager.setApplicationEnabledSetting(adminPkg,
-                                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
-                                PackageManager.DONT_KILL_APP, userHandle, "DevicePolicyManager");
-                    }
-                } catch (RemoteException e) {
-                }
-            }
-
             setActiveAdmin(profileOwner, true, userHandle);
             // User is not started yet, the broadcast by setActiveAdmin will not be received.
             // So we store adminExtras for broadcasting when the user starts for first time.
@@ -8493,6 +8479,8 @@
             enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER,
                     DELEGATION_ENABLE_SYSTEM_APP);
 
+            final boolean isDemo = isCurrentUserDemo();
+
             int userId = UserHandle.getCallingUserId();
             long id = mInjector.binderClearCallingIdentity();
 
@@ -8503,14 +8491,19 @@
                 }
 
                 int parentUserId = getProfileParentId(userId);
-                if (!isSystemApp(mIPackageManager, packageName, parentUserId)) {
+                if (!isDemo && !isSystemApp(mIPackageManager, packageName, parentUserId)) {
                     throw new IllegalArgumentException("Only system apps can be enabled this way.");
                 }
 
                 // Install the app.
                 mIPackageManager.installExistingPackageAsUser(packageName, userId,
                         0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
-
+                if (isDemo) {
+                    // Ensure the app is also ENABLED for demo users.
+                    mIPackageManager.setApplicationEnabledSetting(packageName,
+                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                            PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager");
+                }
             } catch (RemoteException re) {
                 // shouldn't happen
                 Slog.wtf(LOG_TAG, "Failed to install " + packageName, re);
@@ -8955,7 +8948,8 @@
                 return;
             }
 
-            if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) {
+            if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)
+                    && !UserManager.isDeviceInDemoMode(mContext)) {
                 throw new SecurityException(String.format(
                         "Permission denial: device owners cannot update %1$s", setting));
             }
@@ -8987,11 +8981,12 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             if (isDeviceOwner(who, callingUserId)) {
-                if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)) {
+                if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)
+                        && !isCurrentUserDemo()) {
                     throw new SecurityException(String.format(
                             "Permission denial: Device owners cannot update %1$s", setting));
                 }
-            } else if (!SECURE_SETTINGS_WHITELIST.contains(setting)) {
+            } else if (!SECURE_SETTINGS_WHITELIST.contains(setting) && !isCurrentUserDemo()) {
                 throw new SecurityException(String.format(
                         "Permission denial: Profile owners cannot update %1$s", setting));
             }
@@ -9442,12 +9437,6 @@
 
     @Override
     public SystemUpdatePolicy getSystemUpdatePolicy() {
-        if (UserManager.isDeviceInDemoMode(mContext)) {
-            // Pretending to have an automatic update policy when the device is in retail demo
-            // mode. This will allow the device to download and install an ota without
-            // any user interaction.
-            return SystemUpdatePolicy.createAutomaticInstallPolicy();
-        }
         synchronized (this) {
             SystemUpdatePolicy policy =  mOwners.getSystemUpdatePolicy();
             if (policy != null && !policy.isValid()) {
@@ -10454,6 +10443,19 @@
         }
     }
 
+    private boolean isCurrentUserDemo() {
+        if (UserManager.isDeviceInDemoMode(mContext)) {
+            final int userId = mInjector.userHandleGetCallingUserId();
+            final long callingIdentity = mInjector.binderClearCallingIdentity();
+            try {
+                return mUserManager.getUserInfo(userId).isDemo();
+            } finally {
+                mInjector.binderRestoreCallingIdentity(callingIdentity);
+            }
+        }
+        return false;
+    }
+
     private void removePackageIfRequired(final String packageName, final int userId) {
         if (!packageHasActiveAdmins(packageName, userId)) {
             // Will not do anything if uninstall was not requested or was already started.
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 bad9b5b..23330f1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -382,74 +382,6 @@
         mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
     }
 
-    public void testCreateAndManageUser_demoUserSystemApp() throws Exception {
-        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
-
-        setDeviceOwner();
-
-        final int id = UserHandle.getUserId(DpmMockContext.CALLER_UID);
-
-        final UserInfo demoUserInfo = mock(UserInfo.class);
-        demoUserInfo.id = id;
-        doReturn(UserHandle.of(id)).when(demoUserInfo).getUserHandle();
-        doReturn(true).when(demoUserInfo).isDemo();
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        doReturn(demoUserInfo).when(um).getUserInfo(id);
-        doReturn(demoUserInfo).when(mContext.getUserManagerInternal())
-                .createUserEvenWhenDisallowed(anyString(), anyInt());
-
-        final ApplicationInfo applicationInfo = getServices().ipackageManager.getApplicationInfo(
-                admin2.getPackageName(), PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, id);
-        applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
-        doReturn(applicationInfo).when(getServices().ipackageManager).getApplicationInfo(
-                anyString(), anyInt(), anyInt());
-
-        final UserHandle userHandle = dpm.createAndManageUser(admin1, "", admin2, null, 0);
-
-        verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting(
-                eq(admin2.getPackageName()),
-                eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
-                eq(PackageManager.DONT_KILL_APP),
-                eq(id),
-                anyString());
-
-        assertNotNull(userHandle);
-    }
-
-    public void testCreateAndManageUser_demoUserSystemUpdatedApp() throws Exception {
-        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
-
-        setDeviceOwner();
-
-        final int id = UserHandle.getUserId(DpmMockContext.CALLER_UID);
-
-        final UserInfo demoUserInfo = mock(UserInfo.class);
-        demoUserInfo.id = id;
-        doReturn(UserHandle.of(id)).when(demoUserInfo).getUserHandle();
-        doReturn(true).when(demoUserInfo).isDemo();
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        doReturn(demoUserInfo).when(um).getUserInfo(id);
-        doReturn(demoUserInfo).when(mContext.getUserManagerInternal())
-                .createUserEvenWhenDisallowed(anyString(), anyInt());
-
-        final ApplicationInfo applicationInfo = getServices().ipackageManager.getApplicationInfo(
-                admin2.getPackageName(), PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, id);
-        applicationInfo.flags = ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
-        doReturn(applicationInfo).when(getServices().ipackageManager).getApplicationInfo(
-                anyString(), anyInt(), anyInt());
-
-        final UserHandle userHandle = dpm.createAndManageUser(admin1, "", admin2, null, 0);
-
-        verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting(
-                eq(admin2.getPackageName()),
-                eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
-                eq(PackageManager.DONT_KILL_APP),
-                eq(id),
-                anyString());
-
-        assertNotNull(userHandle);
-    }
-
     public void testSetActiveAdmin_multiUsers() throws Exception {
 
         final int ANOTHER_USER_ID = 100;
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index 8121bcf..99f54ba 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -46,6 +46,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
+import android.provider.Settings;
 import android.security.KeyChain;
 import android.telephony.TelephonyManager;
 import android.test.mock.MockContentResolver;
@@ -53,6 +54,7 @@
 import android.util.Pair;
 import android.view.IWindowManager;
 
+import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.widget.LockPatternUtils;
 
 import java.io.File;
@@ -130,6 +132,7 @@
         packageManager = spy(realContext.getPackageManager());
 
         contentResolver = new MockContentResolver();
+        contentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
 
         // Add the system user with a fake profile group already set up (this can happen in the real
         // world if a managed profile is added and then removed).