From e36087e5b6eeb92607f4ad5b3b1662bef9bafa4c Mon Sep 17 00:00:00 2001 From: Benjamin Franz Date: Tue, 7 Apr 2015 16:40:34 +0100 Subject: [PATCH] Introduce device owner API to disable the keyguard Let the device owner disable the keyguard to achieve undisturbed single use mode with multiple apps. Calling this API has no effect if a password has been set for the calling user. Bug: 19533026 Change-Id: I6b726b7f36efb669359e9da4b7e3db1f8031dad5 --- api/current.txt | 1 + api/system-current.txt | 1 + .../app/admin/DevicePolicyManager.java | 23 +++++++++++++++++++ .../app/admin/IDevicePolicyManager.aidl | 2 ++ .../DevicePolicyManagerService.java | 22 ++++++++++++++++++ 5 files changed, 49 insertions(+) diff --git a/api/current.txt b/api/current.txt index 0db2319f99a59..8f8fb9e368948 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5713,6 +5713,7 @@ package android.app.admin { method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String); method public void setKeyguardDisabledFeatures(android.content.ComponentName, int); + method public boolean setKeyguardEnabledState(android.content.ComponentName, boolean); method public void setLockTaskPackages(android.content.ComponentName, java.lang.String[]) throws java.lang.SecurityException; method public void setMasterVolumeMuted(android.content.ComponentName, boolean); method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int); diff --git a/api/system-current.txt b/api/system-current.txt index 9fd7b657c7c74..4acc818ab1f01 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5817,6 +5817,7 @@ package android.app.admin { method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String); method public void setKeyguardDisabledFeatures(android.content.ComponentName, int); + method public boolean setKeyguardEnabledState(android.content.ComponentName, boolean); method public void setLockTaskPackages(android.content.ComponentName, java.lang.String[]) throws java.lang.SecurityException; method public void setMasterVolumeMuted(android.content.ComponentName, boolean); method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index dd6443673c58f..a0a6c4cd678c4 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -4187,4 +4187,27 @@ public class DevicePolicyManager { } return null; } + + /** + * Called by a device owner to disable the keyguard altogether. + * + *

Setting the keyguard to disabled has the same effect as choosing "None" as the screen + * lock type. However, this call has no effect if a password, pin or pattern is currently set. + * If a password, pin or pattern is set after the keyguard was disabled, the keyguard stops + * being disabled. + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param enabled New state of the keyguard. + * + * @return {@code false} if attempting to disable the keyguard while a lock password was in + * place. {@code true} otherwise." + */ + public boolean setKeyguardEnabledState(ComponentName admin, boolean enabled) { + try { + return mService.setKeyguardEnabledState(admin, enabled); + } catch (RemoteException re) { + Log.w(TAG, "Failed talking with device policy service", re); + return false; + } + } } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 332d59ed5edae..131b99cb4e4a9 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -221,4 +221,6 @@ interface IDevicePolicyManager { void sendDeviceInitializerStatus(int statusCode, String description); void setOtaPolicy(in ComponentName who, in PersistableBundle policy); PersistableBundle getOtaPolicy(); + + boolean setKeyguardEnabledState(in ComponentName admin, boolean enabled); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 26c7130a8a3e6..c7d2b8687b9e5 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -5808,6 +5808,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + @Override + public boolean setKeyguardEnabledState(ComponentName who, boolean enabled) { + Preconditions.checkNotNull(who, "ComponentName is null"); + synchronized (this) { + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); + } + final int userId = UserHandle.getCallingUserId(); + LockPatternUtils utils = new LockPatternUtils(mContext); + + // disallow disabling the keyguard if a password is currently set + if (!enabled && utils.isSecure(userId)) { + return false; + } + long ident = Binder.clearCallingIdentity(); + try { + utils.setLockScreenDisabled(!enabled, userId); + } finally { + Binder.restoreCallingIdentity(ident); + } + return true; + } + /** * We need to update the internal state of whether a user has completed setup once. After * that, we ignore any changes that reset the Settings.Secure.USER_SETUP_COMPLETE changes