Loading core/java/android/app/admin/DevicePolicyManager.java +21 −0 Original line number Original line Diff line number Diff line Loading @@ -122,6 +122,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executor; // TODO(b/172376923) - add CarDevicePolicyManager examples below (or remove reference to it). /** /** * Public interface for managing policies enforced on a device. Most clients of this class must be * Public interface for managing policies enforced on a device. Most clients of this class must be * registered with the system as a <a href="{@docRoot}guide/topics/admin/device-admin.html">device * registered with the system as a <a href="{@docRoot}guide/topics/admin/device-admin.html">device Loading @@ -130,6 +131,13 @@ import java.util.concurrent.Executor; * for that method specifies that it is restricted to either device or profile owners. Any * for that method specifies that it is restricted to either device or profile owners. Any * application calling an api may only pass as an argument a device administrator component it * application calling an api may only pass as an argument a device administrator component it * owns. Otherwise, a {@link SecurityException} will be thrown. * owns. Otherwise, a {@link SecurityException} will be thrown. * * <p><b>Note: </b>on * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds}, some methods can * throw an {@link UnsafeStateException} exception (for example, if the vehicle is moving), so * callers running on automotive builds should wrap every method call under the methods provided by * {@code android.car.admin.CarDevicePolicyManager}. * * <div class="special reference"> * <div class="special reference"> * <h3>Developer Guides</h3> * <h3>Developer Guides</h3> * <p> * <p> Loading Loading @@ -2445,6 +2453,19 @@ public class DevicePolicyManager { @Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE) public @interface PersonalAppsSuspensionReason {} public @interface PersonalAppsSuspensionReason {} /** @hide */ // TODO(b/172376923): make it TestApi public static final int OPERATION_LOCK_NOW = 1; // TODO(b/172376923) - add all operations /** @hide */ @IntDef(prefix = "OPERATION_", value = { OPERATION_LOCK_NOW, }) @Retention(RetentionPolicy.SOURCE) public static @interface DevicePolicyOperation { } /** /** * Return true if the given administrator component is currently active (enabled) in the system. * Return true if the given administrator component is currently active (enabled) in the system. * * Loading core/java/android/app/admin/DevicePolicySafetyChecker.java 0 → 100644 +42 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2020 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 android.app.admin; import android.annotation.NonNull; import android.app.admin.DevicePolicyManager.DevicePolicyOperation; /** * Interface responsible to check if a {@link DevicePolicyManager} API can be safely executed. * * @hide */ public interface DevicePolicySafetyChecker { /** * Returns whether the given {@code operation} can be safely executed at the moment. */ default boolean isDevicePolicyOperationSafe(@DevicePolicyOperation int operation) { return true; } /** * Returns a new exception for when the given {@code operation} cannot be safely executed. */ @NonNull default UnsafeStateException newUnsafeStateException(@DevicePolicyOperation int operation) { return new UnsafeStateException(operation); } } core/java/android/app/admin/UnsafeStateException.java 0 → 100644 +76 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2020 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 android.app.admin; import android.annotation.NonNull; import android.app.admin.DevicePolicyManager.DevicePolicyOperation; import android.os.Parcel; import android.os.Parcelable; /** * Exception thrown when a {@link DevicePolicyManager} operation failed because it was not safe * to be executed at that moment. * * <p>For example, it can be thrown on * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive devices} when the vehicle * is moving. * * @hide */ // TODO(b/172376923): make it public @SuppressWarnings("serial") public final class UnsafeStateException extends IllegalStateException implements Parcelable { private final @DevicePolicyOperation int mOperation; /** @hide */ public UnsafeStateException(@DevicePolicyOperation int operation) { super(); mOperation = operation; } /** @hide */ // TODO(b/172376923): make it TestApi public @DevicePolicyOperation int getOperation() { return mOperation; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mOperation); } @NonNull public static final Creator<UnsafeStateException> CREATOR = new Creator<UnsafeStateException>() { @Override public UnsafeStateException createFromParcel(Parcel source) { return new UnsafeStateException(source.readInt()); } @Override public UnsafeStateException[] newArray(int size) { return new UnsafeStateException[size]; } }; } services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java +15 −0 Original line number Original line Diff line number Diff line Loading @@ -15,8 +15,10 @@ */ */ package com.android.server.devicepolicy; package com.android.server.devicepolicy; import android.app.admin.DevicePolicySafetyChecker; import android.app.admin.IDevicePolicyManager; import android.app.admin.IDevicePolicyManager; import android.content.ComponentName; import android.content.ComponentName; import android.util.Slog; import com.android.server.SystemService; import com.android.server.SystemService; Loading @@ -30,6 +32,9 @@ import com.android.server.SystemService; * should be added here to avoid build breakage in downstream branches. * should be added here to avoid build breakage in downstream branches. */ */ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { private static final String TAG = BaseIDevicePolicyManager.class.getSimpleName(); /** /** * To be called by {@link DevicePolicyManagerService#Lifecycle} during the various boot phases. * To be called by {@link DevicePolicyManagerService#Lifecycle} during the various boot phases. * * Loading @@ -55,6 +60,16 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { */ */ abstract void handleStopUser(int userId); abstract void handleStopUser(int userId); /** * Sets the {@link DevicePolicySafetyChecker}. * * <p>Currently, it's called only by {@code SystemServer} on * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds} */ public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) { Slog.w(TAG, "setDevicePolicySafetyChecker() not implemented by " + getClass()); } public void clearSystemUpdatePolicyFreezePeriodRecord() { public void clearSystemUpdatePolicyFreezePeriodRecord() { } } Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +49 −3 Original line number Original line Diff line number Diff line Loading @@ -135,9 +135,11 @@ import android.app.admin.DeviceAdminReceiver; import android.app.admin.DevicePolicyCache; import android.app.admin.DevicePolicyCache; import android.app.admin.DevicePolicyEventLogger; import android.app.admin.DevicePolicyEventLogger; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager.DevicePolicyOperation; import android.app.admin.DevicePolicyManager.PasswordComplexity; import android.app.admin.DevicePolicyManager.PasswordComplexity; import android.app.admin.DevicePolicyManager.PersonalAppsSuspensionReason; import android.app.admin.DevicePolicyManager.PersonalAppsSuspensionReason; import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.DevicePolicySafetyChecker; import android.app.admin.DeviceStateCache; import android.app.admin.DeviceStateCache; import android.app.admin.FactoryResetProtectionPolicy; import android.app.admin.FactoryResetProtectionPolicy; import android.app.admin.NetworkEvent; import android.app.admin.NetworkEvent; Loading @@ -148,6 +150,7 @@ import android.app.admin.SecurityLog.SecurityEvent; import android.app.admin.StartInstallingUpdateCallback; import android.app.admin.StartInstallingUpdateCallback; import android.app.admin.SystemUpdateInfo; import android.app.admin.SystemUpdateInfo; import android.app.admin.SystemUpdatePolicy; import android.app.admin.SystemUpdatePolicy; import android.app.admin.UnsafeStateException; import android.app.backup.IBackupManager; import android.app.backup.IBackupManager; import android.app.trust.TrustManager; import android.app.trust.TrustManager; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal; Loading Loading @@ -634,6 +637,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @VisibleForTesting @VisibleForTesting final TransferOwnershipMetadataManager mTransferOwnershipMetadataManager; final TransferOwnershipMetadataManager mTransferOwnershipMetadataManager; @Nullable private DevicePolicySafetyChecker mSafetyChecker; public static final class Lifecycle extends SystemService { public static final class Lifecycle extends SystemService { private BaseIDevicePolicyManager mService; private BaseIDevicePolicyManager mService; Loading @@ -645,8 +651,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { dpmsClassName = DevicePolicyManagerService.class.getName(); dpmsClassName = DevicePolicyManagerService.class.getName(); } } try { try { Class serviceClass = Class.forName(dpmsClassName); Class<?> serviceClass = Class.forName(dpmsClassName); Constructor constructor = serviceClass.getConstructor(Context.class); Constructor<?> constructor = serviceClass.getConstructor(Context.class); mService = (BaseIDevicePolicyManager) constructor.newInstance(context); mService = (BaseIDevicePolicyManager) constructor.newInstance(context); } catch (Exception e) { } catch (Exception e) { throw new IllegalStateException( throw new IllegalStateException( Loading @@ -655,6 +661,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } } } /** Sets the {@link DevicePolicySafetyChecker}. */ public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) { mService.setDevicePolicySafetyChecker(safetyChecker); } @Override @Override public void onStart() { public void onStart() { publishBinderService(Context.DEVICE_POLICY_SERVICE, mService); publishBinderService(Context.DEVICE_POLICY_SERVICE, mService); Loading Loading @@ -953,6 +964,38 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } } } @Override public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) { Slog.i(LOG_TAG, "Setting DevicePolicySafetyChecker as " + safetyChecker.getClass()); mSafetyChecker = safetyChecker; } /** * Checks if the feature is supported and it's safe to execute the given {@code operation}. * * <p>Typically called at the beginning of each API method as: * * <pre><code> * * if (!canExecute(operation, permission)) return; * * </code></pre> * * @return {@code true} when it's safe to execute, {@code false} when the feature is not * supported or the caller does not have the given {@code requiredPermission}. * * @throws UnsafeStateException if it's not safe to execute the operation. */ boolean canExecute(@DevicePolicyOperation int operation, @NonNull String requiredPermission) { if (!mHasFeature && !hasCallingPermission(requiredPermission)) { return false; } if (mSafetyChecker == null || mSafetyChecker.isDevicePolicyOperationSafe(operation)) { return true; } throw mSafetyChecker.newUnsafeStateException(operation); } /** /** * Unit test will subclass it to inject mocks. * Unit test will subclass it to inject mocks. */ */ Loading Loading @@ -4760,9 +4803,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override @Override public void lockNow(int flags, boolean parent) { public void lockNow(int flags, boolean parent) { if (!mHasFeature && !hasCallingPermission(permission.LOCK_DEVICE)) { if (!canExecute(DevicePolicyManager.OPERATION_LOCK_NOW, permission.LOCK_DEVICE)) { return; return; } } final CallerIdentity caller = getCallerIdentity(); final CallerIdentity caller = getCallerIdentity(); final int callingUserId = caller.getUserId(); final int callingUserId = caller.getUserId(); Loading Loading @@ -8554,6 +8598,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pw.printf("mIsWatch=%b\n", mIsWatch); pw.printf("mIsWatch=%b\n", mIsWatch); pw.printf("mIsAutomotive=%b\n", mIsAutomotive); pw.printf("mIsAutomotive=%b\n", mIsAutomotive); pw.printf("mHasTelephonyFeature=%b\n", mHasTelephonyFeature); pw.printf("mHasTelephonyFeature=%b\n", mHasTelephonyFeature); String safetyChecker = mSafetyChecker == null ? "N/A" : mSafetyChecker.getClass().getName(); pw.printf("mSafetyChecker=%b\n", safetyChecker); pw.decreaseIndent(); pw.decreaseIndent(); } } Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +21 −0 Original line number Original line Diff line number Diff line Loading @@ -122,6 +122,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executor; // TODO(b/172376923) - add CarDevicePolicyManager examples below (or remove reference to it). /** /** * Public interface for managing policies enforced on a device. Most clients of this class must be * Public interface for managing policies enforced on a device. Most clients of this class must be * registered with the system as a <a href="{@docRoot}guide/topics/admin/device-admin.html">device * registered with the system as a <a href="{@docRoot}guide/topics/admin/device-admin.html">device Loading @@ -130,6 +131,13 @@ import java.util.concurrent.Executor; * for that method specifies that it is restricted to either device or profile owners. Any * for that method specifies that it is restricted to either device or profile owners. Any * application calling an api may only pass as an argument a device administrator component it * application calling an api may only pass as an argument a device administrator component it * owns. Otherwise, a {@link SecurityException} will be thrown. * owns. Otherwise, a {@link SecurityException} will be thrown. * * <p><b>Note: </b>on * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds}, some methods can * throw an {@link UnsafeStateException} exception (for example, if the vehicle is moving), so * callers running on automotive builds should wrap every method call under the methods provided by * {@code android.car.admin.CarDevicePolicyManager}. * * <div class="special reference"> * <div class="special reference"> * <h3>Developer Guides</h3> * <h3>Developer Guides</h3> * <p> * <p> Loading Loading @@ -2445,6 +2453,19 @@ public class DevicePolicyManager { @Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE) public @interface PersonalAppsSuspensionReason {} public @interface PersonalAppsSuspensionReason {} /** @hide */ // TODO(b/172376923): make it TestApi public static final int OPERATION_LOCK_NOW = 1; // TODO(b/172376923) - add all operations /** @hide */ @IntDef(prefix = "OPERATION_", value = { OPERATION_LOCK_NOW, }) @Retention(RetentionPolicy.SOURCE) public static @interface DevicePolicyOperation { } /** /** * Return true if the given administrator component is currently active (enabled) in the system. * Return true if the given administrator component is currently active (enabled) in the system. * * Loading
core/java/android/app/admin/DevicePolicySafetyChecker.java 0 → 100644 +42 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2020 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 android.app.admin; import android.annotation.NonNull; import android.app.admin.DevicePolicyManager.DevicePolicyOperation; /** * Interface responsible to check if a {@link DevicePolicyManager} API can be safely executed. * * @hide */ public interface DevicePolicySafetyChecker { /** * Returns whether the given {@code operation} can be safely executed at the moment. */ default boolean isDevicePolicyOperationSafe(@DevicePolicyOperation int operation) { return true; } /** * Returns a new exception for when the given {@code operation} cannot be safely executed. */ @NonNull default UnsafeStateException newUnsafeStateException(@DevicePolicyOperation int operation) { return new UnsafeStateException(operation); } }
core/java/android/app/admin/UnsafeStateException.java 0 → 100644 +76 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2020 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 android.app.admin; import android.annotation.NonNull; import android.app.admin.DevicePolicyManager.DevicePolicyOperation; import android.os.Parcel; import android.os.Parcelable; /** * Exception thrown when a {@link DevicePolicyManager} operation failed because it was not safe * to be executed at that moment. * * <p>For example, it can be thrown on * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive devices} when the vehicle * is moving. * * @hide */ // TODO(b/172376923): make it public @SuppressWarnings("serial") public final class UnsafeStateException extends IllegalStateException implements Parcelable { private final @DevicePolicyOperation int mOperation; /** @hide */ public UnsafeStateException(@DevicePolicyOperation int operation) { super(); mOperation = operation; } /** @hide */ // TODO(b/172376923): make it TestApi public @DevicePolicyOperation int getOperation() { return mOperation; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mOperation); } @NonNull public static final Creator<UnsafeStateException> CREATOR = new Creator<UnsafeStateException>() { @Override public UnsafeStateException createFromParcel(Parcel source) { return new UnsafeStateException(source.readInt()); } @Override public UnsafeStateException[] newArray(int size) { return new UnsafeStateException[size]; } }; }
services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java +15 −0 Original line number Original line Diff line number Diff line Loading @@ -15,8 +15,10 @@ */ */ package com.android.server.devicepolicy; package com.android.server.devicepolicy; import android.app.admin.DevicePolicySafetyChecker; import android.app.admin.IDevicePolicyManager; import android.app.admin.IDevicePolicyManager; import android.content.ComponentName; import android.content.ComponentName; import android.util.Slog; import com.android.server.SystemService; import com.android.server.SystemService; Loading @@ -30,6 +32,9 @@ import com.android.server.SystemService; * should be added here to avoid build breakage in downstream branches. * should be added here to avoid build breakage in downstream branches. */ */ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { private static final String TAG = BaseIDevicePolicyManager.class.getSimpleName(); /** /** * To be called by {@link DevicePolicyManagerService#Lifecycle} during the various boot phases. * To be called by {@link DevicePolicyManagerService#Lifecycle} during the various boot phases. * * Loading @@ -55,6 +60,16 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { */ */ abstract void handleStopUser(int userId); abstract void handleStopUser(int userId); /** * Sets the {@link DevicePolicySafetyChecker}. * * <p>Currently, it's called only by {@code SystemServer} on * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds} */ public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) { Slog.w(TAG, "setDevicePolicySafetyChecker() not implemented by " + getClass()); } public void clearSystemUpdatePolicyFreezePeriodRecord() { public void clearSystemUpdatePolicyFreezePeriodRecord() { } } Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +49 −3 Original line number Original line Diff line number Diff line Loading @@ -135,9 +135,11 @@ import android.app.admin.DeviceAdminReceiver; import android.app.admin.DevicePolicyCache; import android.app.admin.DevicePolicyCache; import android.app.admin.DevicePolicyEventLogger; import android.app.admin.DevicePolicyEventLogger; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager.DevicePolicyOperation; import android.app.admin.DevicePolicyManager.PasswordComplexity; import android.app.admin.DevicePolicyManager.PasswordComplexity; import android.app.admin.DevicePolicyManager.PersonalAppsSuspensionReason; import android.app.admin.DevicePolicyManager.PersonalAppsSuspensionReason; import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.DevicePolicySafetyChecker; import android.app.admin.DeviceStateCache; import android.app.admin.DeviceStateCache; import android.app.admin.FactoryResetProtectionPolicy; import android.app.admin.FactoryResetProtectionPolicy; import android.app.admin.NetworkEvent; import android.app.admin.NetworkEvent; Loading @@ -148,6 +150,7 @@ import android.app.admin.SecurityLog.SecurityEvent; import android.app.admin.StartInstallingUpdateCallback; import android.app.admin.StartInstallingUpdateCallback; import android.app.admin.SystemUpdateInfo; import android.app.admin.SystemUpdateInfo; import android.app.admin.SystemUpdatePolicy; import android.app.admin.SystemUpdatePolicy; import android.app.admin.UnsafeStateException; import android.app.backup.IBackupManager; import android.app.backup.IBackupManager; import android.app.trust.TrustManager; import android.app.trust.TrustManager; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal; Loading Loading @@ -634,6 +637,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @VisibleForTesting @VisibleForTesting final TransferOwnershipMetadataManager mTransferOwnershipMetadataManager; final TransferOwnershipMetadataManager mTransferOwnershipMetadataManager; @Nullable private DevicePolicySafetyChecker mSafetyChecker; public static final class Lifecycle extends SystemService { public static final class Lifecycle extends SystemService { private BaseIDevicePolicyManager mService; private BaseIDevicePolicyManager mService; Loading @@ -645,8 +651,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { dpmsClassName = DevicePolicyManagerService.class.getName(); dpmsClassName = DevicePolicyManagerService.class.getName(); } } try { try { Class serviceClass = Class.forName(dpmsClassName); Class<?> serviceClass = Class.forName(dpmsClassName); Constructor constructor = serviceClass.getConstructor(Context.class); Constructor<?> constructor = serviceClass.getConstructor(Context.class); mService = (BaseIDevicePolicyManager) constructor.newInstance(context); mService = (BaseIDevicePolicyManager) constructor.newInstance(context); } catch (Exception e) { } catch (Exception e) { throw new IllegalStateException( throw new IllegalStateException( Loading @@ -655,6 +661,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } } } /** Sets the {@link DevicePolicySafetyChecker}. */ public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) { mService.setDevicePolicySafetyChecker(safetyChecker); } @Override @Override public void onStart() { public void onStart() { publishBinderService(Context.DEVICE_POLICY_SERVICE, mService); publishBinderService(Context.DEVICE_POLICY_SERVICE, mService); Loading Loading @@ -953,6 +964,38 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } } } @Override public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) { Slog.i(LOG_TAG, "Setting DevicePolicySafetyChecker as " + safetyChecker.getClass()); mSafetyChecker = safetyChecker; } /** * Checks if the feature is supported and it's safe to execute the given {@code operation}. * * <p>Typically called at the beginning of each API method as: * * <pre><code> * * if (!canExecute(operation, permission)) return; * * </code></pre> * * @return {@code true} when it's safe to execute, {@code false} when the feature is not * supported or the caller does not have the given {@code requiredPermission}. * * @throws UnsafeStateException if it's not safe to execute the operation. */ boolean canExecute(@DevicePolicyOperation int operation, @NonNull String requiredPermission) { if (!mHasFeature && !hasCallingPermission(requiredPermission)) { return false; } if (mSafetyChecker == null || mSafetyChecker.isDevicePolicyOperationSafe(operation)) { return true; } throw mSafetyChecker.newUnsafeStateException(operation); } /** /** * Unit test will subclass it to inject mocks. * Unit test will subclass it to inject mocks. */ */ Loading Loading @@ -4760,9 +4803,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override @Override public void lockNow(int flags, boolean parent) { public void lockNow(int flags, boolean parent) { if (!mHasFeature && !hasCallingPermission(permission.LOCK_DEVICE)) { if (!canExecute(DevicePolicyManager.OPERATION_LOCK_NOW, permission.LOCK_DEVICE)) { return; return; } } final CallerIdentity caller = getCallerIdentity(); final CallerIdentity caller = getCallerIdentity(); final int callingUserId = caller.getUserId(); final int callingUserId = caller.getUserId(); Loading Loading @@ -8554,6 +8598,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pw.printf("mIsWatch=%b\n", mIsWatch); pw.printf("mIsWatch=%b\n", mIsWatch); pw.printf("mIsAutomotive=%b\n", mIsAutomotive); pw.printf("mIsAutomotive=%b\n", mIsAutomotive); pw.printf("mHasTelephonyFeature=%b\n", mHasTelephonyFeature); pw.printf("mHasTelephonyFeature=%b\n", mHasTelephonyFeature); String safetyChecker = mSafetyChecker == null ? "N/A" : mSafetyChecker.getClass().getName(); pw.printf("mSafetyChecker=%b\n", safetyChecker); pw.decreaseIndent(); pw.decreaseIndent(); } } Loading