Make DPM/DPMS unit-testable

- Now all services that DPMS uses are injectable.
- Introduce some wrappers to make static methods and final class mockable.
(e.g. for Binder.getCallingUid())

- In unit tests we replace those with Mockito mocks, except we use a partial
mock for PackageManager, because we use way too many methods of this and
most of them are okay to use directly.

- To install a partial mock to PackageManager, I needed to make
ApplicationPackageManager @hide public non-final.

- For a starter, added tests for DPM.setAmin().

Bug 24061108

Change-Id: I2afd51d8bc0038992d5f9be38c686260be775b75
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0cd02dd..5544a71 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -93,8 +93,8 @@
 import java.util.Map;
 import java.util.Objects;
 
-/*package*/
-final class ApplicationPackageManager extends PackageManager {
+/** @hide */
+public class ApplicationPackageManager extends PackageManager {
     private static final String TAG = "ApplicationPackageManager";
     private final static boolean DEBUG_ICONS = false;
 
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 3d264c6..288a2cb 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -240,7 +240,7 @@
                 new CachedServiceFetcher<DevicePolicyManager>() {
             @Override
             public DevicePolicyManager createService(ContextImpl ctx) {
-                return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
+                return DevicePolicyManager.create(ctx);
             }});
 
         registerService(Context.DOWNLOAD_SERVICE, DownloadManager.class,
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ac50699..e6484e9 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -32,7 +32,6 @@
 import android.graphics.Bitmap;
 import android.net.ProxyInfo;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteCallback;
@@ -45,6 +44,7 @@
 import android.service.restrictions.RestrictionsReceiver;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.org.conscrypt.TrustedCertificateStore;
 
 import org.xmlpull.v1.XmlPullParserException;
@@ -87,18 +87,30 @@
     private final Context mContext;
     private final IDevicePolicyManager mService;
 
-    private DevicePolicyManager(Context context, Handler handler) {
-        mContext = context;
-        mService = IDevicePolicyManager.Stub.asInterface(
-                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
+    private DevicePolicyManager(Context context) {
+        this(context, IDevicePolicyManager.Stub.asInterface(
+                        ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)));
     }
 
     /** @hide */
-    public static DevicePolicyManager create(Context context, Handler handler) {
-        DevicePolicyManager me = new DevicePolicyManager(context, handler);
+    @VisibleForTesting
+    protected DevicePolicyManager(Context context, IDevicePolicyManager service) {
+        mContext = context;
+        mService = service;
+    }
+
+    /** @hide */
+    public static DevicePolicyManager create(Context context) {
+        DevicePolicyManager me = new DevicePolicyManager(context);
         return me.mService != null ? me : null;
     }
 
+    /** @hide test will override it. */
+    @VisibleForTesting
+    protected int myUserId() {
+        return UserHandle.myUserId();
+    }
+
     /**
      * Activity action: Starts the provisioning flow which sets up a managed profile.
      *
@@ -823,7 +835,7 @@
      * active (enabled) in the system.
      */
     public boolean isAdminActive(@NonNull ComponentName admin) {
-        return isAdminActiveAsUser(admin, UserHandle.myUserId());
+        return isAdminActiveAsUser(admin, myUserId());
     }
 
     /**
@@ -863,7 +875,7 @@
      * returned.
      */
     public List<ComponentName> getActiveAdmins() {
-        return getActiveAdminsAsUser(UserHandle.myUserId());
+        return getActiveAdminsAsUser(myUserId());
     }
 
     /**
@@ -889,7 +901,7 @@
     public boolean packageHasActiveAdmins(String packageName) {
         if (mService != null) {
             try {
-                return mService.packageHasActiveAdmins(packageName, UserHandle.myUserId());
+                return mService.packageHasActiveAdmins(packageName, myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -906,7 +918,7 @@
     public void removeActiveAdmin(@NonNull ComponentName admin) {
         if (mService != null) {
             try {
-                mService.removeActiveAdmin(admin, UserHandle.myUserId());
+                mService.removeActiveAdmin(admin, myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -925,7 +937,7 @@
     public boolean hasGrantedPolicy(@NonNull ComponentName admin, int usesPolicy) {
         if (mService != null) {
             try {
-                return mService.hasGrantedPolicy(admin, usesPolicy, UserHandle.myUserId());
+                return mService.hasGrantedPolicy(admin, usesPolicy, myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1040,7 +1052,7 @@
      * all admins.
      */
     public int getPasswordQuality(@Nullable ComponentName admin) {
-        return getPasswordQuality(admin, UserHandle.myUserId());
+        return getPasswordQuality(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1093,7 +1105,7 @@
      * all admins.
      */
     public int getPasswordMinimumLength(@Nullable ComponentName admin) {
-        return getPasswordMinimumLength(admin, UserHandle.myUserId());
+        return getPasswordMinimumLength(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1154,7 +1166,7 @@
      *         password.
      */
     public int getPasswordMinimumUpperCase(@Nullable ComponentName admin) {
-        return getPasswordMinimumUpperCase(admin, UserHandle.myUserId());
+        return getPasswordMinimumUpperCase(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1215,7 +1227,7 @@
      *         password.
      */
     public int getPasswordMinimumLowerCase(@Nullable ComponentName admin) {
-        return getPasswordMinimumLowerCase(admin, UserHandle.myUserId());
+        return getPasswordMinimumLowerCase(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1273,7 +1285,7 @@
      * @return The minimum number of letters required in the password.
      */
     public int getPasswordMinimumLetters(@Nullable ComponentName admin) {
-        return getPasswordMinimumLetters(admin, UserHandle.myUserId());
+        return getPasswordMinimumLetters(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1332,7 +1344,7 @@
      * @return The minimum number of numerical digits required in the password.
      */
     public int getPasswordMinimumNumeric(@Nullable ComponentName admin) {
-        return getPasswordMinimumNumeric(admin, UserHandle.myUserId());
+        return getPasswordMinimumNumeric(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1390,7 +1402,7 @@
      * @return The minimum number of symbols required in the password.
      */
     public int getPasswordMinimumSymbols(@Nullable ComponentName admin) {
-        return getPasswordMinimumSymbols(admin, UserHandle.myUserId());
+        return getPasswordMinimumSymbols(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1449,7 +1461,7 @@
      * @return The minimum number of letters required in the password.
      */
     public int getPasswordMinimumNonLetter(@Nullable ComponentName admin) {
-        return getPasswordMinimumNonLetter(admin, UserHandle.myUserId());
+        return getPasswordMinimumNonLetter(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1540,7 +1552,7 @@
     public long getPasswordExpirationTimeout(@Nullable ComponentName admin) {
         if (mService != null) {
             try {
-                return mService.getPasswordExpirationTimeout(admin, UserHandle.myUserId());
+                return mService.getPasswordExpirationTimeout(admin, myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1561,7 +1573,7 @@
     public long getPasswordExpiration(@Nullable ComponentName admin) {
         if (mService != null) {
             try {
-                return mService.getPasswordExpiration(admin, UserHandle.myUserId());
+                return mService.getPasswordExpiration(admin, myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1577,7 +1589,7 @@
      * @return The length of the password history
      */
     public int getPasswordHistoryLength(@Nullable ComponentName admin) {
-        return getPasswordHistoryLength(admin, UserHandle.myUserId());
+        return getPasswordHistoryLength(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1617,7 +1629,7 @@
     public boolean isActivePasswordSufficient() {
         if (mService != null) {
             try {
-                return mService.isActivePasswordSufficient(UserHandle.myUserId());
+                return mService.isActivePasswordSufficient(myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1636,7 +1648,7 @@
     public int getCurrentFailedPasswordAttempts() {
         if (mService != null) {
             try {
-                return mService.getCurrentFailedPasswordAttempts(UserHandle.myUserId());
+                return mService.getCurrentFailedPasswordAttempts(myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1698,7 +1710,7 @@
      * all admins.
      */
     public int getMaximumFailedPasswordsForWipe(@Nullable ComponentName admin) {
-        return getMaximumFailedPasswordsForWipe(admin, UserHandle.myUserId());
+        return getMaximumFailedPasswordsForWipe(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1818,7 +1830,7 @@
      * all admins if admin is null. Returns 0 if there are no restrictions.
      */
     public long getMaximumTimeToLock(@Nullable ComponentName admin) {
-        return getMaximumTimeToLock(admin, UserHandle.myUserId());
+        return getMaximumTimeToLock(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -1881,7 +1893,7 @@
     public void wipeData(int flags) {
         if (mService != null) {
             try {
-                mService.wipeData(flags, UserHandle.myUserId());
+                mService.wipeData(flags, myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1995,7 +2007,7 @@
     public ComponentName getGlobalProxyAdmin() {
         if (mService != null) {
             try {
-                return mService.getGlobalProxyAdmin(UserHandle.myUserId());
+                return mService.getGlobalProxyAdmin(myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -2145,7 +2157,7 @@
     public boolean getStorageEncryption(@Nullable ComponentName admin) {
         if (mService != null) {
             try {
-                return mService.getStorageEncryption(admin, UserHandle.myUserId());
+                return mService.getStorageEncryption(admin, myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -2173,7 +2185,7 @@
      * or {@link #ENCRYPTION_STATUS_ACTIVE}.
      */
     public int getStorageEncryptionStatus() {
-        return getStorageEncryptionStatus(UserHandle.myUserId());
+        return getStorageEncryptionStatus(myUserId());
     }
 
     /** @hide per-user version */
@@ -2410,7 +2422,7 @@
      * have disabled the camera
      */
     public boolean getCameraDisabled(@Nullable ComponentName admin) {
-        return getCameraDisabled(admin, UserHandle.myUserId());
+        return getCameraDisabled(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -2457,7 +2469,7 @@
      * have disabled screen capture.
      */
     public boolean getScreenCaptureDisabled(@Nullable ComponentName admin) {
-        return getScreenCaptureDisabled(admin, UserHandle.myUserId());
+        return getScreenCaptureDisabled(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -2557,7 +2569,7 @@
      * for a list.
      */
     public int getKeyguardDisabledFeatures(@Nullable ComponentName admin) {
-        return getKeyguardDisabledFeatures(admin, UserHandle.myUserId());
+        return getKeyguardDisabledFeatures(admin, myUserId());
     }
 
     /** @hide per-user version */
@@ -2590,7 +2602,7 @@
      * @hide
      */
     public void setActiveAdmin(@NonNull ComponentName policyReceiver, boolean refreshing) {
-        setActiveAdmin(policyReceiver, refreshing, UserHandle.myUserId());
+        setActiveAdmin(policyReceiver, refreshing, myUserId());
     }
 
     /**
@@ -2627,7 +2639,7 @@
     public void getRemoveWarning(@Nullable ComponentName admin, RemoteCallback result) {
         if (mService != null) {
             try {
-                mService.getRemoveWarning(admin, result, UserHandle.myUserId());
+                mService.getRemoveWarning(admin, result, myUserId());
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -2956,7 +2968,7 @@
             throws IllegalArgumentException {
         if (mService != null) {
             try {
-                final int myUserId = UserHandle.myUserId();
+                final int myUserId = myUserId();
                 mService.setActiveAdmin(admin, false, myUserId);
                 return mService.setProfileOwner(admin, ownerName, myUserId);
             } catch (RemoteException re) {
@@ -3301,7 +3313,7 @@
      */
     public List<PersistableBundle> getTrustAgentConfiguration(@Nullable ComponentName admin,
             @NonNull ComponentName agent) {
-        return getTrustAgentConfiguration(admin, agent, UserHandle.myUserId());
+        return getTrustAgentConfiguration(admin, agent, myUserId());
     }
 
     /** @hide per-user version */
@@ -3927,7 +3939,7 @@
      * @see #setAccountManagementDisabled
      */
     public String[] getAccountTypesWithManagementDisabled() {
-        return getAccountTypesWithManagementDisabledAsUser(UserHandle.myUserId());
+        return getAccountTypesWithManagementDisabledAsUser(myUserId());
     }
 
     /**
diff --git a/core/java/com/android/server/LocalServices.java b/core/java/com/android/server/LocalServices.java
index 25dcb30..9c632ea 100644
--- a/core/java/com/android/server/LocalServices.java
+++ b/core/java/com/android/server/LocalServices.java
@@ -16,6 +16,8 @@
 
 package com.android.server;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import android.util.ArrayMap;
 
 /**
@@ -57,4 +59,14 @@
             sLocalServiceObjects.put(type, service);
         }
     }
+
+    /**
+     * Remove a service instance, must be only used in tests.
+     */
+    @VisibleForTesting
+    public static <T> void removeServiceForTest(Class<T> type) {
+        synchronized (sLocalServiceObjects) {
+            sLocalServiceObjects.remove(type);
+        }
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 67e5703..e11e317 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -73,8 +73,10 @@
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.PersistableBundle;
 import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
 import android.os.PowerManagerInternal;
 import android.os.Process;
 import android.os.RecoverySystem;
@@ -111,6 +113,7 @@
 import android.view.inputmethod.InputMethodManager;
 
 import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.JournaledFile;
@@ -266,16 +269,16 @@
             | DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
 
     final Context mContext;
+    final PackageManager mPackageManager;
     final UserManager mUserManager;
     final PowerManager.WakeLock mWakeLock;
 
     final LocalService mLocalService;
 
-    final PowerManager mPowerManager;
     final PowerManagerInternal mPowerManagerInternal;
 
-    IWindowManager mIWindowManager;
-    NotificationManager mNotificationManager;
+    final IWindowManager mIWindowManager;
+    final NotificationManager mNotificationManager;
 
     // Stores and loads state on device and profile owners.
     private final Owners mOwners;
@@ -346,7 +349,7 @@
 
     final SparseArray<DevicePolicyData> mUserData = new SparseArray<>();
 
-    Handler mHandler = new Handler();
+    final Handler mHandler;
 
     BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
@@ -1036,18 +1039,119 @@
         }
     }
 
+    /** Unit test will override it to inject a mock. */
+    @VisibleForTesting
+    Owners newOwners() {
+        return new Owners(mContext);
+    }
+
+    /** Unit test will override it to inject a mock. */
+    @VisibleForTesting
+    UserManager getUserManager() {
+        return UserManager.get(mContext);
+    }
+
+    /** Unit test will override it to inject a mock. */
+    @VisibleForTesting
+    PackageManager getPackageManager() {
+        return mContext.getPackageManager();
+    }
+
+    /** Unit test will override it to inject a mock. */
+    @VisibleForTesting
+    NotificationManager getNotificationManager() {
+        return mContext.getSystemService(NotificationManager.class);
+    }
+
+    /** Unit test will override it to inject a mock. */
+    @VisibleForTesting
+    PowerManagerInternal getPowerManagerInternal() {
+        return LocalServices.getService(PowerManagerInternal.class);
+    }
+
+    /** Unit test will override it to inject a mock. */
+    @VisibleForTesting
+    IWindowManager newIWindowManager() {
+        return IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
+    }
+
+    /** Unit test will override it to inject a mock. */
+    @VisibleForTesting
+    IActivityManager getIActivityManager() {
+        return ActivityManagerNative.getDefault();
+    }
+
+    /** Unit test will override it to inject a mock. */
+    @VisibleForTesting
+    LockPatternUtils newLockPatternUtils(Context context) {
+        return new LockPatternUtils(context);
+    }
+
+    /** Unit test will override it to inject. */
+    @VisibleForTesting
+    Looper getMyLooper() {
+        return Looper.myLooper();
+    }
+
+    @VisibleForTesting
+    long binderClearCallingIdentity() {
+        return Binder.clearCallingIdentity();
+    }
+
+    @VisibleForTesting
+    void binderRestoreCallingIdentity(long token) {
+        Binder.restoreCallingIdentity(token);
+    }
+
+    @VisibleForTesting
+    int binderGetCallingUid() {
+        return Binder.getCallingUid();
+    }
+
+    @VisibleForTesting
+    int binderGetCallingPid() {
+        return Binder.getCallingPid();
+    }
+
+    @VisibleForTesting
+    UserHandle binderGetCallingUserHandle() {
+        return Binder.getCallingUserHandle();
+    }
+
+    @VisibleForTesting
+    boolean binderIsCallingUidMyUid() {
+        return getCallingUid() == Process.myUid();
+    }
+
+    @VisibleForTesting
+    File environmentGetUserSystemDirectory(int userId) {
+        return Environment.getUserSystemDirectory(userId);
+    }
+
+    @VisibleForTesting
+    WakeLock powerManagerNewWakeLock(int levelAndFlags, String tag) {
+        return mContext.getSystemService(PowerManager.class).newWakeLock(levelAndFlags, tag);
+    }
+
+    @VisibleForTesting
+    void powerManagerGoToSleep(long time, int reason, int flags) {
+        mContext.getSystemService(PowerManager.class).goToSleep(time, reason, flags);
+    }
+
     /**
      * Instantiates the service.
      */
     public DevicePolicyManagerService(Context context) {
         mContext = context;
-        mOwners = new Owners(mContext);
-        mUserManager = UserManager.get(mContext);
-        mHasFeature = context.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_DEVICE_ADMIN);
-        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
-        mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM");
+        mHandler = new Handler(getMyLooper());
+        mOwners = newOwners();
+        mUserManager = getUserManager();
+        mPackageManager = getPackageManager();
+        mHasFeature = mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
+        mPowerManagerInternal = getPowerManagerInternal();
+        mWakeLock = powerManagerNewWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM");
+        mIWindowManager = newIWindowManager();
+        mNotificationManager = getNotificationManager();
         mLocalService = new LocalService();
         if (!mHasFeature) {
             // Skip the rest of the initialization
@@ -1076,6 +1180,15 @@
     }
 
     /**
+     * We need it for testing to allow accessing context from the test-only subclass while this
+     * class's constructor is still running.
+     */
+    @VisibleForTesting
+    Context getContext() {
+        return mContext;
+    }
+
+    /**
      * Creates and loads the policy data from xml.
      * @param userHandle the user for whom to load the policy data
      * @return
@@ -1103,11 +1216,11 @@
      * @return
      */
     DevicePolicyData getUserDataUnchecked(int userHandle) {
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             return getUserData(userHandle);
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -1124,7 +1237,7 @@
             if (policy != null) {
                 mUserData.remove(userHandle);
             }
-            File policyFile = new File(Environment.getUserSystemDirectory(userHandle),
+            File policyFile = new File(environmentGetUserSystemDirectory(userHandle),
                     DEVICE_POLICIES_XML);
             policyFile.delete();
             Slog.i(LOG_TAG, "Removed device policy file " + policyFile.getAbsolutePath());
@@ -1164,7 +1277,7 @@
             alarmTime = now + alarmInterval;
         }
 
-        long token = Binder.clearCallingIdentity();
+        long token = binderClearCallingIdentity();
         try {
             AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
             PendingIntent pi = PendingIntent.getBroadcastAsUser(context, REQUEST_EXPIRE_PASSWORD,
@@ -1176,26 +1289,10 @@
                 am.set(AlarmManager.RTC, alarmTime, pi);
             }
         } finally {
-            Binder.restoreCallingIdentity(token);
+            binderRestoreCallingIdentity(token);
         }
     }
 
-    private IWindowManager getWindowManager() {
-        if (mIWindowManager == null) {
-            IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
-            mIWindowManager = IWindowManager.Stub.asInterface(b);
-        }
-        return mIWindowManager;
-    }
-
-    private NotificationManager getNotificationManager() {
-        if (mNotificationManager == null) {
-            mNotificationManager =
-                    (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
-        }
-        return mNotificationManager;
-    }
-
     ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) {
         ActiveAdmin admin = getUserData(userHandle).mAdminMap.get(who);
         if (admin != null
@@ -1208,7 +1305,7 @@
 
     ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy)
             throws SecurityException {
-        final int callingUid = Binder.getCallingUid();
+        final int callingUid = binderGetCallingUid();
 
         ActiveAdmin result = getActiveAdminWithPolicyForUidLocked(who, reqPolicy, callingUid);
         if (result != null) {
@@ -1232,7 +1329,7 @@
                     + admin.info.getTagForPolicy(reqPolicy));
         } else {
             throw new SecurityException("No active admin owned by uid "
-                    + Binder.getCallingUid() + " for policy #" + reqPolicy);
+                    + binderGetCallingUid() + " for policy #" + reqPolicy);
         }
     }
 
@@ -1248,7 +1345,7 @@
             }
             if (admin.getUid() != uid) {
                 throw new SecurityException("Admin " + who + " is not owned by uid "
-                        + Binder.getCallingUid());
+                        + binderGetCallingUid());
             }
             if (isActiveAdminWithPolicyForUserLocked(admin, reqPolicy, userId)) {
                 return admin;
@@ -1410,14 +1507,19 @@
         }
     }
 
-    private static JournaledFile makeJournaledFile(int userHandle) {
-        final String base = userHandle == 0
-                ? "/data/system/" + DEVICE_POLICIES_XML
-                : new File(Environment.getUserSystemDirectory(userHandle), DEVICE_POLICIES_XML)
+    private JournaledFile makeJournaledFile(int userHandle) {
+        final String base = userHandle == UserHandle.USER_SYSTEM
+                ? getDevicePolicyFilePathForSystemUser() + DEVICE_POLICIES_XML
+                : new File(environmentGetUserSystemDirectory(userHandle), DEVICE_POLICIES_XML)
                         .getAbsolutePath();
         return new JournaledFile(new File(base), new File(base + ".tmp"));
     }
 
+    @VisibleForTesting
+    String getDevicePolicyFilePathForSystemUser() {
+        return "/data/system/";
+    }
+
     private void saveSettingsLocked(int userHandle) {
         DevicePolicyData policy = getUserData(userHandle);
         JournaledFile journal = makeJournaledFile(userHandle);
@@ -1513,6 +1615,7 @@
             journal.commit();
             sendChangedNotification(userHandle);
         } catch (IOException e) {
+            Slog.w(LOG_TAG, "failed writing file", e);
             try {
                 if (stream != null) {
                     stream.close();
@@ -1527,11 +1630,11 @@
     private void sendChangedNotification(int userHandle) {
         Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
         intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             mContext.sendBroadcastAsUser(intent, new UserHandle(userHandle));
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -1663,9 +1766,9 @@
         // sufficiently what is currently set.  Note that this is only
         // a sanity check in case the two get out of sync; this should
         // never normally happen.
-        final long identity = Binder.clearCallingIdentity();
+        final long identity = binderClearCallingIdentity();
         try {
-            LockPatternUtils utils = new LockPatternUtils(mContext);
+            LockPatternUtils utils = newLockPatternUtils(mContext);
             if (utils.getActivePasswordQuality(userHandle) < policy.mActivePasswordQuality) {
                 Slog.w(LOG_TAG, "Active password quality 0x"
                         + Integer.toHexString(policy.mActivePasswordQuality)
@@ -1681,7 +1784,7 @@
                 policy.mActivePasswordNonLetter = 0;
             }
         } finally {
-            Binder.restoreCallingIdentity(identity);
+            binderRestoreCallingIdentity(identity);
         }
 
         validatePasswordOwnerLocked(policy);
@@ -1695,26 +1798,26 @@
     }
 
     private void updateLockTaskPackagesLocked(List<String> packages, int userId) {
-        IActivityManager am = ActivityManagerNative.getDefault();
-        long ident = Binder.clearCallingIdentity();
+        IActivityManager am = getIActivityManager();
+        long ident = binderClearCallingIdentity();
         try {
             am.updateLockTaskPackages(userId, packages.toArray(new String[packages.size()]));
         } catch (RemoteException e) {
             // Not gonna happen.
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
     private void updateDeviceOwnerLocked() {
-        IActivityManager am = ActivityManagerNative.getDefault();
-        long ident = Binder.clearCallingIdentity();
+        IActivityManager am = getIActivityManager();
+        long ident = binderClearCallingIdentity();
         try {
             am.updateDeviceOwner(getDeviceOwner());
         } catch (RemoteException e) {
             // Not gonna happen.
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -1762,14 +1865,14 @@
         boolean systemState = SystemProperties.getBoolean(cameraPropertyForUser, false);
         boolean cameraDisabled = getCameraDisabled(null, policy.mUserHandle);
         if (cameraDisabled != systemState) {
-            long token = Binder.clearCallingIdentity();
+            long token = binderClearCallingIdentity();
             try {
                 String value = cameraDisabled ? "1" : "0";
                 if (DBG) Slog.v(LOG_TAG, "Change in camera state ["
                         + cameraPropertyForUser + "] = " + value);
                 SystemProperties.set(cameraPropertyForUser, value);
             } finally {
-                Binder.restoreCallingIdentity(token);
+                binderRestoreCallingIdentity(token);
             }
         }
     }
@@ -1809,7 +1912,7 @@
 
     private void ensureDeviceOwnerUserStarted() {
         if (mOwners.hasDeviceOwner()) {
-            final IActivityManager am = ActivityManagerNative.getDefault();
+            final IActivityManager am = getIActivityManager();
             final int userId = mOwners.getDeviceOwnerUserId();
             if (VERBOSE_LOG) {
                 Log.v(LOG_TAG, "Starting non-system DO user: " + userId);
@@ -1917,7 +2020,7 @@
                 Log.e(LOG_TAG, "Could not connect to KeyChain service", e);
             }
             if (!hasCert) {
-                getNotificationManager().cancelAsUser(
+                mNotificationManager.cancelAsUser(
                         null, MONITORING_CERT_NOTIFICATION_ID, userHandle);
                 return;
             }
@@ -1962,7 +2065,7 @@
                         com.android.internal.R.color.system_notification_accent_color))
                 .build();
 
-            getNotificationManager().notifyAsUser(
+            mNotificationManager.notifyAsUser(
                     null, MONITORING_CERT_NOTIFICATION_ID, noti, userHandle);
         }
     }
@@ -1991,7 +2094,7 @@
             throw new IllegalArgumentException("Bad admin: " + adminReceiver);
         }
         synchronized (this) {
-            long ident = Binder.clearCallingIdentity();
+            long ident = binderClearCallingIdentity();
             try {
                 if (!refreshing
                         && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) {
@@ -2018,7 +2121,7 @@
                 sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED,
                         onEnableData, null);
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
         }
     }
@@ -2112,7 +2215,7 @@
             if (admin == null) {
                 return;
             }
-            if (admin.getUid() != Binder.getCallingUid()) {
+            if (admin.getUid() != binderGetCallingUid()) {
                 // Active device owners must remain active admins.
                 if (isDeviceOwner(adminReceiver.getPackageName())) {
                     return;
@@ -2120,11 +2223,11 @@
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
             }
-            long ident = Binder.clearCallingIdentity();
+            long ident = binderClearCallingIdentity();
             try {
                 removeActiveAdminLocked(adminReceiver, userHandle);
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
         }
     }
@@ -2394,7 +2497,7 @@
                     || activeAdmin.crossProfileWidgetProviders.isEmpty()) {
                 return null;
             }
-            if (Binder.getCallingUid() == Process.myUid()) {
+            if (binderIsCallingUidMyUid()) {
                 return new ArrayList<>(activeAdmin.crossProfileWidgetProviders);
             } else {
                 return activeAdmin.crossProfileWidgetProviders;
@@ -2959,7 +3062,7 @@
             }
         }
 
-        int callingUid = Binder.getCallingUid();
+        int callingUid = binderGetCallingUid();
         DevicePolicyData policy = getUserData(userHandle);
         if (policy.mPasswordOwner >= 0 && policy.mPasswordOwner != callingUid) {
             Slog.w(LOG_TAG, "resetPassword: already set by another uid and not entered by user");
@@ -2975,7 +3078,7 @@
 
         // Don't do this with the lock held, because it is going to call
         // back in to the service.
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             LockPatternUtils utils = new LockPatternUtils(mContext);
             if (!TextUtils.isEmpty(password)) {
@@ -2996,7 +3099,7 @@
                 }
             }
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
 
         return true;
@@ -3046,7 +3149,7 @@
             return;
         }
 
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             if (timeMs <= 0) {
                 timeMs = Integer.MAX_VALUE;
@@ -3060,7 +3163,7 @@
             policy.mLastMaximumTimeToLock = timeMs;
             mPowerManagerInternal.setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -3112,18 +3215,18 @@
     }
 
     private void lockNowUnchecked() {
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             // Power off the display
-            mPowerManager.goToSleep(SystemClock.uptimeMillis(),
+            powerManagerGoToSleep(SystemClock.uptimeMillis(),
                     PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
             // Ensure the device is locked
             new LockPatternUtils(mContext).requireStrongAuth(
                     STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW, UserHandle.USER_ALL);
-            getWindowManager().lockNow(null);
+            mIWindowManager.lockNow(null);
         } catch (RemoteException e) {
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -3146,7 +3249,7 @@
     }
 
     private boolean isCallerDelegatedCertInstaller() {
-        final int callingUid = Binder.getCallingUid();
+        final int callingUid = binderGetCallingUid();
         final int userHandle = UserHandle.getUserId(callingUid);
         synchronized (this) {
             final DevicePolicyData policy = getUserData(userHandle);
@@ -3181,7 +3284,7 @@
         }
 
         final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
-        final long id = Binder.clearCallingIdentity();
+        final long id = binderClearCallingIdentity();
         try {
             final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
             try {
@@ -3196,7 +3299,7 @@
             Log.w(LOG_TAG, "installCaCertsToKeyChain(): ", e1);
             Thread.currentThread().interrupt();
         } finally {
-            Binder.restoreCallingIdentity(id);
+            binderRestoreCallingIdentity(id);
         }
         return false;
     }
@@ -3212,7 +3315,7 @@
         enforceCanManageCaCerts(admin);
 
         final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
-        final long id = Binder.clearCallingIdentity();
+        final long id = binderClearCallingIdentity();
         try {
             final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
             try {
@@ -3228,7 +3331,7 @@
             Log.w(LOG_TAG, "CaCertUninstaller: ", ie);
             Thread.currentThread().interrupt();
         } finally {
-            Binder.restoreCallingIdentity(id);
+            binderRestoreCallingIdentity(id);
         }
     }
 
@@ -3244,7 +3347,7 @@
             }
         }
         final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
-        final long id = Binder.clearCallingIdentity();
+        final long id = binderClearCallingIdentity();
         try {
           final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
           try {
@@ -3259,7 +3362,7 @@
             Log.w(LOG_TAG, "Interrupted while installing certificate", e);
             Thread.currentThread().interrupt();
         } finally {
-            Binder.restoreCallingIdentity(id);
+            binderRestoreCallingIdentity(id);
         }
         return false;
     }
@@ -3268,11 +3371,11 @@
     public void choosePrivateKeyAlias(final int uid, final Uri uri, final String alias,
             final IBinder response) {
         // Caller UID needs to be trusted, so we restrict this method to SYSTEM_UID callers.
-        if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) {
+        if (UserHandle.getAppId(binderGetCallingUid()) != Process.SYSTEM_UID) {
             return;
         }
 
-        final UserHandle caller = Binder.getCallingUserHandle();
+        final UserHandle caller = binderGetCallingUserHandle();
         // If there is a profile owner, redirect to that; otherwise query the device owner.
         ComponentName aliasChooser = getProfileOwner(caller.getIdentifier());
         if (aliasChooser == null && caller.isOwner()) {
@@ -3293,7 +3396,7 @@
         intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_ALIAS, alias);
         intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE, response);
 
-        final long id = Binder.clearCallingIdentity();
+        final long id = binderClearCallingIdentity();
         try {
             mContext.sendOrderedBroadcastAsUser(intent, caller, null, new BroadcastReceiver() {
                 @Override
@@ -3303,7 +3406,7 @@
                 }
             }, null, Activity.RESULT_OK, null, null);
         } finally {
-            Binder.restoreCallingIdentity(id);
+            binderRestoreCallingIdentity(id);
         }
     }
 
@@ -3380,7 +3483,7 @@
                 source = admin.info.getPackageName();
             }
 
-            long ident = Binder.clearCallingIdentity();
+            long ident = binderClearCallingIdentity();
             try {
                 if ((flags & WIPE_RESET_PROTECTION_DATA) != 0) {
                     boolean ownsInitialization = isDeviceInitializer(admin.info.getPackageName())
@@ -3401,7 +3504,7 @@
                 wipeDeviceOrUserLocked(wipeExtRequested, userHandle,
                         "DevicePolicyManager.wipeData() from " + source);
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
         }
     }
@@ -3414,7 +3517,7 @@
                 @Override
                 public void run() {
                     try {
-                        IActivityManager am = ActivityManagerNative.getDefault();
+                        IActivityManager am = getIActivityManager();
                         if (am.getCurrentUser().id == userHandle) {
                             am.switchUser(UserHandle.USER_OWNER);
                         }
@@ -3442,11 +3545,11 @@
                 .setColor(mContext.getColor(R.color.system_notification_accent_color))
                 .setStyle(new Notification.BigTextStyle().bigText(contentText))
                 .build();
-        getNotificationManager().notify(PROFILE_WIPED_NOTIFICATION_ID, notification);
+        mNotificationManager.notify(PROFILE_WIPED_NOTIFICATION_ID, notification);
     }
 
     private void clearWipeProfileNotification() {
-        getNotificationManager().cancel(PROFILE_WIPED_NOTIFICATION_ID);
+        mNotificationManager.cancel(PROFILE_WIPED_NOTIFICATION_ID);
     }
 
     @Override
@@ -3506,7 +3609,7 @@
                     || p.mActivePasswordNumeric != numbers
                     || p.mActivePasswordSymbols != symbols
                     || p.mActivePasswordNonLetter != nonletter) {
-                long ident = Binder.clearCallingIdentity();
+                long ident = binderClearCallingIdentity();
                 try {
                     p.mActivePasswordQuality = quality;
                     p.mActivePasswordLength = length;
@@ -3524,7 +3627,7 @@
                             DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
                             DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
                 } finally {
-                    Binder.restoreCallingIdentity(ident);
+                    binderRestoreCallingIdentity(ident);
                 }
             }
         }
@@ -3560,7 +3663,7 @@
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.BIND_DEVICE_ADMIN, null);
 
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             boolean wipeData = false;
             int identifier = 0;
@@ -3591,7 +3694,7 @@
                         "reportFailedPasswordAttempt()");
             }
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -3604,7 +3707,7 @@
         synchronized (this) {
             DevicePolicyData policy = getUserData(userHandle);
             if (policy.mFailedPasswordAttempts != 0 || policy.mPasswordOwner >= 0) {
-                long ident = Binder.clearCallingIdentity();
+                long ident = binderClearCallingIdentity();
                 try {
                     policy.mFailedPasswordAttempts = 0;
                     policy.mPasswordOwner = -1;
@@ -3615,7 +3718,7 @@
                                 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
                     }
                 } finally {
-                    Binder.restoreCallingIdentity(ident);
+                    binderRestoreCallingIdentity(ident);
                 }
             }
         }
@@ -3666,11 +3769,11 @@
 
             // Reset the global proxy accordingly
             // Do this using system permissions, as apps cannot write to secure settings
-            long origId = Binder.clearCallingIdentity();
+            long origId = binderClearCallingIdentity();
             try {
                 resetGlobalProxyLocked(policy);
             } finally {
-                Binder.restoreCallingIdentity(origId);
+                binderRestoreCallingIdentity(origId);
             }
             return null;
         }
@@ -3705,13 +3808,13 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
         }
-        long token = Binder.clearCallingIdentity();
+        long token = binderClearCallingIdentity();
         try {
             ConnectivityManager connectivityManager = (ConnectivityManager)
                     mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
             connectivityManager.setGlobalProxy(proxyInfo);
         } finally {
-            Binder.restoreCallingIdentity(token);
+            binderRestoreCallingIdentity(token);
         }
     }
 
@@ -3875,13 +3978,13 @@
     private int getEncryptionStatus() {
         String status = SystemProperties.get("ro.crypto.state", "unsupported");
         if ("encrypted".equalsIgnoreCase(status)) {
-            final long token = Binder.clearCallingIdentity();
+            final long token = binderClearCallingIdentity();
             try {
                 return LockPatternUtils.isDeviceEncrypted()
                         ? DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE
                         : DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY;
             } finally {
-                Binder.restoreCallingIdentity(token);
+                binderRestoreCallingIdentity(token);
             }
         } else if ("unencrypted".equalsIgnoreCase(status)) {
             return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
@@ -3946,13 +4049,13 @@
     }
 
     private void updateScreenCaptureDisabledInWindowManager(int userHandle, boolean disabled) {
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
-            getWindowManager().setScreenCaptureDisabled(userHandle, disabled);
+            mIWindowManager.setScreenCaptureDisabled(userHandle, disabled);
         } catch (RemoteException e) {
             Log.w(LOG_TAG, "Unable to notify WindowManager.", e);
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -3977,12 +4080,12 @@
 
         // Turn AUTO_TIME on in settings if it is required
         if (required) {
-            long ident = Binder.clearCallingIdentity();
+            long ident = binderClearCallingIdentity();
             try {
                 Settings.Global.putInt(mContext.getContentResolver(),
                         Settings.Global.AUTO_TIME, 1 /* AUTO_TIME on */);
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
         }
     }
@@ -4091,7 +4194,7 @@
             return 0;
         }
         enforceCrossUserPermission(userHandle);
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             synchronized (this) {
                 if (who != null) {
@@ -4134,7 +4237,7 @@
                 return which;
             }
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -4152,7 +4255,7 @@
             enforceCanSetDeviceOwner(userId);
 
             // Shutting down backup manager service permanently.
-            long ident = Binder.clearCallingIdentity();
+            long ident = binderClearCallingIdentity();
             try {
                 IBackupManager ibm = IBackupManager.Stub.asInterface(
                         ServiceManager.getService(Context.BACKUP_SERVICE));
@@ -4160,7 +4263,7 @@
             } catch (RemoteException e) {
                 throw new IllegalStateException("Failed deactivating backup service.", e);
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
 
             mOwners.setDeviceOwner(packageName, ownerName, userId);
@@ -4168,12 +4271,12 @@
             updateDeviceOwnerLocked();
             Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED);
 
-            ident = Binder.clearCallingIdentity();
+            ident = binderClearCallingIdentity();
             try {
                 // TODO Send to system too?
                 mContext.sendBroadcastAsUser(intent, new UserHandle(userId));
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
             return true;
         }
@@ -4238,7 +4341,7 @@
         Preconditions.checkNotNull(packageName, "packageName is null");
         try {
             int uid = mContext.getPackageManager().getPackageUid(packageName, 0);
-            if (uid != Binder.getCallingUid()) {
+            if (uid != binderGetCallingUid()) {
                 throw new SecurityException("Invalid packageName");
             }
         } catch (NameNotFoundException e) {
@@ -4254,7 +4357,7 @@
             mOwners.writeDeviceOwner();
             updateDeviceOwnerLocked();
             // Reactivate backup service.
-            long ident = Binder.clearCallingIdentity();
+            long ident = binderClearCallingIdentity();
             try {
                 IBackupManager ibm = IBackupManager.Stub.asInterface(
                         ServiceManager.getService(Context.BACKUP_SERVICE));
@@ -4262,7 +4365,7 @@
             } catch (RemoteException e) {
                 throw new IllegalStateException("Failed reactivating backup service.", e);
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
         }
     }
@@ -4282,7 +4385,7 @@
         boolean isInitializerSystemApp;
         try {
             isInitializerSystemApp = isSystemApp(AppGlobals.getPackageManager(),
-                    initializer.getPackageName(), Binder.getCallingUserHandle().getIdentifier());
+                    initializer.getPackageName(), binderGetCallingUserHandle().getIdentifier());
         } catch (RemoteException | IllegalArgumentException e) {
             isInitializerSystemApp = false;
             Slog.e(LOG_TAG, "Fail to check if device initialzer is system app.", e);
@@ -4365,9 +4468,9 @@
 
         ActiveAdmin admin = getActiveAdminUncheckedLocked(who, UserHandle.getCallingUserId());
 
-        if (admin.getUid() != Binder.getCallingUid()) {
+        if (admin.getUid() != binderGetCallingUid()) {
             throw new SecurityException("Admin " + who + " is not owned by uid "
-                    + Binder.getCallingUid());
+                    + binderGetCallingUid());
         }
 
         if (!isDeviceInitializer(admin.info.getPackageName())
@@ -4376,12 +4479,12 @@
                     "clearDeviceInitializer can only be called by the device initializer/owner");
         }
         synchronized (this) {
-            long ident = Binder.clearCallingIdentity();
+            long ident = binderClearCallingIdentity();
             try {
                 mOwners.clearDeviceInitializer();
                 mOwners.writeDeviceOwner();
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
         }
     }
@@ -4409,7 +4512,7 @@
         if (!mHasFeature) {
             return;
         }
-        UserHandle callingUser = Binder.getCallingUserHandle();
+        UserHandle callingUser = binderGetCallingUserHandle();
         // Check if this is the profile owner who is calling
         getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
         synchronized (this) {
@@ -4429,7 +4532,7 @@
         policy.mStatusBarDisabled = false;
         saveSettingsLocked(userId);
 
-        final long ident = Binder.clearCallingIdentity();
+        final long ident = binderClearCallingIdentity();
         try {
             clearUserRestrictions(userHandle);
             AppGlobals.getPackageManager().updatePermissionFlagsForAllApps(
@@ -4437,7 +4540,7 @@
                     0  /* flagValues */, userHandle.getIdentifier());
         } catch (RemoteException re) {
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -4497,7 +4600,7 @@
                         "This method can only be called by device initializers");
             }
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 if (!isDeviceOwner(activeAdmin.info.getPackageName())) {
                     IPackageManager ipm = AppGlobals.getPackageManager();
@@ -4518,7 +4621,7 @@
                 Log.i(LOG_TAG, "Can't talk to package manager", e);
                 return false;
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
             return true;
         }
@@ -4536,7 +4639,7 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
             int userId = UserHandle.getCallingUserId();
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 mUserManager.setUserEnabled(userId);
                 UserInfo parent = mUserManager.getProfileParent(userId);
@@ -4546,7 +4649,7 @@
                         Intent.FLAG_RECEIVER_FOREGROUND);
                 mContext.sendBroadcastAsUser(intent, new UserHandle(parent.id));
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -4558,11 +4661,11 @@
         // Check if this is the profile owner (includes device owner).
         getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
-        long id = Binder.clearCallingIdentity();
+        long id = binderClearCallingIdentity();
         try {
             mUserManager.setUserName(userId, profileName);
         } finally {
-            restoreCallingIdentity(id);
+            binderRestoreCallingIdentity(id);
         }
     }
 
@@ -4612,7 +4715,7 @@
      * Canonical name for a given package.
      */
     private String getApplicationLabel(String packageName, int userHandle) {
-        long token = Binder.clearCallingIdentity();
+        long token = binderClearCallingIdentity();
         try {
             final Context userContext;
             try {
@@ -4630,7 +4733,7 @@
             }
             return result != null ? result.toString() : null;
         } finally {
-            Binder.restoreCallingIdentity(token);
+            binderRestoreCallingIdentity(token);
         }
     }
 
@@ -4656,7 +4759,7 @@
             throw new IllegalStateException("Trying to set the profile owner, but profile owner "
                     + "is already set.");
         }
-        int callingUid = Binder.getCallingUid();
+        int callingUid = binderGetCallingUid();
         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) {
             if (hasUserSetupCompleted(userHandle) &&
                     AccountManager.get(mContext).getAccountsAsUser(userHandle).length > 0) {
@@ -4689,7 +4792,7 @@
             throw new IllegalStateException("User not running: " + userId);
         }
 
-        int callingUid = Binder.getCallingUid();
+        int callingUid = binderGetCallingUid();
         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) {
             if (!hasUserSetupCompleted(UserHandle.USER_OWNER)) {
                 return;
@@ -4726,7 +4829,7 @@
         if (userHandle < 0) {
             throw new IllegalArgumentException("Invalid userId " + userHandle);
         }
-        final int callingUid = Binder.getCallingUid();
+        final int callingUid = binderGetCallingUid();
         if (userHandle == UserHandle.getUserId(callingUid)) return;
         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
             mContext.enforceCallingOrSelfPermission(
@@ -4742,20 +4845,20 @@
     }
 
     private UserInfo getProfileParent(int userHandle) {
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             return mUserManager.getProfileParent(userHandle);
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
     private boolean isManagedProfile(int userHandle) {
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             return mUserManager.getUserInfo(userHandle).isManagedProfile();
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -4781,8 +4884,8 @@
                 != PackageManager.PERMISSION_GRANTED) {
 
             pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
+                    + binderGetCallingPid()
+                    + ", uid=" + binderGetCallingUid());
             return;
         }
 
@@ -4824,13 +4927,13 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             IPackageManager pm = AppGlobals.getPackageManager();
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 pm.addPersistentPreferredActivity(filter, activity, userHandle);
             } catch (RemoteException re) {
                 // Shouldn't happen
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -4843,13 +4946,13 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             IPackageManager pm = AppGlobals.getPackageManager();
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 pm.clearPackagePersistentPreferredActivities(packageName, userHandle);
             } catch (RemoteException re) {
                 // Shouldn't happen
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -4861,11 +4964,11 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 mUserManager.setApplicationRestrictions(packageName, settings, userHandle);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -4963,7 +5066,7 @@
     @Override
     public ComponentName getRestrictionsProvider(int userHandle) {
         synchronized (this) {
-            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            if (binderGetCallingUid() != Process.SYSTEM_UID) {
                 throw new SecurityException("Only the system can query the permission provider");
             }
             DevicePolicyData userData = getUserData(userHandle);
@@ -4979,7 +5082,7 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             IPackageManager pm = AppGlobals.getPackageManager();
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 UserInfo parent = mUserManager.getProfileParent(callingUserId);
                 if (parent == null) {
@@ -4998,7 +5101,7 @@
             } catch (RemoteException re) {
                 // Shouldn't happen
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -5010,7 +5113,7 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
             IPackageManager pm = AppGlobals.getPackageManager();
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 UserInfo parent = mUserManager.getProfileParent(callingUserId);
                 if (parent == null) {
@@ -5027,7 +5130,7 @@
             } catch (RemoteException re) {
                 // Shouldn't happen
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -5039,7 +5142,7 @@
     private boolean checkPackagesInPermittedListOrSystem(List<String> enabledPackages,
             List<String> permittedList) {
         int userIdToCheck = UserHandle.getCallingUserId();
-        long id = Binder.clearCallingIdentity();
+        long id = binderClearCallingIdentity();
         try {
             // If we have an enabled packages list for a managed profile the packages
             // we should check are installed for the parent user.
@@ -5063,7 +5166,7 @@
                 }
             }
         } finally {
-            restoreCallingIdentity(id);
+            binderRestoreCallingIdentity(id);
         }
         return true;
     }
@@ -5088,7 +5191,7 @@
         if (packageList != null) {
             int userId = UserHandle.getCallingUserId();
             List<AccessibilityServiceInfo> enabledServices = null;
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 UserInfo user = mUserManager.getUserInfo(userId);
                 if (user.isManagedProfile()) {
@@ -5098,7 +5201,7 @@
                 enabledServices = accessibilityManager.getEnabledAccessibilityServiceList(
                         AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
 
             if (enabledServices != null) {
@@ -5169,7 +5272,7 @@
 
             // If we have a permitted list add all system accessibility services.
             if (result != null) {
-                long id = Binder.clearCallingIdentity();
+                long id = binderClearCallingIdentity();
                 try {
                     UserInfo user = mUserManager.getUserInfo(userId);
                     if (user.isManagedProfile()) {
@@ -5191,7 +5294,7 @@
                         }
                     }
                 } finally {
-                    restoreCallingIdentity(id);
+                    binderRestoreCallingIdentity(id);
                 }
             }
 
@@ -5201,12 +5304,12 @@
 
     private boolean checkCallerIsCurrentUserOrProfile() {
         int callingUserId = UserHandle.getCallingUserId();
-        long token = Binder.clearCallingIdentity();
+        long token = binderClearCallingIdentity();
         try {
             UserInfo currentUser;
             UserInfo callingUser = mUserManager.getUserInfo(callingUserId);
             try {
-                currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+                currentUser = getIActivityManager().getCurrentUser();
             } catch (RemoteException e) {
                 Slog.e(LOG_TAG, "Failed to talk to activity managed.", e);
                 return false;
@@ -5223,7 +5326,7 @@
                 return false;
             }
         } finally {
-            Binder.restoreCallingIdentity(token);
+            binderRestoreCallingIdentity(token);
         }
         return true;
     }
@@ -5289,7 +5392,7 @@
     public List getPermittedInputMethodsForCurrentUser() {
         UserInfo currentUser;
         try {
-            currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+            currentUser = getIActivityManager().getCurrentUser();
         } catch (RemoteException e) {
             Slog.e(LOG_TAG, "Failed to make remote calls to get current user", e);
             // Activity managed is dead, just allow all IMEs
@@ -5327,7 +5430,7 @@
                 InputMethodManager inputMethodManager = (InputMethodManager) mContext
                         .getSystemService(Context.INPUT_METHOD_SERVICE);
                 List<InputMethodInfo> imes = inputMethodManager.getInputMethodList();
-                long id = Binder.clearCallingIdentity();
+                long id = binderClearCallingIdentity();
                 try {
                     IPackageManager pm = AppGlobals.getPackageManager();
                     if (imes != null) {
@@ -5340,7 +5443,7 @@
                         }
                     }
                 } finally {
-                    restoreCallingIdentity(id);
+                    binderRestoreCallingIdentity(id);
                 }
             }
             return result;
@@ -5353,7 +5456,7 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 UserInfo userInfo = mUserManager.createUser(name, 0 /* flags */);
                 if (userInfo != null) {
@@ -5361,7 +5464,7 @@
                 }
                 return null;
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -5373,11 +5476,11 @@
         if (user == null) {
             return null;
         }
-        long id = Binder.clearCallingIdentity();
+        long id = binderClearCallingIdentity();
         try {
             String profileOwnerPkg = profileOwnerComponent.getPackageName();
             final IPackageManager ipm = AppGlobals.getPackageManager();
-            IActivityManager activityManager = ActivityManagerNative.getDefault();
+            IActivityManager activityManager = getIActivityManager();
 
             final int userHandle = user.getIdentifier();
             try {
@@ -5396,7 +5499,7 @@
             setProfileOwner(profileOwnerComponent, ownerName, userHandle);
             return user;
         } finally {
-            restoreCallingIdentity(id);
+            binderRestoreCallingIdentity(id);
         }
     }
 
@@ -5406,11 +5509,11 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 return mUserManager.removeUser(userHandle.getIdentifier());
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -5421,18 +5524,18 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 int userId = UserHandle.USER_OWNER;
                 if (userHandle != null) {
                     userId = userHandle.getIdentifier();
                 }
-                return ActivityManagerNative.getDefault().switchUser(userId);
+                return getIActivityManager().switchUser(userId);
             } catch (RemoteException e) {
                 Log.e(LOG_TAG, "Couldn't switch user", e);
                 return false;
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -5445,14 +5548,14 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 Bundle bundle = mUserManager.getApplicationRestrictions(packageName, userHandle);
                 // if no restrictions were saved, mUserManager.getApplicationRestrictions
                 // returns null, but DPM method should return an empty Bundle as per JavaDoc
                 return bundle != null ? bundle : Bundle.EMPTY;
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -5482,7 +5585,7 @@
                         ServiceManager.getService(Context.AUDIO_SERVICE));
             }
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 if (enabled && !alreadyRestricted) {
                     if (UserManager.DISALLOW_UNMUTE_MICROPHONE.equals(key)) {
@@ -5548,7 +5651,7 @@
             } catch (RemoteException re) {
                 Slog.e(LOG_TAG, "Failed to talk to AudioService.", re);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
             sendChangedNotification(userHandle);
         }
@@ -5562,7 +5665,7 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 IPackageManager pm = AppGlobals.getPackageManager();
                 return pm.setApplicationHiddenSettingAsUser(packageName, hidden, callingUserId);
@@ -5570,7 +5673,7 @@
                 // shouldn't happen
                 Slog.e(LOG_TAG, "Failed to setApplicationHiddenSetting", re);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
             return false;
         }
@@ -5583,7 +5686,7 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 IPackageManager pm = AppGlobals.getPackageManager();
                 return pm.getApplicationHiddenSettingAsUser(packageName, callingUserId);
@@ -5591,7 +5694,7 @@
                 // shouldn't happen
                 Slog.e(LOG_TAG, "Failed to getApplicationHiddenSettingAsUser", re);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
             return false;
         }
@@ -5606,7 +5709,7 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             int userId = UserHandle.getCallingUserId();
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
 
             try {
                 if (DBG) {
@@ -5634,7 +5737,7 @@
                 // shouldn't happen
                 Slog.wtf(LOG_TAG, "Failed to install " + packageName, re);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -5648,7 +5751,7 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             int userId = UserHandle.getCallingUserId();
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
 
             try {
                 UserManager um = UserManager.get(mContext);
@@ -5687,7 +5790,7 @@
                 Slog.wtf(LOG_TAG, "Failed to resolve intent for: " + intent);
                 return 0;
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -5753,7 +5856,7 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 IPackageManager pm = AppGlobals.getPackageManager();
                 pm.setBlockUninstallForUser(packageName, uninstallBlocked, userId);
@@ -5761,7 +5864,7 @@
                 // Shouldn't happen.
                 Slog.e(LOG_TAG, "Failed to setBlockUninstallForUser", re);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -5778,7 +5881,7 @@
                 getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
             }
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 IPackageManager pm = AppGlobals.getPackageManager();
                 return pm.getBlockUninstallForUser(packageName, userId);
@@ -5786,7 +5889,7 @@
                 // Shouldn't happen.
                 Slog.e(LOG_TAG, "Failed to getBlockUninstallForUser", re);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
         return false;
@@ -5838,7 +5941,7 @@
                 actualLookupKey, actualContactId, originalIntent);
         final int callingUserId = UserHandle.getCallingUserId();
 
-        final long ident = Binder.clearCallingIdentity();
+        final long ident = binderClearCallingIdentity();
         try {
             synchronized (this) {
                 final int managedUserId = getManagedUserId(callingUserId);
@@ -5856,7 +5959,7 @@
                         mContext, intent, new UserHandle(managedUserId));
             }
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
     }
 
@@ -5937,7 +6040,7 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
 
-            int userHandle = Binder.getCallingUserHandle().getIdentifier();
+            int userHandle = binderGetCallingUserHandle().getIdentifier();
             setLockTaskPackagesLocked(userHandle, new ArrayList<>(Arrays.asList(packages)));
         }
     }
@@ -5959,7 +6062,7 @@
         Preconditions.checkNotNull(who, "ComponentName is null");
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
-            int userHandle = Binder.getCallingUserHandle().getIdentifier();
+            int userHandle = binderGetCallingUserHandle().getIdentifier();
             final List<String> packages = getLockTaskPackagesLocked(userHandle);
             return packages.toArray(new String[packages.size()]);
         }
@@ -5978,7 +6081,7 @@
     @Override
     public boolean isLockTaskPermitted(String pkg) {
         // Get current user's devicepolicy
-        int uid = Binder.getCallingUid();
+        int uid = binderGetCallingUid();
         int userHandle = UserHandle.getUserId(uid);
         DevicePolicyData policy = getUserData(userHandle);
         synchronized (this) {
@@ -5997,7 +6100,7 @@
 
     @Override
     public void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userHandle) {
-        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+        if (binderGetCallingUid() != Process.SYSTEM_UID) {
             throw new SecurityException("notifyLockTaskModeChanged can only be called by system");
         }
         synchronized (this) {
@@ -6048,11 +6151,11 @@
                 }
             }
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 Settings.Global.putString(contentResolver, setting, value);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -6077,11 +6180,11 @@
                         "Permission denial: Profile owners cannot update %1$s", setting));
             }
 
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 Settings.Secure.putStringForUser(contentResolver, setting, value, callingUserId);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -6092,7 +6195,7 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
             int userId = UserHandle.getCallingUserId();
-            long identity = Binder.clearCallingIdentity();
+            long identity = binderClearCallingIdentity();
             try {
                 IAudioService iAudioService = IAudioService.Stub.asInterface(
                         ServiceManager.getService(Context.AUDIO_SERVICE));
@@ -6100,7 +6203,7 @@
             } catch (RemoteException re) {
                 Slog.e(LOG_TAG, "Failed to setMasterMute", re);
             } finally {
-                Binder.restoreCallingIdentity(identity);
+                binderRestoreCallingIdentity(identity);
             }
         }
     }
@@ -6124,11 +6227,11 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
             int userId = UserHandle.getCallingUserId();
-            long id = Binder.clearCallingIdentity();
+            long id = binderClearCallingIdentity();
             try {
                 mUserManager.setUserIcon(userId, icon);
             } finally {
-                restoreCallingIdentity(id);
+                binderRestoreCallingIdentity(id);
             }
         }
     }
@@ -6142,7 +6245,7 @@
         final int userId = UserHandle.getCallingUserId();
         LockPatternUtils utils = new LockPatternUtils(mContext);
 
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             // disallow disabling the keyguard if a password is currently set
             if (disabled && utils.isSecure(userId)) {
@@ -6150,7 +6253,7 @@
             }
             utils.setLockScreenDisabled(disabled, userId);
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
         return true;
     }
@@ -6173,7 +6276,7 @@
     }
 
     private boolean setStatusBarDisabledInternal(boolean disabled, int userId) {
-        long ident = Binder.clearCallingIdentity();
+        long ident = binderClearCallingIdentity();
         try {
             IStatusBarService statusBarService = IStatusBarService.Stub.asInterface(
                     ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
@@ -6187,7 +6290,7 @@
         } catch (RemoteException e) {
             Slog.e(LOG_TAG, "Failed to disable the status bar", e);
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            binderRestoreCallingIdentity(ident);
         }
         return false;
     }
@@ -6418,7 +6521,7 @@
                 Log.e(LOG_TAG, "Cannot find device owner package", e);
             }
             if (receivers != null) {
-                long ident = Binder.clearCallingIdentity();
+                long ident = binderClearCallingIdentity();
                 try {
                     for (int i = 0; i < receivers.length; i++) {
                         if (permission.BIND_DEVICE_ADMIN.equals(receivers[i].permission)) {
@@ -6428,7 +6531,7 @@
                         }
                     }
                 } finally {
-                    Binder.restoreCallingIdentity(ident);
+                    binderRestoreCallingIdentity(ident);
                 }
             }
         }
@@ -6459,10 +6562,10 @@
     @Override
     public boolean setPermissionGrantState(ComponentName admin, String packageName,
             String permission, int grantState) throws RemoteException {
-        UserHandle user = Binder.getCallingUserHandle();
+        UserHandle user = binderGetCallingUserHandle();
         synchronized (this) {
             getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-            long ident = Binder.clearCallingIdentity();
+            long ident = binderClearCallingIdentity();
             try {
                 final ApplicationInfo ai = AppGlobals.getPackageManager()
                         .getApplicationInfo(packageName, 0, user.getIdentifier());
@@ -6496,7 +6599,7 @@
             } catch (SecurityException se) {
                 return false;
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
         }
     }
@@ -6506,10 +6609,10 @@
             String permission) throws RemoteException {
         PackageManager packageManager = mContext.getPackageManager();
 
-        UserHandle user = Binder.getCallingUserHandle();
+        UserHandle user = binderGetCallingUserHandle();
         synchronized (this) {
             getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-            long ident = Binder.clearCallingIdentity();
+            long ident = binderClearCallingIdentity();
             try {
                 int granted = AppGlobals.getPackageManager().checkPermission(permission,
                         packageName, user.getIdentifier());
@@ -6525,7 +6628,7 @@
                             : DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
                 }
             } finally {
-                Binder.restoreCallingIdentity(ident);
+                binderRestoreCallingIdentity(ident);
             }
         }
     }
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 7d1282b..cb2c9b7 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -67,6 +67,15 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name="com.android.server.devicepolicy.DummyDeviceAdmin"
+                android:permission="android.permission.BIND_DEVICE_ADMIN">
+            <meta-data android:name="android.app.device_admin"
+                android:resource="@xml/device_admin_sample" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
     </application>
 
     <instrumentation
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
new file mode 100644
index 0000000..cb439eb
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2015 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 com.android.internal.widget.LockPatternUtils;
+
+import android.app.IActivityManager;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Looper;
+import android.os.PowerManager.WakeLock;
+import android.os.PowerManagerInternal;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.view.IWindowManager;
+
+import java.io.File;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+
+/**
+ * Overrides {@link #DevicePolicyManagerService} for dependency injection.
+ */
+public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerService {
+    /**
+     * Overrides {@link #Owners} for dependency injection.
+     */
+    public static class OwnersTestable extends Owners {
+        public static final String LEGACY_FILE = "legacy.xml";
+        public static final String DEVICE_OWNER_FILE = "device_owner2.xml";
+        public static final String PROFILE_OWNER_FILE_BASE = "profile_owner.xml";
+
+        final private File mLegacyFile;
+        final private File mDeviceOwnerFile;
+        final private File mProfileOwnerBase;
+
+        public OwnersTestable(Context context, File dataDir) {
+            super(context);
+            mLegacyFile = new File(dataDir, LEGACY_FILE);
+            mDeviceOwnerFile = new File(dataDir, DEVICE_OWNER_FILE);
+            mProfileOwnerBase = new File(dataDir, PROFILE_OWNER_FILE_BASE);
+        }
+
+        @Override
+        File getLegacyConfigFileWithTestOverride() {
+            return mLegacyFile;
+        }
+
+        @Override
+        File getDeviceOwnerFileWithTestOverride() {
+            return mDeviceOwnerFile;
+        }
+
+        @Override
+        File getProfileOwnerFileWithTestOverride(int userId) {
+            return new File(mDeviceOwnerFile.getAbsoluteFile() + "-" + userId);
+        }
+    }
+
+    public final File dataDir;
+    public final File systemUserDataDir;
+    public final File secondUserDataDir;
+
+    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);
+    }
+
+    @Override
+    DpmMockContext getContext() {
+        return (DpmMockContext) super.getContext();
+    }
+
+    @Override
+    protected Owners newOwners() {
+        return new OwnersTestable(getContext(), dataDir);
+    }
+
+    @Override
+    protected UserManager getUserManager() {
+        return getContext().userManager;
+    }
+
+    @Override
+    protected PackageManager getPackageManager() {
+        return getContext().packageManager;
+    }
+
+    @Override
+    protected PowerManagerInternal getPowerManagerInternal() {
+        return getContext().powerManagerInternal;
+    }
+
+    @Override
+    protected NotificationManager getNotificationManager() {
+        return getContext().notificationManager;
+    }
+
+    @Override
+    protected IWindowManager newIWindowManager() {
+        return getContext().iwindowManager;
+    }
+
+    @Override
+    protected IActivityManager getIActivityManager() {
+        return getContext().iactivityManager;
+    }
+
+    @Override
+    protected LockPatternUtils newLockPatternUtils(Context context) {
+        return getContext().lockPatternUtils;
+    }
+
+    @Override
+    protected Looper getMyLooper() {
+        return Looper.getMainLooper();
+    }
+
+    @Override
+    String getDevicePolicyFilePathForSystemUser() {
+        return systemUserDataDir.getAbsolutePath();
+    }
+
+    @Override
+    long binderClearCallingIdentity() {
+        return getContext().binder.clearCallingIdentity();
+    }
+
+    @Override
+    void binderRestoreCallingIdentity(long token) {
+        getContext().binder.restoreCallingIdentity(token);
+    }
+
+    @Override
+    int binderGetCallingUid() {
+        return getContext().binder.getCallingUid();
+    }
+
+    @Override
+    int binderGetCallingPid() {
+        return getContext().binder.getCallingPid();
+    }
+
+    @Override
+    UserHandle binderGetCallingUserHandle() {
+        return getContext().binder.getCallingUserHandle();
+    }
+
+    @Override
+    boolean binderIsCallingUidMyUid() {
+        return getContext().binder.isCallerUidMyUid();
+    }
+
+    @Override
+    File environmentGetUserSystemDirectory(int userId) {
+        return getContext().environment.getUserSystemDirectory(userId);
+    }
+
+    @Override
+    WakeLock powerManagerNewWakeLock(int levelAndFlags, String tag) {
+        return getContext().powerManager.newWakeLock(levelAndFlags, tag);
+    }
+
+    @Override
+    void powerManagerGoToSleep(long time, int reason, int flags) {
+        getContext().powerManager.goToSleep(time, reason, flags);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
new file mode 100644
index 0000000..7cce56c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2015 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 com.android.server.LocalServices;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.DevicePolicyManagerInternal;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+
+import org.mockito.ArgumentCaptor;
+
+import java.util.List;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for {@link DevicePolicyManager} and {@link DevicePolicyManagerService}.
+ *
+ m FrameworksServicesTests &&
+ adb install \
+ -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
+ adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest \
+ -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+
+ (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
+ */
+public class DevicePolicyManagerTest extends DpmTestBase {
+
+    private DpmMockContext mContext;
+    public DevicePolicyManager dpm;
+    public DevicePolicyManagerServiceTestable dpms;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mContext = getContext();
+
+        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
+                .thenReturn(true);
+
+        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
+        dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
+        dpm = new DevicePolicyManagerTestable(mContext, dpms);
+    }
+
+    public void testHasNoFeature() {
+        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
+                .thenReturn(false);
+
+        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
+        new DevicePolicyManagerServiceTestable(mContext, dataDir);
+
+        // If the device has no DPMS feature, it shouldn't register the local service.
+        assertNull(LocalServices.getService(DevicePolicyManagerInternal.class));
+    }
+
+    /**
+     * Caller doesn't have proper permissions.
+     */
+    public void testSetActiveAdmin_SecurityException() {
+        final ComponentName admin = new ComponentName(mRealTestContext, DummyDeviceAdmin.class);
+
+        // 1. Failure cases.
+
+        // Caller doesn't have MANAGE_DEVICE_ADMINS.
+        try {
+            dpm.setActiveAdmin(admin, false);
+            fail("Didn't throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+
+        // Caller has MANAGE_DEVICE_ADMINS, but for different user.
+        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
+        try {
+            dpm.setActiveAdmin(admin, false, DpmMockContext.CALLER_USER_HANDLE + 1);
+            fail("Didn't throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testSetActiveAdmin() {
+        final ComponentName admin = new ComponentName(mRealTestContext, DummyDeviceAdmin.class);
+
+        // 1. Prepare mock package manager (and other mocks)
+
+        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
+
+        // Create ResolveInfo for the admin.
+        final Intent resolveIntent = new Intent();
+        resolveIntent.setComponent(admin);
+        final List<ResolveInfo> realResolveInfo =
+                mRealTestContext.getPackageManager().queryBroadcastReceivers(
+                        resolveIntent,
+                        PackageManager.GET_META_DATA
+                            | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
+        assertNotNull(realResolveInfo);
+        assertEquals(1, realResolveInfo.size());
+
+        // We need to rewrite the UID in the activity info.
+        realResolveInfo.get(0).activityInfo.applicationInfo.uid = DpmMockContext.CALLER_UID;
+
+        doReturn(realResolveInfo).when(mContext.packageManager).queryBroadcastReceivers(
+                any(Intent.class), // TODO check the intent too.
+                eq(PackageManager.GET_META_DATA
+                        | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS),
+                eq(DpmMockContext.CALLER_USER_HANDLE)
+        );
+
+        // 2. Everything is ready; call the method.
+        dpm.setActiveAdmin(admin, false);
+
+        // 3. Verify internal calls.
+
+        // Check if the boradcast is sent.
+        final ArgumentCaptor<Intent> intentCap = ArgumentCaptor.forClass(Intent.class);
+        final ArgumentCaptor<UserHandle> uhCap = ArgumentCaptor.forClass(UserHandle.class);
+
+        verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
+                intentCap.capture(),
+                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
+
+        // First call from saveSettingsLocked().
+        assertEquals(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED,
+                intentCap.getAllValues().get(0).getAction());
+
+        // Second call from setActiveAdmin/sendAdminCommandLocked()
+        assertEquals(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED,
+                intentCap.getAllValues().get(1).getAction());
+
+        // TODO Verify other calls too.
+    }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTestable.java
new file mode 100644
index 0000000..325bf9f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTestable.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 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.DevicePolicyManager;
+
+/**
+ * Overrides {@link #DevicePolicyManager} for dependency injection.
+ */
+public class DevicePolicyManagerTestable extends DevicePolicyManager {
+    public final DevicePolicyManagerServiceTestable dpms;
+
+    public DevicePolicyManagerTestable(DpmMockContext context,
+            DevicePolicyManagerServiceTestable dpms) {
+        super(context, dpms);
+        this.dpms = dpms;
+    }
+
+    @Override
+    public int myUserId() {
+        return DpmMockContext.CALLER_USER_HANDLE;
+    }
+}
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 c2b8981..8644311 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -16,31 +16,328 @@
 
 package com.android.server.devicepolicy;
 
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.IActivityManager;
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.PowerManager.WakeLock;
+import android.os.PowerManagerInternal;
+import android.os.UserHandle;
 import android.os.UserManager;
+import android.test.mock.MockContext;
+import android.view.IWindowManager;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 
-public class DpmMockContext extends ContextWrapper {
-    private final UserManager mMockUserManager;
+/**
+ * Context used throughout DPMS tests.
+ */
+public class DpmMockContext extends MockContext {
+    /**
+     * User-id of a non-system user we use throughout unit tests.
+     */
+    public static final int CALLER_USER_HANDLE = 20;
 
+    /**
+     * UID of the caller.
+     */
+    public static final int CALLER_UID = UserHandle.PER_USER_RANGE * CALLER_USER_HANDLE + 123;
 
-    public DpmMockContext(Context context) {
-        super(context);
-        mMockUserManager = mock(UserManager.class);
+    /**
+     * PID of the caller.
+     */
+    public static final int CALLER_PID = 22222;
+
+    /**
+     * UID of the system server.
+     */
+    public static final int SYSTEM_UID = android.os.Process.SYSTEM_UID;
+
+    /**
+     * PID of the system server.
+     */
+    public static final int SYSTEM_PID = 11111;
+
+    public static class MockBinder {
+        int mCallingUid = CALLER_UID;
+        int mCallingPid = CALLER_PID;
+
+        public long clearCallingIdentity() {
+            final long token = (((long) mCallingUid) << 32) | (mCallingPid);
+            mCallingUid = SYSTEM_UID;
+            mCallingPid = SYSTEM_PID;
+            return token;
+        }
+
+        public void restoreCallingIdentity(long token) {
+            mCallingUid = (int) (token >> 32);
+            mCallingPid = (int) token;
+        }
+
+        public int getCallingUid() {
+            return mCallingUid;
+        }
+
+        public int getCallingPid() {
+            return mCallingPid;
+        }
+
+        public UserHandle getCallingUserHandle() {
+            return new UserHandle(UserHandle.getUserId(getCallingUid()));
+        }
+
+        public boolean isCallerUidMyUid() {
+            return mCallingUid == SYSTEM_UID;
+        }
     }
 
-    public UserManager getMockUserManager() {
-        return mMockUserManager;
+    public static class EnvironmentForMock {
+        public File getUserSystemDirectory(int userId) {
+            return null;
+        }
+    }
+
+    public static class PowerManagerForMock {
+        public WakeLock newWakeLock(int levelAndFlags, String tag) {
+            return null;
+        }
+
+        public void goToSleep(long time, int reason, int flags) {
+        }
+    }
+
+    public final Context realTestContext;
+
+    /**
+     * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}.
+     * (Spying on {@code this} instance will confuse mockito somehow and I got weired "wrong number
+     * of arguments" exceptions.)
+     */
+    public final Context spiedContext;
+
+    public final MockBinder binder;
+    public final EnvironmentForMock environment;
+    public final UserManager userManager;
+    public final PowerManagerForMock powerManager;
+    public final PowerManagerInternal powerManagerInternal;
+    public final NotificationManager notificationManager;
+    public final IWindowManager iwindowManager;
+    public final IActivityManager iactivityManager;
+    public final LockPatternUtils lockPatternUtils;
+
+    /** Note this is a partial mock, not a real mock. */
+    public final PackageManager packageManager;
+
+    public final List<String> callerPermissions = new ArrayList<>();
+
+    public DpmMockContext(Context context) {
+        realTestContext = context;
+        binder = new MockBinder();
+        environment = mock(EnvironmentForMock.class);
+        userManager = mock(UserManager.class);
+        powerManager = mock(PowerManagerForMock.class);
+        powerManagerInternal = mock(PowerManagerInternal.class);
+        notificationManager = mock(NotificationManager.class);
+        iwindowManager = mock(IWindowManager.class);
+        iactivityManager = mock(IActivityManager.class);
+        lockPatternUtils = mock(LockPatternUtils.class);
+
+        // Package manager is huge, so we use a partial mock instead.
+        packageManager = spy(context.getPackageManager());
+
+        spiedContext = mock(Context.class);
     }
 
     @Override
     public Object getSystemService(String name) {
         switch (name) {
             case Context.USER_SERVICE:
-                return mMockUserManager;
+                return userManager;
+            case Context.POWER_SERVICE:
+                return powerManager;
         }
-        return super.getSystemService(name);
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PackageManager getPackageManager() {
+        return packageManager;
+    }
+
+    @Override
+    public void enforceCallingOrSelfPermission(String permission, String message) {
+        if (binder.getCallingUid() == SYSTEM_UID) {
+            return; // Assume system has all permissions.
+        }
+        if (!callerPermissions.contains(permission)) {
+            throw new SecurityException("Caller doesn't have " + permission + " : " + message);
+        }
+    }
+
+    @Override
+    public void sendBroadcast(Intent intent) {
+        spiedContext.sendBroadcast(intent);
+    }
+
+    @Override
+    public void sendBroadcast(Intent intent, String receiverPermission) {
+        spiedContext.sendBroadcast(intent, receiverPermission);
+    }
+
+    @Override
+    public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
+        spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions);
+    }
+
+    @Override
+    public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
+        spiedContext.sendBroadcast(intent, receiverPermission, options);
+    }
+
+    @Override
+    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
+        spiedContext.sendBroadcast(intent, receiverPermission, appOp);
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
+        spiedContext.sendOrderedBroadcast(intent, receiverPermission);
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+            String initialData, Bundle initialExtras) {
+        spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
+                initialCode, initialData, initialExtras);
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+            String initialData, Bundle initialExtras) {
+        spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver,
+                scheduler,
+                initialCode, initialData, initialExtras);
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+            String initialData, Bundle initialExtras) {
+        spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver,
+                scheduler,
+                initialCode, initialData, initialExtras);
+    }
+
+    @Override
+    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+        spiedContext.sendBroadcastAsUser(intent, user);
+    }
+
+    @Override
+    public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) {
+        spiedContext.sendBroadcastAsUser(intent, user, receiverPermission);
+    }
+
+    @Override
+    public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
+            int appOp) {
+        spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp);
+    }
+
+    @Override
+    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
+            int initialCode, String initialData, Bundle initialExtras) {
+        spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver,
+                scheduler, initialCode, initialData, initialExtras);
+    }
+
+    @Override
+    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+        spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
+                resultReceiver,
+                scheduler, initialCode, initialData, initialExtras);
+    }
+
+    @Override
+    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+        spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options,
+                resultReceiver, scheduler, initialCode, initialData, initialExtras);
+    }
+
+    @Override
+    public void sendStickyBroadcast(Intent intent) {
+        spiedContext.sendStickyBroadcast(intent);
+    }
+
+    @Override
+    public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+        spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode,
+                initialData, initialExtras);
+    }
+
+    @Override
+    public void removeStickyBroadcast(Intent intent) {
+        spiedContext.removeStickyBroadcast(intent);
+    }
+
+    @Override
+    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
+        spiedContext.sendStickyBroadcastAsUser(intent, user);
+    }
+
+    @Override
+    public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+            String initialData, Bundle initialExtras) {
+        spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode,
+                initialData, initialExtras);
+    }
+
+    @Override
+    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
+        spiedContext.removeStickyBroadcastAsUser(intent, user);
+    }
+
+    @Override
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+        return spiedContext.registerReceiver(receiver, filter);
+    }
+
+    @Override
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+            String broadcastPermission, Handler scheduler) {
+        return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
+    }
+
+    @Override
+    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
+            IntentFilter filter, String broadcastPermission, Handler scheduler) {
+        return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
+                scheduler);
+    }
+
+    @Override
+    public void unregisterReceiver(BroadcastReceiver receiver) {
+        spiedContext.unregisterReceiver(receiver);
     }
 }
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 445260b..77270c8 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
@@ -19,14 +19,25 @@
 import android.content.Context;
 import android.test.AndroidTestCase;
 
+import java.io.File;
+
 public class DpmTestBase extends AndroidTestCase {
-    private DpmMockContext mMockContext;
+    public static final String TAG = "DpmTest";
+
+    protected Context mRealTestContext;
+    protected DpmMockContext mMockContext;
+
+    public File dataDir;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
 
+        mRealTestContext = super.getContext();
         mMockContext = new DpmMockContext(super.getContext());
+
+        dataDir = new File(mRealTestContext.getCacheDir(), "test-data");
+        DpmTestUtils.clearDir(dataDir);
     }
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestUtils.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestUtils.java
new file mode 100644
index 0000000..a8e2c3c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestUtils.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 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.os.FileUtils;
+import android.util.Log;
+import android.util.Printer;
+
+import org.junit.Assert;
+
+import java.io.File;
+
+public class DpmTestUtils {
+    private DpmTestUtils() {
+    }
+
+    public static void clearDir(File dir) {
+        if (dir.exists()) {
+            Assert.assertTrue("failed to delete dir", FileUtils.deleteContents(dir));
+        }
+        dir.mkdirs();
+    }
+
+    public static Printer LOG_PRINTER = new Printer() {
+        @Override
+        public void println(String x) {
+            Log.i(DpmTestBase.TAG, x);
+        }
+    };
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmin.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmin.java
new file mode 100644
index 0000000..c47d194
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmin.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2015 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;
+
+public class DummyDeviceAdmin extends DeviceAdminReceiver {
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
new file mode 100644
index 0000000..f2a2bf7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 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 com.google.common.base.Objects;
+
+import android.os.UserHandle;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.mockito.Mockito;
+
+public class MockUtils {
+    private MockUtils() {
+    }
+
+    public static UserHandle checkUserHandle(final int userId) {
+        final Matcher<UserHandle> m = new BaseMatcher<UserHandle>() {
+            @Override
+            public boolean matches(Object item) {
+                if (item == null) return false;
+                return Objects.equal(((UserHandle) item).getIdentifier(), userId);
+            }
+
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("UserHandle: user-id= \"" + userId + "\"");
+            }
+        };
+        return Mockito.argThat(m);
+    }
+
+}
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 3b88fb1..a07d615 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
@@ -16,12 +16,11 @@
 
 package com.android.server.devicepolicy;
 
+import com.android.server.devicepolicy.DevicePolicyManagerServiceTestable.OwnersTestable;
+
 import android.content.ComponentName;
-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;
 
 import java.io.BufferedReader;
@@ -31,8 +30,6 @@
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 
-import junit.framework.Assert;
-
 import static org.mockito.Mockito.when;
 
 /**
@@ -47,58 +44,11 @@
  (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
  */
 public class OwnersTest extends DpmTestBase {
-    private static final String TAG = "DeviceOwnerTest";
-
-    private static final String LEGACY_FILE = "legacy.xml";
-    private static final String DEVICE_OWNER_FILE = "device_owner2.xml";
-    private static final String PROFILE_OWNER_FILE_BASE = "profile_owner.xml";
-
-    private File mDataDir;
-
-    private class OwnersSub extends Owners {
-        final File mLegacyFile;
-        final File mDeviceOwnerFile;
-        final File mProfileOwnerBase;
-
-        public OwnersSub() {
-            super(getContext());
-            mLegacyFile = new File(mDataDir, LEGACY_FILE);
-            mDeviceOwnerFile = new File(mDataDir, DEVICE_OWNER_FILE);
-            mProfileOwnerBase = new File(mDataDir, PROFILE_OWNER_FILE_BASE);
-        }
-
-        @Override
-        File getLegacyConfigFileWithTestOverride() {
-            return mLegacyFile;
-        }
-
-        @Override
-        File getDeviceOwnerFileWithTestOverride() {
-            return mDeviceOwnerFile;
-        }
-
-        @Override
-        File getProfileOwnerFileWithTestOverride(int userId) {
-            return new File(mDeviceOwnerFile.getAbsoluteFile() + "-" + userId);
-        }
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mDataDir = new File(getContext().getCacheDir(), "OwnersTest");
-        if (mDataDir.exists()) {
-            assertTrue("failed to delete dir", FileUtils.deleteContents(mDataDir));
-        }
-        mDataDir.mkdirs();
-        Log.i(TAG, "Created " + mDataDir);
-    }
-
     private String readAsset(String assetPath) throws IOException {
         final StringBuilder sb = new StringBuilder();
         try (BufferedReader br = new BufferedReader(
-                new InputStreamReader((getContext().getResources().getAssets().open(assetPath))))) {
+                new InputStreamReader(
+                        mRealTestContext.getResources().getAssets().open(assetPath)))) {
             String line;
             while ((line = br.readLine()) != null) {
                 sb.append(line);
@@ -126,7 +76,7 @@
             ui.id = userId;
             userInfos.add(ui);
         }
-        when(getContext().getMockUserManager().getUsers()).thenReturn(userInfos);
+        when(getContext().userManager.getUsers()).thenReturn(userInfos);
     }
 
     public void testUpgrade01() throws Exception {
@@ -134,9 +84,10 @@
 
         // First, migrate.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
 
-            createLegacyFile(owners.mLegacyFile, readAsset("OwnersTest/test01/input.xml"));
+            createLegacyFile(owners.getLegacyConfigFileWithTestOverride(),
+                    readAsset("OwnersTest/test01/input.xml"));
 
             owners.load();
 
@@ -160,7 +111,7 @@
 
         // Then re-read and check.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -176,9 +127,10 @@
 
         // First, migrate.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
 
-            createLegacyFile(owners.mLegacyFile, readAsset("OwnersTest/test02/input.xml"));
+            createLegacyFile(owners.getLegacyConfigFileWithTestOverride(),
+                    readAsset("OwnersTest/test02/input.xml"));
 
             owners.load();
 
@@ -204,7 +156,7 @@
 
         // Then re-read and check.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
             owners.load();
 
             assertTrue(owners.hasDeviceOwner());
@@ -223,9 +175,10 @@
 
         // First, migrate.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
 
-            createLegacyFile(owners.mLegacyFile, readAsset("OwnersTest/test03/input.xml"));
+            createLegacyFile(owners.getLegacyConfigFileWithTestOverride(),
+                    readAsset("OwnersTest/test03/input.xml"));
 
             owners.load();
 
@@ -259,7 +212,7 @@
 
         // Then re-read and check.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -286,9 +239,10 @@
 
         // First, migrate.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
 
-            createLegacyFile(owners.mLegacyFile, readAsset("OwnersTest/test04/input.xml"));
+            createLegacyFile(owners.getLegacyConfigFileWithTestOverride(),
+                    readAsset("OwnersTest/test04/input.xml"));
 
             owners.load();
 
@@ -327,7 +281,7 @@
 
         // Then re-read and check.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
             owners.load();
 
             assertTrue(owners.hasDeviceOwner());
@@ -359,9 +313,10 @@
 
         // First, migrate.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
 
-            createLegacyFile(owners.mLegacyFile, readAsset("OwnersTest/test05/input.xml"));
+            createLegacyFile(owners.getLegacyConfigFileWithTestOverride(),
+                    readAsset("OwnersTest/test05/input.xml"));
 
             owners.load();
 
@@ -386,7 +341,7 @@
 
         // Then re-read and check.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -405,9 +360,10 @@
 
         // First, migrate.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
 
-            createLegacyFile(owners.mLegacyFile, readAsset("OwnersTest/test06/input.xml"));
+            createLegacyFile(owners.getLegacyConfigFileWithTestOverride(),
+                    readAsset("OwnersTest/test06/input.xml"));
 
             owners.load();
 
@@ -431,7 +387,7 @@
 
         // Then re-read and check.
         {
-            final OwnersSub owners = new OwnersSub();
+            final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
             owners.load();
 
             assertFalse(owners.hasDeviceOwner());
@@ -447,10 +403,11 @@
     public void testRemoveExistingFiles() throws Exception {
         addUsersToUserManager(10, 11, 20, 21);
 
-        final OwnersSub owners = new OwnersSub();
+        final OwnersTestable owners = new OwnersTestable(getContext(), dataDir);
 
         // First, migrate to create new-style config files.
-        createLegacyFile(owners.mLegacyFile, readAsset("OwnersTest/test04/input.xml"));
+        createLegacyFile(owners.getLegacyConfigFileWithTestOverride(),
+                readAsset("OwnersTest/test04/input.xml"));
 
         owners.load();