Use a factory class for dependency injection, add more tests.

- Extracting into a factory allows us to use mocks in other classes.
(Such as Owners.)

- Also removed broken test ApplicationRestrictionsTest.  Instead added a new
simplified test to DevicePolicyManagerTest.

- Also stop caching rarely used instances in DPMS.

Bug 24061108
Bug 24275172

Change-Id: Ice9e57204b18e7b5f6b115126dab2209041439c2
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/ApplicationRestrictionsTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/ApplicationRestrictionsTest.java
deleted file mode 100644
index ca270e7..0000000
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/ApplicationRestrictionsTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.devicepolicy;
-
-import android.app.admin.DeviceAdminReceiver;
-import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
-/**
- * Tests for application restrictions persisting via profile owner:
- *   make -j FrameworksServicesTests
- *   runtest --path frameworks/base/services/tests/servicestests/ \
- *       src/com/android/server/devicepolicy/ApplicationRestrictionsTest.java
- */
-public class ApplicationRestrictionsTest extends AndroidTestCase {
-
-    static DevicePolicyManager sDpm;
-    static ComponentName sAdminReceiver;
-    private static final String RESTRICTED_APP = "com.example.restrictedApp";
-    static boolean sAddBack = false;
-
-    public static class AdminReceiver extends DeviceAdminReceiver {
-
-        @Override
-        public void onDisabled(Context context, Intent intent) {
-            if (sAddBack) {
-                sDpm.setActiveAdmin(sAdminReceiver, false);
-                sAddBack = false;
-            }
-
-            super.onDisabled(context, intent);
-        }
-    }
-
-    @Override
-    public void setUp() {
-        final Context context = getContext();
-        sAdminReceiver = new ComponentName(mContext.getPackageName(),
-                AdminReceiver.class.getName());
-        sDpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        Settings.Secure.putInt(context.getContentResolver(),
-                Settings.Secure.USER_SETUP_COMPLETE, 0);
-        sDpm.setProfileOwner(sAdminReceiver, "Test", UserHandle.myUserId());
-        Settings.Secure.putInt(context.getContentResolver(),
-                Settings.Secure.USER_SETUP_COMPLETE, 1);
-        // Remove the admin if already registered. It's async, so add it back
-        // when the admin gets a broadcast. Otherwise add it back right away.
-        if (sDpm.isAdminActive(sAdminReceiver)) {
-            sAddBack = true;
-            sDpm.removeActiveAdmin(sAdminReceiver);
-        } else {
-            sDpm.setActiveAdmin(sAdminReceiver, false);
-        }
-    }
-
-    @Override
-    public void tearDown() {
-        Settings.Secure.putInt(getContext().getContentResolver(),
-                Settings.Secure.USER_SETUP_COMPLETE, 0);
-        sDpm.removeActiveAdmin(sAdminReceiver);
-        Settings.Secure.putInt(getContext().getContentResolver(),
-                Settings.Secure.USER_SETUP_COMPLETE, 1);
-    }
-
-    public void testSettingRestrictions() {
-        Bundle restrictions = new Bundle();
-        restrictions.putString("KEY_STRING", "Foo");
-        assertNotNull(sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP));
-        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, restrictions);
-        Bundle returned = sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP);
-        assertNotNull(returned);
-        assertEquals(returned.size(), 1);
-        assertEquals(returned.get("KEY_STRING"), "Foo");
-        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, new Bundle());
-        returned = sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP);
-        assertEquals(returned.size(), 0);
-    }
-
-    public void testRestrictionTypes() {
-        Bundle restrictions = new Bundle();
-        restrictions.putString("KEY_STRING", "Foo");
-        restrictions.putInt("KEY_INT", 7);
-        restrictions.putBoolean("KEY_BOOLEAN", true);
-        restrictions.putBoolean("KEY_BOOLEAN_2", false);
-        restrictions.putString("KEY_STRING_2", "Bar");
-        restrictions.putStringArray("KEY_STR_ARRAY", new String[] { "Foo", "Bar" });
-        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, restrictions);
-        Bundle returned = sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP);
-        assertTrue(returned.getBoolean("KEY_BOOLEAN"));
-        assertFalse(returned.getBoolean("KEY_BOOLEAN_2"));
-        assertFalse(returned.getBoolean("KEY_BOOLEAN_3"));
-        assertEquals(returned.getInt("KEY_INT"), 7);
-        assertTrue(returned.get("KEY_BOOLEAN") instanceof Boolean);
-        assertTrue(returned.get("KEY_INT") instanceof Integer);
-        assertEquals(returned.get("KEY_STRING"), "Foo");
-        assertEquals(returned.get("KEY_STRING_2"), "Bar");
-        assertTrue(returned.getStringArray("KEY_STR_ARRAY") instanceof String[]);
-        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, new Bundle());
-    }
-
-    public void testTextEscaping() {
-        String fancyText = "<This contains XML/> <JSON> "
-                + "{ \"One\": { \"OneOne\": \"11\", \"OneTwo\": \"12\" }, \"Two\": \"2\" } <JSON/>";
-        Bundle restrictions = new Bundle();
-        restrictions.putString("KEY_FANCY_TEXT", fancyText);
-        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, restrictions);
-        Bundle returned = sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP);
-        assertEquals(returned.getString("KEY_FANCY_TEXT"), fancyText);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index 7e730f6..c6c7497 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -19,11 +19,11 @@
 
 import android.app.IActivityManager;
 import android.app.NotificationManager;
+import android.app.backup.IBackupManager;
 import android.content.Context;
 import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
+import android.media.IAudioService;
 import android.os.Looper;
-import android.os.PowerManager.WakeLock;
 import android.os.PowerManagerInternal;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -73,146 +73,169 @@
         }
     }
 
-    public final File dataDir;
-    public final File systemUserDataDir;
-    public final File secondUserDataDir;
+    public final DpmMockContext context;
 
     public DevicePolicyManagerServiceTestable(DpmMockContext context, File dataDir) {
-        super(context);
-        this.dataDir = dataDir;
-
-        systemUserDataDir = new File(dataDir, "user0");
-        DpmTestUtils.clearDir(dataDir);
-
-        secondUserDataDir = new File(dataDir, "user" + DpmMockContext.CALLER_USER_HANDLE);
-        DpmTestUtils.clearDir(secondUserDataDir);
-
-        when(getContext().environment.getUserSystemDirectory(
-                eq(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(secondUserDataDir);
+        this(new MockInjector(context, dataDir));
     }
 
-    @Override
-    DpmMockContext getContext() {
-        return (DpmMockContext) super.getContext();
+    private DevicePolicyManagerServiceTestable(MockInjector injector) {
+        super(injector);
+        this.context = injector.context;
     }
 
-    @Override
-    Owners newOwners() {
-        return new OwnersTestable(getContext(), dataDir);
-    }
+    private static class MockInjector extends Injector {
 
-    @Override
-    UserManager getUserManager() {
-        return getContext().userManager;
-    }
+        public final DpmMockContext context;
 
-    @Override
-    PackageManager getPackageManager() {
-        return getContext().packageManager;
-    }
+        public final File dataDir;
 
-    @Override
-    PowerManagerInternal getPowerManagerInternal() {
-        return getContext().powerManagerInternal;
-    }
+        public final File systemUserDataDir;
+        public final File secondUserDataDir;
 
-    @Override
-    NotificationManager getNotificationManager() {
-        return getContext().notificationManager;
-    }
+        private MockInjector(DpmMockContext context, File dataDir) {
+            super(context);
+            this.context = context;
+            this.dataDir = dataDir;
 
-    @Override
-    IWindowManager getIWindowManager() {
-        return getContext().iwindowManager;
-    }
+            systemUserDataDir = new File(dataDir, "user0");
+            DpmTestUtils.clearDir(dataDir);
 
-    @Override
-    IActivityManager getIActivityManager() {
-        return getContext().iactivityManager;
-    }
+            secondUserDataDir = new File(dataDir, "user" + DpmMockContext.CALLER_USER_HANDLE);
+            DpmTestUtils.clearDir(secondUserDataDir);
 
-    @Override
-    IPackageManager getIPackageManager() {
-        return getContext().ipackageManager;
-    }
+            when(context.environment.getUserSystemDirectory(
+                    eq(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(secondUserDataDir);
+        }
 
-    @Override
-    LockPatternUtils newLockPatternUtils(Context context) {
-        return getContext().lockPatternUtils;
-    }
+        @Override
+        Owners newOwners() {
+            return new OwnersTestable(context, dataDir);
+        }
 
-    @Override
-    Looper getMyLooper() {
-        return Looper.getMainLooper();
-    }
+        @Override
+        UserManager getUserManager() {
+            return context.userManager;
+        }
 
-    @Override
-    String getDevicePolicyFilePathForSystemUser() {
-        return systemUserDataDir.getAbsolutePath();
-    }
+        @Override
+        PowerManagerInternal getPowerManagerInternal() {
+            return context.powerManagerInternal;
+        }
 
-    @Override
-    long binderClearCallingIdentity() {
-        return getContext().binder.clearCallingIdentity();
-    }
+        @Override
+        NotificationManager getNotificationManager() {
+            return context.notificationManager;
+        }
 
-    @Override
-    void binderRestoreCallingIdentity(long token) {
-        getContext().binder.restoreCallingIdentity(token);
-    }
+        @Override
+        IWindowManager getIWindowManager() {
+            return context.iwindowManager;
+        }
 
-    @Override
-    int binderGetCallingUid() {
-        return getContext().binder.getCallingUid();
-    }
+        @Override
+        IActivityManager getIActivityManager() {
+            return context.iactivityManager;
+        }
 
-    @Override
-    int binderGetCallingPid() {
-        return getContext().binder.getCallingPid();
-    }
+        @Override
+        IPackageManager getIPackageManager() {
+            return context.ipackageManager;
+        }
 
-    @Override
-    UserHandle binderGetCallingUserHandle() {
-        return getContext().binder.getCallingUserHandle();
-    }
+        @Override
+        IBackupManager getIBackupManager() {
+            return context.ibackupManager;
+        }
 
-    @Override
-    boolean binderIsCallingUidMyUid() {
-        return getContext().binder.isCallerUidMyUid();
-    }
+        @Override
+        IAudioService getIAudioService() {
+            return context.iaudioService;
+        }
 
-    @Override
-    File environmentGetUserSystemDirectory(int userId) {
-        return getContext().environment.getUserSystemDirectory(userId);
-    }
+        @Override
+        Looper getMyLooper() {
+            return Looper.getMainLooper();
+        }
 
-    @Override
-    void powerManagerGoToSleep(long time, int reason, int flags) {
-        getContext().powerManager.goToSleep(time, reason, flags);
-    }
+        @Override
+        LockPatternUtils newLockPatternUtils() {
+            return context.lockPatternUtils;
+        }
 
-    @Override
-    boolean systemPropertiesGetBoolean(String key, boolean def) {
-        return getContext().systemProperties.getBoolean(key, def);
-    }
+        @Override
+        String getDevicePolicyFilePathForSystemUser() {
+            return systemUserDataDir.getAbsolutePath();
+        }
 
-    @Override
-    long systemPropertiesGetLong(String key, long def) {
-        return getContext().systemProperties.getLong(key, def);
-    }
+        @Override
+        long binderClearCallingIdentity() {
+            return context.binder.clearCallingIdentity();
+        }
 
-    @Override
-    String systemPropertiesGet(String key, String def) {
-        return getContext().systemProperties.get(key, def);
-    }
+        @Override
+        void binderRestoreCallingIdentity(long token) {
+            context.binder.restoreCallingIdentity(token);
+        }
 
-    @Override
-    String systemPropertiesGet(String key) {
-        return getContext().systemProperties.get(key);
-    }
+        @Override
+        int binderGetCallingUid() {
+            return context.binder.getCallingUid();
+        }
 
-    @Override
-    void systemPropertiesSet(String key, String value) {
-        getContext().systemProperties.set(key, value);
+        @Override
+        int binderGetCallingPid() {
+            return context.binder.getCallingPid();
+        }
+
+        @Override
+        UserHandle binderGetCallingUserHandle() {
+            return context.binder.getCallingUserHandle();
+        }
+
+        @Override
+        boolean binderIsCallingUidMyUid() {
+            return context.binder.isCallerUidMyUid();
+        }
+
+        @Override
+        File environmentGetUserSystemDirectory(int userId) {
+            return context.environment.getUserSystemDirectory(userId);
+        }
+
+        @Override
+        void powerManagerGoToSleep(long time, int reason, int flags) {
+            context.powerManager.goToSleep(time, reason, flags);
+        }
+
+        @Override
+        boolean systemPropertiesGetBoolean(String key, boolean def) {
+            return context.systemProperties.getBoolean(key, def);
+        }
+
+        @Override
+        long systemPropertiesGetLong(String key, long def) {
+            return context.systemProperties.getLong(key, def);
+        }
+
+        @Override
+        String systemPropertiesGet(String key, String def) {
+            return context.systemProperties.get(key, def);
+        }
+
+        @Override
+        String systemPropertiesGet(String key) {
+            return context.systemProperties.get(key);
+        }
+
+        @Override
+        void systemPropertiesSet(String key, String value) {
+            context.systemProperties.set(key, value);
+        }
+
+        @Override
+        boolean userManagerIsSplitSystemUser() {
+            return context.userManagerForMock.isSplitSystemUser();
+        }
     }
 }
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 0da459d..0072f52 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -30,15 +30,24 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
+import android.content.pm.PackageInfo;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.util.Pair;
 
 import org.mockito.ArgumentCaptor;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -87,6 +96,8 @@
         setUpPackageManagerForAdmin(admin3);
 
         setUpApplicationInfo(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
+        setUpPackageInfo();
+        setUpUserManager();
     }
 
     /**
@@ -132,7 +143,85 @@
                 eq(DpmMockContext.CALLER_USER_HANDLE));
     }
 
-    public void testHasNoFeature() {
+    /**
+     * Set up a mock result for {@link IPackageManager#getPackageInfo(String, int, int)} for user
+     * {@link DpmMockContext#CALLER_USER_HANDLE} as well as the system user.
+     */
+    private void setUpPackageInfo() throws Exception {
+        final PackageInfo pi = mRealTestContext.getPackageManager().getPackageInfo(
+                admin1.getPackageName(), 0);
+        assertTrue(pi.applicationInfo.flags != 0);
+
+        doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
+                eq(admin1.getPackageName()),
+                eq(0),
+                eq(DpmMockContext.CALLER_USER_HANDLE));
+        doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
+                eq(admin1.getPackageName()),
+                eq(0),
+                eq(UserHandle.USER_SYSTEM));
+    }
+
+    private void setUpUserManager() {
+        // Emulate UserManager.set/getApplicationRestriction().
+        final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>();
+
+        // UM.setApplicationRestrictions() will save to appRestrictions.
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                String pkg = (String) invocation.getArguments()[0];
+                Bundle bundle = (Bundle) invocation.getArguments()[1];
+                UserHandle user = (UserHandle) invocation.getArguments()[2];
+
+                appRestrictions.put(Pair.create(pkg, user), bundle);
+
+                return null;
+            }
+        }).when(mContext.userManager).setApplicationRestrictions(
+                anyString(), any(Bundle.class), any(UserHandle.class));
+
+        // UM.getApplicationRestrictions() will read from appRestrictions.
+        doAnswer(new Answer<Bundle>() {
+            @Override
+            public Bundle answer(InvocationOnMock invocation) throws Throwable {
+                String pkg = (String) invocation.getArguments()[0];
+                UserHandle user = (UserHandle) invocation.getArguments()[1];
+
+                return appRestrictions.get(Pair.create(pkg, user));
+            }
+        }).when(mContext.userManager).getApplicationRestrictions(
+                anyString(), any(UserHandle.class));
+
+        // System user is always running.
+        when(mContext.userManager.isUserRunning(MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)))
+                .thenReturn(true);
+
+        // Set up (default) UserInfo for CALLER_USER_HANDLE.
+        final UserInfo uh = new UserInfo(DpmMockContext.CALLER_USER_HANDLE,
+                "user" + DpmMockContext.CALLER_USER_HANDLE, 0);
+
+        when(mContext.userManager.getUserInfo(eq(DpmMockContext.CALLER_USER_HANDLE)))
+                .thenReturn(uh);
+    }
+
+    private void setAsProfileOwner(ComponentName admin) {
+        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        final UserInfo uh = new UserInfo(DpmMockContext.CALLER_USER_HANDLE, "user", 0);
+
+        // DO needs to be an DA.
+        dpm.setActiveAdmin(admin, /* replace =*/ false);
+
+        // Fire!
+        assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
+
+        // Check
+        assertEquals(admin1, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
+    }
+
+    public void testHasNoFeature() throws Exception {
         when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                 .thenReturn(false);
 
@@ -399,6 +488,105 @@
 
         // TODO Check other internal calls.
     }
+
+    /**
+     * Test for: {@link DevicePolicyManager#setDeviceOwner} DO on system user installs
+     * successfully.
+     */
+    public void testSetDeviceOwner() throws Exception {
+        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
+
+        // Call from a process on the system user.
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+
+        // DO needs to be an DA.
+        dpm.setActiveAdmin(admin1, /* replace =*/ false);
+
+        // Fire!
+        assertTrue(dpm.setDeviceOwner(admin1.getPackageName(), "owner-name"));
+
+        // Verify internal calls.
+        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
+                eq(admin1.getPackageName()));
+
+        // TODO We should check if the caller has called clearCallerIdentity().
+        verify(mContext.ibackupManager, times(1)).setBackupServiceActive(
+                eq(UserHandle.USER_SYSTEM), eq(false));
+
+        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
+                MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
+                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
+
+        assertEquals(admin1.getPackageName(), dpm.getDeviceOwner());
+
+        // TODO Test getDeviceOwnerName() too.  To do so, we need to change
+        // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
+    }
+
+    /**
+     * Test for: {@link DevicePolicyManager#setDeviceOwner} Package doesn't exist.
+     */
+    public void testSetDeviceOwner_noSuchPackage() {
+        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
+
+        // Call from a process on the system user.
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+
+        // DO needs to be an DA.
+        dpm.setActiveAdmin(admin1, /* replace =*/ false);
+        try {
+            dpm.setDeviceOwner("a.b.c");
+            fail("Didn't throw IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testSetDeviceOwner_failures() throws Exception {
+        // TODO Test more failure cases.  Basically test all chacks in enforceCanSetDeviceOwner().
+    }
+
+    public void testSetProfileOwner() throws Exception {
+        setAsProfileOwner(admin1);
+    }
+
+    public void testSetProfileOwner_failures() throws Exception {
+        // TODO Test more failure cases.  Basically test all chacks in enforceCanSetProfileOwner().
+    }
+
+    public void testSetGetApplicationRestriction() {
+        setAsProfileOwner(admin1);
+
+        {
+            Bundle rest = new Bundle();
+            rest.putString("KEY_STRING", "Foo1");
+            dpm.setApplicationRestrictions(admin1, "pkg1", rest);
+        }
+
+        {
+            Bundle rest = new Bundle();
+            rest.putString("KEY_STRING", "Foo2");
+            dpm.setApplicationRestrictions(admin1, "pkg2", rest);
+        }
+
+        {
+            Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg1");
+            assertNotNull(returned);
+            assertEquals(returned.size(), 1);
+            assertEquals(returned.get("KEY_STRING"), "Foo1");
+        }
+
+        {
+            Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg2");
+            assertNotNull(returned);
+            assertEquals(returned.size(), 1);
+            assertEquals(returned.get("KEY_STRING"), "Foo2");
+        }
+
+        dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle());
+        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg2").size());
+    }
 }
-
-
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 6bb9833..f3d9160 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -16,27 +16,29 @@
 
 package com.android.server.devicepolicy;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.LockPatternUtils;
 
 import android.app.IActivityManager;
 import android.app.NotificationManager;
+import android.app.backup.IBackupManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.media.IAudioService;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.PowerManager.WakeLock;
 import android.os.PowerManagerInternal;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.test.mock.MockContext;
 import android.view.IWindowManager;
 
+import org.junit.Assert;
+
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
@@ -54,11 +56,16 @@
     public static final int CALLER_USER_HANDLE = 20;
 
     /**
-     * UID of the caller.
+     * UID corresponding to {@link #CALLER_USER_HANDLE}.
      */
     public static final int CALLER_UID = UserHandle.PER_USER_RANGE * CALLER_USER_HANDLE + 123;
 
     /**
+     * UID used when a caller is on the system user.
+     */
+    public static final int CALLER_SYSTEM_USER_UID = 123;
+
+    /**
      * PID of the caller.
      */
     public static final int CALLER_PID = 22222;
@@ -142,6 +149,12 @@
         }
     }
 
+    public static class UserManagerForMock {
+        public boolean isSplitSystemUser() {
+            return false;
+        }
+    }
+
     public final Context realTestContext;
 
     /**
@@ -155,12 +168,15 @@
     public final EnvironmentForMock environment;
     public final SystemPropertiesForMock systemProperties;
     public final UserManager userManager;
+    public final UserManagerForMock userManagerForMock;
     public final PowerManagerForMock powerManager;
     public final PowerManagerInternal powerManagerInternal;
     public final NotificationManager notificationManager;
     public final IWindowManager iwindowManager;
     public final IActivityManager iactivityManager;
     public final IPackageManager ipackageManager;
+    public final IBackupManager ibackupManager;
+    public final IAudioService iaudioService;
     public final LockPatternUtils lockPatternUtils;
 
     /** Note this is a partial mock, not a real mock. */
@@ -174,12 +190,15 @@
         environment = mock(EnvironmentForMock.class);
         systemProperties= mock(SystemPropertiesForMock.class);
         userManager = mock(UserManager.class);
+        userManagerForMock = mock(UserManagerForMock.class);
         powerManager = mock(PowerManagerForMock.class);
         powerManagerInternal = mock(PowerManagerInternal.class);
         notificationManager = mock(NotificationManager.class);
         iwindowManager = mock(IWindowManager.class);
         iactivityManager = mock(IActivityManager.class);
         ipackageManager = mock(IPackageManager.class);
+        ibackupManager = mock(IBackupManager.class);
+        iaudioService = mock(IAudioService.class);
         lockPatternUtils = mock(LockPatternUtils.class);
 
         // Package manager is huge, so we use a partial mock instead.
@@ -272,6 +291,13 @@
 
     @Override
     public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+        if (binder.callingPid != SYSTEM_PID) {
+            // Unless called as the system process, can only call if the target user is the
+            // calling user.
+            // (The actual check is more complex; we may need to change it later.)
+            Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier());
+        }
+
         spiedContext.sendBroadcastAsUser(intent, user);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
index 77270c8..6f9f6ab 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
@@ -21,7 +21,7 @@
 
 import java.io.File;
 
-public class DpmTestBase extends AndroidTestCase {
+public abstract class DpmTestBase extends AndroidTestCase {
     public static final String TAG = "DpmTest";
 
     protected Context mRealTestContext;
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java
index 5cd1555..08293a2 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java
@@ -24,4 +24,4 @@
     }
     public static class Admin3 extends DeviceAdminReceiver {
     }
-}
\ No newline at end of file
+}