[split system] Tentatively support running DO on meat user

- setDeviceOwner() now takes a user ID.  (We can infer it from Binder, but
we still need it for the dpm command.)

- Change broadcast target UID for DO to the DO user

- Start the DO user on boot complete.
TODO Investigate whether this is actually the good timing.

TODO Prevent the DO user from being killed

Bug 23827706

Change-Id: I227dbd444f1f4e94d98c317489d151554fe79d91
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
index 471fa3b..214dc5d 100644
--- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -51,7 +51,8 @@
         out.println(
                 "usage: dpm [subcommand] [options]\n" +
                 "usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" +
-                "usage: dpm set-device-owner <COMPONENT>\n" +
+                // STOPSHIP Finalize it
+                "usage: dpm set-device-owner [ --user <USER_ID> *EXPERIMENTAL* ] <COMPONENT>\n" +
                 "usage: dpm set-profile-owner [ --user <USER_ID> ] <COMPONENT>\n" +
                 "\n" +
                 "dpm set-active-admin: Sets the given component as active admin" +
@@ -106,22 +107,22 @@
     }
 
     private void runSetDeviceOwner() throws RemoteException {
-        ComponentName component = parseComponentName(nextArgRequired());
-        mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, UserHandle.USER_SYSTEM);
+        parseArgs(true);
+        mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);
 
-        String packageName = component.getPackageName();
+        String packageName = mComponent.getPackageName();
         try {
-            if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/)) {
+            if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/, mUserId)) {
                 throw new RuntimeException(
                         "Can't set package " + packageName + " as device owner.");
             }
         } catch (Exception e) {
             // Need to remove the admin that we just added.
-            mDevicePolicyManager.removeActiveAdmin(component, UserHandle.USER_SYSTEM);
+            mDevicePolicyManager.removeActiveAdmin(mComponent, UserHandle.USER_SYSTEM);
             throw e;
         }
         System.out.println("Success: Device owner set to package " + packageName);
-        System.out.println("Active admin set to component " + component.toShortString());
+        System.out.println("Active admin set to component " + mComponent.toShortString());
     }
 
     private void runSetProfileOwner() throws RemoteException {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 7ffac0a..ac50699 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2684,13 +2684,26 @@
      * @throws IllegalArgumentException if the package name is null or invalid
      * @throws IllegalStateException If the preconditions mentioned are not met.
      */
-    public boolean setDeviceOwner(String packageName) throws IllegalArgumentException,
-            IllegalStateException {
+    public boolean setDeviceOwner(String packageName) {
         return setDeviceOwner(packageName, null);
     }
 
     /**
      * @hide
+     */
+    public boolean setDeviceOwner(String packageName, int userId)  {
+        return setDeviceOwner(packageName, null, userId);
+    }
+
+    /**
+     * @hide
+     */
+    public boolean setDeviceOwner(String packageName, String ownerName) {
+        return setDeviceOwner(packageName, ownerName, UserHandle.USER_SYSTEM);
+    }
+
+    /**
+     * @hide
      * Sets the given package as the device owner. The package must already be installed. There
      * must not already be a device owner.
      * Only apps with the MANAGE_PROFILE_AND_DEVICE_OWNERS permission and the shell uid can call
@@ -2699,15 +2712,16 @@
      * the caller is the shell uid, and there are no additional users and no accounts.
      * @param packageName the package name of the application to be registered as the device owner.
      * @param ownerName the human readable name of the institution that owns this device.
+     * @param userId ID of the user on which the device owner runs.
      * @return whether the package was successfully registered as the device owner.
      * @throws IllegalArgumentException if the package name is null or invalid
      * @throws IllegalStateException If the preconditions mentioned are not met.
      */
-    public boolean setDeviceOwner(String packageName, String ownerName)
+    public boolean setDeviceOwner(String packageName, String ownerName, int userId)
             throws IllegalArgumentException, IllegalStateException {
         if (mService != null) {
             try {
-                return mService.setDeviceOwner(packageName, ownerName);
+                return mService.setDeviceOwner(packageName, ownerName, userId);
             } catch (RemoteException re) {
                 Log.w(TAG, "Failed to set device owner");
             }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 376a3d8..55a21c6 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -113,7 +113,7 @@
     void reportFailedPasswordAttempt(int userHandle);
     void reportSuccessfulPasswordAttempt(int userHandle);
 
-    boolean setDeviceOwner(String packageName, String ownerName);
+    boolean setDeviceOwner(String packageName, String ownerName, int userId);
     boolean isDeviceOwner(String packageName);
     String getDeviceOwner();
     String getDeviceOwnerName();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0202309..6d7343d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -303,9 +303,7 @@
 
         @Override
         public void onBootPhase(int phase) {
-            if (phase == PHASE_LOCK_SETTINGS_READY) {
-                mService.systemReady();
-            }
+            mService.systemReady(phase);
         }
     }
 
@@ -1776,10 +1774,21 @@
         }
     }
 
-    public void systemReady() {
+    public void systemReady(int phase) {
         if (!mHasFeature) {
             return;
         }
+        switch (phase) {
+            case SystemService.PHASE_LOCK_SETTINGS_READY:
+                onLockSettingsReady();
+                break;
+            case SystemService.PHASE_BOOT_COMPLETED:
+                ensureDeviceOwnerUserStarted(); // TODO Consider better place to do this.
+                break;
+        }
+    }
+
+    private void onLockSettingsReady() {
         getUserData(UserHandle.USER_OWNER);
         loadDeviceOwner();
         cleanUpOldUsers();
@@ -1798,6 +1807,26 @@
         }
     }
 
+    private void ensureDeviceOwnerUserStarted() {
+        if (mOwners.hasDeviceOwner()) {
+            final IActivityManager am = ActivityManagerNative.getDefault();
+            final int userId = mOwners.getDeviceOwnerUserId();
+            if (VERBOSE_LOG) {
+                Log.v(LOG_TAG, "Starting non-system DO user: " + userId);
+            }
+            if (userId != UserHandle.USER_SYSTEM) {
+                try {
+                    am.startUserInBackground(userId);
+
+                    // STOPSHIP Prevent the DO user from being killed.
+
+                } catch (RemoteException e) {
+                    Slog.w(LOG_TAG, "Exception starting user", e);
+                }
+            }
+        }
+    }
+
     private void cleanUpOldUsers() {
         // This is needed in case the broadcast {@link Intent.ACTION_USER_REMOVED} was not handled
         // before reboot
@@ -4110,17 +4139,17 @@
     }
 
     @Override
-    public boolean setDeviceOwner(String packageName, String ownerName) {
+    public boolean setDeviceOwner(String packageName, String ownerName, int userId) {
         if (!mHasFeature) {
             return false;
         }
         if (packageName == null
-                || !Owners.isInstalled(packageName, mContext.getPackageManager())) {
+                || !Owners.isInstalledForUser(packageName, userId)) {
             throw new IllegalArgumentException("Invalid package name " + packageName
                     + " for device owner");
         }
         synchronized (this) {
-            enforceCanSetDeviceOwner();
+            enforceCanSetDeviceOwner(userId);
 
             // Shutting down backup manager service permanently.
             long ident = Binder.clearCallingIdentity();
@@ -4134,14 +4163,15 @@
                 Binder.restoreCallingIdentity(ident);
             }
 
-            mOwners.setDeviceOwner(packageName, ownerName);
+            mOwners.setDeviceOwner(packageName, ownerName, userId);
             mOwners.writeDeviceOwner();
             updateDeviceOwnerLocked();
             Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED);
 
             ident = Binder.clearCallingIdentity();
             try {
-                mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
+                // TODO Send to system too?
+                mContext.sendBroadcastAsUser(intent, new UserHandle(userId));
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -4242,10 +4272,12 @@
         if (!mHasFeature) {
             return false;
         }
-        if (initializer == null || !Owners.isInstalled(
-                initializer.getPackageName(), mContext.getPackageManager())) {
+        if (initializer == null ||
+                !mOwners.hasDeviceOwner() ||
+                !Owners.isInstalledForUser(initializer.getPackageName(),
+                        mOwners.getDeviceOwnerUserId())) {
             throw new IllegalArgumentException("Invalid component name " + initializer
-                    + " for device initializer");
+                    + " for device initializer or no device owner set");
         }
         boolean isInitializerSystemApp;
         try {
@@ -4268,7 +4300,7 @@
 
             mOwners.setDeviceInitializer(initializer);
 
-            addDeviceInitializerToLockTaskPackagesLocked(UserHandle.USER_OWNER);
+            addDeviceInitializerToLockTaskPackagesLocked(mOwners.getDeviceOwnerUserId());
             mOwners.writeDeviceOwner();
             return true;
         }
@@ -4278,7 +4310,7 @@
         if (who == null) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
-            if (hasUserSetupCompleted(UserHandle.USER_OWNER)) {
+            if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
                 throw new IllegalStateException(
                         "Trying to set device initializer but device is already provisioned.");
             }
@@ -4648,31 +4680,46 @@
      * The device owner can only be set before the setup phase of the primary user has completed,
      * except for adb if no accounts or additional users are present on the device.
      */
-    private void enforceCanSetDeviceOwner() {
-        if (mOwners != null && mOwners.hasDeviceOwner()) {
+    private void enforceCanSetDeviceOwner(int userId) {
+        if (mOwners.hasDeviceOwner()) {
             throw new IllegalStateException("Trying to set the device owner, but device owner "
                     + "is already set.");
         }
+        // STOPSHIP Make sure the DO user is running
         int callingUid = Binder.getCallingUid();
         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) {
             if (!hasUserSetupCompleted(UserHandle.USER_OWNER)) {
                 return;
             }
-            if (mUserManager.getUserCount() > 1) {
-                throw new IllegalStateException("Not allowed to set the device owner because there "
-                        + "are already several users on the device");
-            }
-            if (AccountManager.get(mContext).getAccounts().length > 0) {
-                throw new IllegalStateException("Not allowed to set the device owner because there "
-                        + "are already some accounts on the device");
+            // STOPSHIP Do proper check in split user mode
+            if (!UserManager.isSplitSystemUser()) {
+                if (mUserManager.getUserCount() > 1) {
+                    throw new IllegalStateException(
+                            "Not allowed to set the device owner because there "
+                                    + "are already several users on the device");
+                }
+                if (AccountManager.get(mContext).getAccounts().length > 0) {
+                    throw new IllegalStateException(
+                            "Not allowed to set the device owner because there "
+                                    + "are already some accounts on the device");
+                }
             }
             return;
+        } else {
+            // STOPSHIP check the caller UID with userId
         }
+        if (mUserManager.isUserRunning(new UserHandle(userId))) {
+            throw new IllegalStateException("User not running: " + userId);
+        }
+
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null);
-        if (hasUserSetupCompleted(UserHandle.USER_OWNER)) {
-            throw new IllegalStateException("Cannot set the device owner if the device is "
-                    + "already set-up");
+        // STOPSHIP Do proper check in split user mode
+        if (!UserManager.isSplitSystemUser()) {
+            if (hasUserSetupCompleted(UserHandle.USER_OWNER)) {
+                throw new IllegalStateException("Cannot set the device owner if the device is "
+                        + "already set-up");
+            }
         }
     }
 
@@ -4689,12 +4736,6 @@
         }
     }
 
-    private void enforceSystemProcess(String message) {
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException(message);
-        }
-    }
-
     private void enforceNotManagedProfile(int userHandle, String message) {
         if(isManagedProfile(userHandle)) {
             throw new SecurityException("You can not " + message + " for a managed profile. ");
@@ -6318,7 +6359,7 @@
         }
         mContext.sendBroadcastAsUser(
                 new Intent(DevicePolicyManager.ACTION_SYSTEM_UPDATE_POLICY_CHANGED),
-                UserHandle.OWNER);
+                UserHandle.SYSTEM);
     }
 
     @Override
@@ -6355,7 +6396,7 @@
                 "Only the system update service can broadcast update information");
 
         if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
-            Slog.w(LOG_TAG, "Only the system update service in the primary user" +
+            Slog.w(LOG_TAG, "Only the system update service in the primary user " +
                     "can broadcast update information.");
             return;
         }
@@ -6368,6 +6409,7 @@
             if (deviceOwnerPackage == null) {
                 return;
             }
+            final UserHandle deviceOwnerUser = new UserHandle(mOwners.getDeviceOwnerUserId());
 
             ActivityInfo[] receivers = null;
             try {
@@ -6383,7 +6425,7 @@
                         if (permission.BIND_DEVICE_ADMIN.equals(receivers[i].permission)) {
                             intent.setComponent(new ComponentName(deviceOwnerPackage,
                                     receivers[i].name));
-                            mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
+                            mContext.sendBroadcastAsUser(intent, deviceOwnerUser);
                         }
                     }
                 } finally {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 1656716..87cf28f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -26,6 +26,7 @@
 import android.content.pm.UserInfo;
 import android.os.Environment;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
@@ -71,6 +72,8 @@
     private static final String TAG_DEVICE_OWNER = "device-owner";
     private static final String TAG_DEVICE_INITIALIZER = "device-initializer";
     private static final String TAG_PROFILE_OWNER = "profile-owner";
+    // Holds "context" for device-owner, this must not be show up before device-owner.
+    private static final String TAG_DEVICE_OWNER_CONTEXT = "device-owner-context";
 
     private static final String ATTR_NAME = "name";
     private static final String ATTR_PACKAGE = "package";
@@ -85,6 +88,8 @@
     // Internal state for the device owner package.
     private OwnerInfo mDeviceOwner;
 
+    private int mDeviceOwnerUserId = UserHandle.USER_NULL;
+
     // Internal state for the device initializer package.
     private OwnerInfo mDeviceInitializer;
 
@@ -140,16 +145,26 @@
         return mDeviceOwner != null ? mDeviceOwner.packageName : null;
     }
 
+    int getDeviceOwnerUserId() {
+        return mDeviceOwnerUserId;
+    }
+
     String getDeviceOwnerName() {
         return mDeviceOwner != null ? mDeviceOwner.name : null;
     }
 
-    void setDeviceOwner(String packageName, String ownerName) {
+    void setDeviceOwner(String packageName, String ownerName, int userId) {
+        if (userId < 0) {
+            Slog.e(TAG, "Invalid user id for device owner user: " + userId);
+            return;
+        }
         mDeviceOwner = new OwnerInfo(ownerName, packageName);
+        mDeviceOwnerUserId = userId;
     }
 
     void clearDeviceOwner() {
         mDeviceOwner = null;
+        mDeviceOwnerUserId = UserHandle.USER_NULL;
     }
 
     ComponentName getDeviceInitializerComponent() {
@@ -215,20 +230,6 @@
         return mDeviceOwner != null;
     }
 
-    static boolean isInstalled(String packageName, PackageManager pm) {
-        try {
-            PackageInfo pi;
-            if ((pi = pm.getPackageInfo(packageName, 0)) != null) {
-                if ((pi.applicationInfo.flags) != 0) {
-                    return true;
-                }
-            }
-        } catch (NameNotFoundException nnfe) {
-            Slog.w(TAG, "Device Owner package " + packageName + " not installed.");
-        }
-        return false;
-    }
-
     static boolean isInstalledForUser(String packageName, int userHandle) {
         try {
             PackageInfo pi = (AppGlobals.getPackageManager())
@@ -263,6 +264,7 @@
                     String name = parser.getAttributeValue(null, ATTR_NAME);
                     String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
                     mDeviceOwner = new OwnerInfo(name, packageName);
+                    mDeviceOwnerUserId = UserHandle.USER_SYSTEM;
                 } else if (tag.equals(TAG_DEVICE_INITIALIZER)) {
                     String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
                     String initializerComponentStr =
@@ -464,7 +466,11 @@
         void writeInner(XmlSerializer out) throws IOException {
             if (mDeviceOwner != null) {
                 mDeviceOwner.writeToXml(out, TAG_DEVICE_OWNER);
+                out.startTag(null, TAG_DEVICE_OWNER_CONTEXT);
+                out.attribute(null, ATTR_USERID, String.valueOf(mDeviceOwnerUserId));
+                out.endTag(null, TAG_DEVICE_OWNER_CONTEXT);
             }
+
             if (mDeviceInitializer != null) {
                 mDeviceInitializer.writeToXml(out, TAG_DEVICE_INITIALIZER);
             }
@@ -483,7 +489,18 @@
             switch (tag) {
                 case TAG_DEVICE_OWNER:
                     mDeviceOwner = OwnerInfo.readFromXml(parser);
+                    mDeviceOwnerUserId = UserHandle.USER_SYSTEM; // Set default
                     break;
+                case TAG_DEVICE_OWNER_CONTEXT: {
+                    final String userIdString =
+                            parser.getAttributeValue(null, ATTR_USERID);
+                    try {
+                        mDeviceOwnerUserId = Integer.parseInt(userIdString);
+                    } catch (NumberFormatException e) {
+                        Slog.e(TAG, "Error parsing user-id " + userIdString);
+                    }
+                    break;
+                }
                 case TAG_DEVICE_INITIALIZER:
                     mDeviceInitializer = OwnerInfo.readFromXml(parser);
                     break;
@@ -594,7 +611,6 @@
             pw.println(prefix + "admin=" + admin);
             pw.println(prefix + "name=" + name);
             pw.println(prefix + "package=" + packageName);
-            pw.println();
         }
     }
 
@@ -602,6 +618,17 @@
         if (mDeviceOwner != null) {
             pw.println(prefix + "Device Owner: ");
             mDeviceOwner.dump(prefix + "  ", pw);
+            pw.println(prefix + "  User ID: " + mDeviceOwnerUserId);
+            pw.println();
+        }
+        if (mDeviceInitializer != null) {
+            pw.println(prefix + "Device Initializer: ");
+            mDeviceInitializer.dump(prefix + "  ", pw);
+            pw.println();
+        }
+        if (mSystemUpdatePolicy != null) {
+            pw.println(prefix + "System Update Policy: " + mSystemUpdatePolicy);
+            pw.println();
         }
         if (mProfileOwners != null) {
             for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
index a284ca0..3b88fb1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.pm.UserInfo;
 import android.os.FileUtils;
+import android.os.UserHandle;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
@@ -37,11 +38,13 @@
 /**
  * Tests for the DeviceOwner object that saves & loads device and policy owner information.
  * run this test with:
- mmma frameworks/base/services/tests/servicestests/ &&
+ m FrameworksServicesTests &&
  adb install \
    -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
  adb shell am instrument -e class com.android.server.devicepolicy.OwnersTest \
    -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+
+ (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
  */
 public class OwnersTest extends DpmTestBase {
     private static final String TAG = "DeviceOwnerTest";
@@ -147,6 +150,12 @@
             assertFalse(owners.getProfileOwnerFileWithTestOverride(11).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(20).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(21).exists());
+
+            assertFalse(owners.hasDeviceOwner());
+            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
+            assertFalse(owners.hasDeviceInitializer());
+            assertNull(owners.getSystemUpdatePolicy());
+            assertEquals(0, owners.getProfileOwnerKeys().size());
         }
 
         // Then re-read and check.
@@ -155,6 +164,7 @@
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
+            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
             assertFalse(owners.hasDeviceInitializer());
             assertNull(owners.getSystemUpdatePolicy());
             assertEquals(0, owners.getProfileOwnerKeys().size());
@@ -181,6 +191,15 @@
             assertFalse(owners.getProfileOwnerFileWithTestOverride(11).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(20).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(21).exists());
+
+            assertTrue(owners.hasDeviceOwner());
+            assertEquals(null, owners.getDeviceOwnerName());
+            assertEquals("com.google.android.testdpc", owners.getDeviceOwnerPackageName());
+            assertEquals(UserHandle.USER_SYSTEM, owners.getDeviceOwnerUserId());
+
+            assertFalse(owners.hasDeviceInitializer());
+            assertNull(owners.getSystemUpdatePolicy());
+            assertEquals(0, owners.getProfileOwnerKeys().size());
         }
 
         // Then re-read and check.
@@ -191,6 +210,7 @@
             assertTrue(owners.hasDeviceOwner());
             assertEquals(null, owners.getDeviceOwnerName());
             assertEquals("com.google.android.testdpc", owners.getDeviceOwnerPackageName());
+            assertEquals(UserHandle.USER_SYSTEM, owners.getDeviceOwnerUserId());
 
             assertFalse(owners.hasDeviceInitializer());
             assertNull(owners.getSystemUpdatePolicy());
@@ -218,6 +238,23 @@
             assertTrue(owners.getProfileOwnerFileWithTestOverride(11).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(20).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(21).exists());
+
+            assertFalse(owners.hasDeviceOwner());
+            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
+            assertFalse(owners.hasDeviceInitializer());
+            assertNull(owners.getSystemUpdatePolicy());
+
+            assertEquals(2, owners.getProfileOwnerKeys().size());
+            assertEquals(new ComponentName("com.google.android.testdpc",
+                            "com.google.android.testdpc.DeviceAdminReceiver0"),
+                    owners.getProfileOwnerComponent(10));
+            assertEquals("0", owners.getProfileOwnerName(10));
+            assertEquals("com.google.android.testdpc", owners.getProfileOwnerPackage(10));
+
+            assertEquals(new ComponentName("com.google.android.testdpc1", ""),
+                    owners.getProfileOwnerComponent(11));
+            assertEquals("1", owners.getProfileOwnerName(11));
+            assertEquals("com.google.android.testdpc1", owners.getProfileOwnerPackage(11));
         }
 
         // Then re-read and check.
@@ -226,6 +263,7 @@
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
+            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
             assertFalse(owners.hasDeviceInitializer());
             assertNull(owners.getSystemUpdatePolicy());
 
@@ -263,6 +301,28 @@
             assertTrue(owners.getProfileOwnerFileWithTestOverride(11).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(20).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(21).exists());
+
+            assertTrue(owners.hasDeviceOwner());
+            assertEquals(null, owners.getDeviceOwnerName());
+            assertEquals("com.google.android.testdpc", owners.getDeviceOwnerPackageName());
+            assertEquals(UserHandle.USER_SYSTEM, owners.getDeviceOwnerUserId());
+
+            assertTrue(owners.hasDeviceInitializer());
+            assertEquals("com.google.android.testdpcx", owners.getDeviceInitializerPackageName());
+            assertNotNull(owners.getSystemUpdatePolicy());
+            assertEquals(5, owners.getSystemUpdatePolicy().getPolicyType());
+
+            assertEquals(2, owners.getProfileOwnerKeys().size());
+            assertEquals(new ComponentName("com.google.android.testdpc",
+                            "com.google.android.testdpc.DeviceAdminReceiver0"),
+                    owners.getProfileOwnerComponent(10));
+            assertEquals("0", owners.getProfileOwnerName(10));
+            assertEquals("com.google.android.testdpc", owners.getProfileOwnerPackage(10));
+
+            assertEquals(new ComponentName("com.google.android.testdpc1", ""),
+                    owners.getProfileOwnerComponent(11));
+            assertEquals("1", owners.getProfileOwnerName(11));
+            assertEquals("com.google.android.testdpc1", owners.getProfileOwnerPackage(11));
         }
 
         // Then re-read and check.
@@ -273,6 +333,7 @@
             assertTrue(owners.hasDeviceOwner());
             assertEquals(null, owners.getDeviceOwnerName());
             assertEquals("com.google.android.testdpc", owners.getDeviceOwnerPackageName());
+            assertEquals(UserHandle.USER_SYSTEM, owners.getDeviceOwnerUserId());
 
             assertTrue(owners.hasDeviceInitializer());
             assertEquals("com.google.android.testdpcx", owners.getDeviceInitializerPackageName());
@@ -312,6 +373,15 @@
             assertFalse(owners.getProfileOwnerFileWithTestOverride(10).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(11).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(20).exists());
+
+            assertFalse(owners.hasDeviceOwner());
+            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
+
+            assertTrue(owners.hasDeviceInitializer());
+            assertEquals("com.google.android.testdpcx", owners.getDeviceInitializerPackageName());
+
+            assertNull(owners.getSystemUpdatePolicy());
+            assertEquals(0, owners.getProfileOwnerKeys().size());
         }
 
         // Then re-read and check.
@@ -320,6 +390,7 @@
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
+            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
 
             assertTrue(owners.hasDeviceInitializer());
             assertEquals("com.google.android.testdpcx", owners.getDeviceInitializerPackageName());
@@ -348,6 +419,14 @@
             assertFalse(owners.getProfileOwnerFileWithTestOverride(10).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(11).exists());
             assertFalse(owners.getProfileOwnerFileWithTestOverride(20).exists());
+
+            assertFalse(owners.hasDeviceOwner());
+            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
+            assertFalse(owners.hasDeviceInitializer());
+            assertEquals(0, owners.getProfileOwnerKeys().size());
+
+            assertNotNull(owners.getSystemUpdatePolicy());
+            assertEquals(5, owners.getSystemUpdatePolicy().getPolicyType());
         }
 
         // Then re-read and check.
@@ -356,6 +435,7 @@
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
+            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
             assertFalse(owners.hasDeviceInitializer());
             assertEquals(0, owners.getProfileOwnerKeys().size());