diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 171f74f9ead8e..5f756fabdb782 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3169,6 +3169,10 @@
classes are instantiated in the order of the array. -->
The interface consists of public parts determined by {@link IDevicePolicyManager} and also + * several package private methods required by internal infrastructure. + * + *
Whenever adding an AIDL method to {@link IDevicePolicyManager}, an empty override method + * should be added here to avoid build breakage in downstream branches. + */ +abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { + /** + * To be called by {@link DevicePolicyManagerService#Lifecycle} during the various boot phases. + * + * @see {@link SystemService#onBootPhase}. + */ + abstract void systemReady(int phase); + /** + * To be called by {@link DevicePolicyManagerService#Lifecycle} when a new user starts. + * + * @see {@link SystemService#onStartUser} + */ + abstract void handleStartUser(int userId); + /** + * To be called by {@link DevicePolicyManagerService#Lifecycle} when a user is being unlocked. + * + * @see {@link SystemService#onUnlockUser} + */ + abstract void handleUnlockUser(int userId); + /** + * To be called by {@link DevicePolicyManagerService#Lifecycle} when a user is being stopped. + * + * @see {@link SystemService#onStopUser} + */ + abstract void handleStopUser(int userId); +} diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 60c36d1b72031..223778f80b7ca 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -198,6 +198,8 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; +import java.lang.IllegalStateException; +import java.lang.reflect.Constructor; import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.util.ArrayList; @@ -214,7 +216,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * Implementation of the device policy APIs. */ -public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { +public class DevicePolicyManagerService extends BaseIDevicePolicyManager { protected static final String LOG_TAG = "DevicePolicyManager"; @@ -451,11 +453,24 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { }; public static final class Lifecycle extends SystemService { - private DevicePolicyManagerService mService; + private BaseIDevicePolicyManager mService; public Lifecycle(Context context) { super(context); - mService = new DevicePolicyManagerService(context); + String dpmsClassName = context.getResources() + .getString(R.string.config_deviceSpecificDevicePolicyManagerService); + if (TextUtils.isEmpty(dpmsClassName)) { + dpmsClassName = DevicePolicyManagerService.class.getName(); + } + try { + Class serviceClass = Class.forName(dpmsClassName); + Constructor constructor = serviceClass.getConstructor(Context.class); + mService = (BaseIDevicePolicyManager) constructor.newInstance(context); + } catch (Exception e) { + throw new IllegalStateException( + "Failed to instantiate DevicePolicyManagerService with class name: " + + dpmsClassName, e); + } } @Override @@ -1551,6 +1566,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mContext = context; } + public boolean hasFeature() { + return getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN); + } + Context createContextAsUser(UserHandle user) throws PackageManager.NameNotFoundException { final String packageName = mContext.getPackageName(); return mContext.createPackageContextAsUser(packageName, 0, user); @@ -1848,8 +1867,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // TODO: why does SecurityLogMonitor need to be created even when mHasFeature == false? mSecurityLogMonitor = new SecurityLogMonitor(this); - mHasFeature = mInjector.getPackageManager() - .hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN); + mHasFeature = mInjector.hasFeature(); mIsWatch = mInjector.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_WATCH); mBackgroundHandler = BackgroundThread.getHandler(); @@ -3033,6 +3051,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @VisibleForTesting + @Override void systemReady(int phase) { if (!mHasFeature) { return; @@ -3099,6 +3118,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + @Override void handleStartUser(int userId) { updateScreenCaptureDisabledInWindowManager(userId, getScreenCaptureDisabled(null, userId)); @@ -3107,10 +3127,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { startOwnerService(userId, "start-user"); } + @Override void handleUnlockUser(int userId) { startOwnerService(userId, "unlock-user"); } + @Override void handleStopUser(int userId) { stopOwnerService(userId, "stop-user"); }