summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--api/system-current.txt1
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java30
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl1
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java15
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/values/strings.xml1
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java54
8 files changed, 102 insertions, 7 deletions
diff --git a/api/current.txt b/api/current.txt
index 44cbe7b..75fb910 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5801,6 +5801,7 @@ package android.app.admin {
field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
field public static final java.lang.String ACTION_SYSTEM_UPDATE_POLICY_CHANGED = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED";
+ field public static final int DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3
field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4
diff --git a/api/system-current.txt b/api/system-current.txt
index 9d3a3c9..1386e4c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5907,6 +5907,7 @@ package android.app.admin {
field public static final java.lang.String ACTION_SET_PROFILE_OWNER = "android.app.action.SET_PROFILE_OWNER";
field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
field public static final java.lang.String ACTION_SYSTEM_UPDATE_POLICY_CHANGED = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED";
+ field public static final int DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3
field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 35b8a8e..9e2da61 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1635,6 +1635,23 @@ public class DevicePolicyManager {
}
/**
+ * Queries whether {@link #DO_NOT_ASK_CREDENTIALS_ON_BOOT} flag is set.
+ *
+ * @return true if DO_NOT_ASK_CREDENTIALS_ON_BOOT flag is set.
+ * @hide
+ */
+ public boolean getDoNotAskCredentialsOnBoot() {
+ if (mService != null) {
+ try {
+ return mService.getDoNotAskCredentialsOnBoot();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to call getDoNotAskCredentialsOnBoot()", e);
+ }
+ }
+ return false;
+ }
+
+ /**
* Setting this to a value greater than zero enables a built-in policy
* that will perform a device wipe after too many incorrect
* device-unlock passwords have been entered. This built-in policy combines
@@ -1711,6 +1728,16 @@ public class DevicePolicyManager {
public static final int RESET_PASSWORD_REQUIRE_ENTRY = 0x0001;
/**
+ * Flag for {@link #resetPassword}: don't ask for user credentials on device boot.
+ * If the flag is set, the device can be booted without asking for user password.
+ * The absence of this flag does not change the current boot requirements. This flag
+ * can be set by the device owner only. If the app is not the device owner, the flag
+ * is ignored. Once the flag is set, it cannot be reverted back without resetting the
+ * device to factory defaults.
+ */
+ public static final int DO_NOT_ASK_CREDENTIALS_ON_BOOT = 0x0002;
+
+ /**
* Force a new device unlock password (the password needed to access the
* entire device, not for individual accounts) on the user. This takes
* effect immediately.
@@ -1733,7 +1760,8 @@ public class DevicePolicyManager {
* <p>Calling this from a managed profile will throw a security exception.
*
* @param password The new password for the user. Null or empty clears the password.
- * @param flags May be 0 or {@link #RESET_PASSWORD_REQUIRE_ENTRY}.
+ * @param flags May be 0 or combination of {@link #RESET_PASSWORD_REQUIRE_ENTRY} and
+ * {@link #DO_NOT_ASK_CREDENTIALS_ON_BOOT}.
* @return Returns true if the password was applied, or false if it is
* not acceptable for the current constraints.
*/
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 48ed45b..1f7498e 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -224,4 +224,5 @@ interface IDevicePolicyManager {
boolean setKeyguardEnabledState(in ComponentName admin, boolean enabled);
void setStatusBarEnabledState(in ComponentName who, boolean enabled);
+ boolean getDoNotAskCredentialsOnBoot();
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index aa60eba..1096e34 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -24,7 +24,6 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.RemoteException;
@@ -32,7 +31,6 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.os.UserManager;
import android.os.storage.IMountService;
import android.os.storage.StorageManager;
import android.provider.Settings;
@@ -544,8 +542,7 @@ public class LockPatternUtils {
// Update the device encryption password.
if (userId == UserHandle.USER_OWNER
&& LockPatternUtils.isDeviceEncryptionEnabled()) {
- final boolean required = isCredentialRequiredToDecrypt(true);
- if (!required) {
+ if (!shouldEncryptWithCredentials(true)) {
clearEncryptionPassword();
} else {
String stringPattern = patternToString(pattern);
@@ -759,7 +756,7 @@ public class LockPatternUtils {
// Update the device encryption password.
if (userHandle == UserHandle.USER_OWNER
&& LockPatternUtils.isDeviceEncryptionEnabled()) {
- if (!isCredentialRequiredToDecrypt(true)) {
+ if (!shouldEncryptWithCredentials(true)) {
clearEncryptionPassword();
} else {
boolean numeric = computedQuality
@@ -1238,4 +1235,12 @@ public class LockPatternUtils {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, required ? 1 : 0);
}
+
+ private boolean isDoNotAskCredentialsOnBootSet() {
+ return mDevicePolicyManager.getDoNotAskCredentialsOnBoot();
+ }
+
+ private boolean shouldEncryptWithCredentials(boolean defaultValue) {
+ return isCredentialRequiredToDecrypt(defaultValue) && !isDoNotAskCredentialsOnBootSet();
+ }
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8f4d9a3..1f529ca 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2404,6 +2404,12 @@
android:description="@string/permdesc_bindCarrierConfigService"
android:protectionLevel="signature|system" />
+ <!-- Allows an application to query whether DO_NOT_ASK_CREDENTIALS_ON_BOOT
+ flag is set.
+ @hide -->
+ <permission android:name="android.permission.QUERY_DO_NOT_ASK_CREDENTIALS_ON_BOOT"
+ android:protectionLevel="signature" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7123cc0..6f554f0 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1302,7 +1302,6 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_sdcardWrite" product="default">Allows the app to write to the SD card.</string>
-
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_use_sip">make/receive SIP calls</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index bc0910e..c2e8ccc 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -160,6 +160,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private static final String ATTR_ENABLED = "enabled";
+ private static final String DO_NOT_ASK_CREDENTIALS_ON_BOOT_XML =
+ "do-not-ask-credentials-on-boot";
+
private static final int REQUEST_EXPIRE_PASSWORD = 5571;
private static final long MS_PER_DAY = 86400 * 1000;
@@ -307,6 +310,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
String mDelegatedCertInstallerPackage;
+ boolean doNotAskCredentialsOnBoot = false;
+
public DevicePolicyData(int userHandle) {
mUserHandle = userHandle;
}
@@ -1456,6 +1461,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
out.endTag(null, TAG_STATUS_BAR);
}
+ if (policy.doNotAskCredentialsOnBoot) {
+ out.startTag(null, DO_NOT_ASK_CREDENTIALS_ON_BOOT_XML);
+ out.endTag(null, DO_NOT_ASK_CREDENTIALS_ON_BOOT_XML);
+ }
+
out.endTag(null, "policies");
out.endDocument();
@@ -1581,6 +1591,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
policy.mStatusBarEnabledState = Boolean.parseBoolean(
parser.getAttributeValue(null, ATTR_ENABLED));
XmlUtils.skipCurrentTag(parser);
+ } else if (DO_NOT_ASK_CREDENTIALS_ON_BOOT_XML.equals(tag)) {
+ policy.doNotAskCredentialsOnBoot = true;
} else {
Slog.w(LOG_TAG, "Unknown tag: " + tag);
XmlUtils.skipCurrentTag(parser);
@@ -2840,6 +2852,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return false;
}
+ boolean callerIsDeviceOwnerAdmin = isCallerDeviceOwnerOrInitializer(callingUid);
+ boolean doNotAskCredentialsOnBoot =
+ (flags & DevicePolicyManager.DO_NOT_ASK_CREDENTIALS_ON_BOOT) != 0;
+ if (callerIsDeviceOwnerAdmin && doNotAskCredentialsOnBoot) {
+ setDoNotAskCredentialsOnBoot();
+ }
+
// Don't do this with the lock held, because it is going to call
// back in to the service.
long ident = Binder.clearCallingIdentity();
@@ -2868,6 +2887,25 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return true;
}
+ private void setDoNotAskCredentialsOnBoot() {
+ synchronized (this) {
+ DevicePolicyData policyData = getUserData(UserHandle.USER_OWNER);
+ if (!policyData.doNotAskCredentialsOnBoot) {
+ policyData.doNotAskCredentialsOnBoot = true;
+ saveSettingsLocked(UserHandle.USER_OWNER);
+ }
+ }
+ }
+
+ public boolean getDoNotAskCredentialsOnBoot() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.QUERY_DO_NOT_ASK_CREDENTIALS_ON_BOOT, null);
+ synchronized (this) {
+ DevicePolicyData policyData = getUserData(UserHandle.USER_OWNER);
+ return policyData.doNotAskCredentialsOnBoot;
+ }
+ }
+
public void setMaximumTimeToLock(ComponentName who, long timeMs) {
if (!mHasFeature) {
return;
@@ -6036,4 +6074,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return mDeviceOwner.getSystemUpdatePolicy();
}
}
+
+ /**
+ * Checks if the caller of the method is the device owner app or device initialization app.
+ *
+ * @param callerUid UID of the caller.
+ * @return true if the caller is the device owner app or device initializer.
+ */
+ private boolean isCallerDeviceOwnerOrInitializer(int callerUid) {
+ String[] pkgs = mContext.getPackageManager().getPackagesForUid(callerUid);
+ for (String pkg : pkgs) {
+ if (isDeviceOwner(pkg) || isDeviceInitializer(pkg)) {
+ return true;
+ }
+ }
+ return false;
+ }
}