OSDN Git Service

Make DevicePolicyManagerService more customizable (per-device).
authorLenka Trochtova <ltrochtova@google.com>
Mon, 16 Oct 2017 16:41:39 +0000 (18:41 +0200)
committerLenka Trochtova <ltrochtova@google.com>
Thu, 30 Nov 2017 09:27:35 +0000 (10:27 +0100)
Add a config to override the DPMS implementation class to
be instantiated from the Lifecycle.
Add a hasFeature method to the Injector class.

BUG: 63753860
Test: manual with TestDPC

Change-Id: I71ef518c49b2233744defdfb7c31019cb228d678

core/res/res/values/config.xml
core/res/res/values/symbols.xml
services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java [new file with mode: 0644]
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java

index 171f74f..5f756fa 100644 (file)
          classes are instantiated in the order of the array. -->
     <string-array translatable="false" name="config_deviceSpecificSystemServices"></string-array>
 
+    <!-- Class name of the device specific implementation to replace the DevicePolicyManagerService
+         or empty if the default should be used. -->
+    <string translatable="false" name="config_deviceSpecificDevicePolicyManagerService"></string>
+
     <!-- Component name of media projection permission dialog -->
     <string name="config_mediaProjectionPermissionDialogComponent" translateable="false">com.android.systemui/com.android.systemui.media.MediaProjectionPermissionActivity</string>
 
index a115816..ad947b7 100644 (file)
   <java-symbol type="bool" name="config_hasPermanentDpad" />
   <java-symbol type="bool" name="config_useDefaultFocusHighlight" />
   <java-symbol type="array" name="config_deviceSpecificSystemServices" />
+  <java-symbol type="string" name="config_deviceSpecificDevicePolicyManagerService" />
 
   <java-symbol type="color" name="tab_indicator_text_v4" />
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
new file mode 100644 (file)
index 0000000..dddff8f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 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.IDevicePolicyManager;
+
+import com.android.internal.R;
+import com.android.server.SystemService;
+
+/**
+ * Defines the required interface for IDevicePolicyManager implemenation.
+ *
+ * <p>The interface consists of public parts determined by {@link IDevicePolicyManager} and also
+ * several package private methods required by internal infrastructure.
+ *
+ * <p>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);
+}
index 60c36d1..223778f 100644 (file)
@@ -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");
     }