API changes to support encryption in DPM

* New uses-policies value
* Definitions for storage domain and encryption status
* API to get and set encryption status
* Intent to launch encryption changes
* Both new calls bottom out in the DPM service and are suitable for
  a device that does not support encryption.

NOTE: Nobody should use ACTION_START_ENCRYPTION yet.  It needs a receiver
  to be built in Settings (different CL).

Change-Id: I2ae193bedbec59f6ba46c0ec7de12ecf321e5803
This commit is contained in:
Andy Stadler
2011-01-12 14:59:52 -08:00
parent 7cc5e1d548
commit 7b0f8f08ac
6 changed files with 268 additions and 2 deletions

View File

@@ -37232,6 +37232,17 @@
visibility="public"
>
</field>
<field name="USES_ENCRYPTED_STORAGE"
type="int"
transient="false"
volatile="false"
value="7"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="USES_POLICY_EXPIRE_PASSWORD"
type="int"
transient="false"
@@ -37795,6 +37806,19 @@
<parameter name="admin" type="android.content.ComponentName">
</parameter>
</method>
<method name="getStorageEncryption"
return="int"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="admin" type="android.content.ComponentName">
</parameter>
</method>
<method name="hasGrantedPolicy"
return="boolean"
abstract="false"
@@ -38070,6 +38094,21 @@
<parameter name="quality" type="int">
</parameter>
</method>
<method name="setStorageEncryption"
return="int"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="admin" type="android.content.ComponentName">
</parameter>
<parameter name="encrypt" type="boolean">
</parameter>
</method>
<method name="wipeData"
return="void"
abstract="false"
@@ -38105,6 +38144,72 @@
visibility="public"
>
</field>
<field name="ACTION_START_ENCRYPTION"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;android.app.action.START_ENCRYPTION&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="ENCRYPTION_STATUS_ACTIVATING"
type="int"
transient="false"
volatile="false"
value="3"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="ENCRYPTION_STATUS_ACTIVE"
type="int"
transient="false"
volatile="false"
value="4"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="ENCRYPTION_STATUS_INACTIVE"
type="int"
transient="false"
volatile="false"
value="1"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="ENCRYPTION_STATUS_REQUESTED"
type="int"
transient="false"
volatile="false"
value="2"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="ENCRYPTION_STATUS_UNSUPPORTED"
type="int"
transient="false"
volatile="false"
value="0"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="EXTRA_ADD_EXPLANATION"
type="java.lang.String"
transient="false"

View File

@@ -121,6 +121,14 @@ public final class DeviceAdminInfo implements Parcelable {
*/
public static final int USES_POLICY_EXPIRE_PASSWORD = 6;
/**
* A type of policy that this device admin can use: require encryption of stored data.
*
* <p>To control this policy, the device admin must have a "encrypted-storage"
* tag in the "uses-policies" section of its meta-data.
*/
public static final int USES_ENCRYPTED_STORAGE = 7;
/** @hide */
public static class PolicyInfo {
public final int ident;
@@ -162,6 +170,9 @@ public final class DeviceAdminInfo implements Parcelable {
sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_EXPIRE_PASSWORD, "expire-password",
com.android.internal.R.string.policylab_expirePassword,
com.android.internal.R.string.policydesc_expirePassword));
sPoliciesDisplayOrder.add(new PolicyInfo(USES_ENCRYPTED_STORAGE, "encrypted-storage",
com.android.internal.R.string.policylab_encryptedStorage,
com.android.internal.R.string.policydesc_encryptedStorage));
for (int i=0; i<sPoliciesDisplayOrder.size(); i++) {
PolicyInfo pi = sPoliciesDisplayOrder.get(i);
@@ -352,7 +363,8 @@ public final class DeviceAdminInfo implements Parcelable {
* the given policy control. The possible policy identifier inputs are:
* {@link #USES_POLICY_LIMIT_PASSWORD}, {@link #USES_POLICY_WATCH_LOGIN},
* {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK},
* {@link #USES_POLICY_WIPE_DATA}, {@link #USES_POLICY_SETS_GLOBAL_PROXY}.
* {@link #USES_POLICY_WIPE_DATA}, {@link #USES_POLICY_SETS_GLOBAL_PROXY},
* {@link #USES_POLICY_EXPIRE_PASSWORD}, {@link #USES_ENCRYPTED_STORAGE}.
*/
public boolean usesPolicy(int policyIdent) {
return (mUsesPolicies & (1<<policyIdent)) != 0;

View File

@@ -1092,6 +1092,112 @@ public class DevicePolicyManager {
return null;
}
/**
* Result code for {@link #setStorageEncryption} and {@link #getStorageEncryption}:
* indicating that encryption is not supported.
*/
public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0;
/**
* Result code for {@link #setStorageEncryption} and {@link #getStorageEncryption}:
* indicating that encryption is supported, but is not currently active.
*/
public static final int ENCRYPTION_STATUS_INACTIVE = 1;
/**
* Result code for {@link #setStorageEncryption} and {@link #getStorageEncryption}:
* indicating that encryption is not currently active, but has been requested.
*/
public static final int ENCRYPTION_STATUS_REQUESTED = 2;
/**
* Result code for {@link #setStorageEncryption} and {@link #getStorageEncryption}:
* indicating that encryption is not currently active, but is currently
* being activated. This is only reported by devices that support
* encryption of data and only when the storage is currently
* undergoing a process of becoming encrypted. A device that must reboot and/or wipe data
* to become encrypted will never return this value.
*/
public static final int ENCRYPTION_STATUS_ACTIVATING = 3;
/**
* Result code for {@link #setStorageEncryption} and {@link #getStorageEncryption}:
* indicating that encryption is active.
*/
public static final int ENCRYPTION_STATUS_ACTIVE = 4;
/**
* Activity action: begin the process of encrypting data on the device. This activity should
* be launched after using {@link #setStorageEncryption} to request encryption be activated.
* After resuming from this activity, use {@link #getStorageEncryption}
* to check encryption status. However, on some devices this activity may never return, as
* it may trigger a reboot and in some cases a complete data wipe of the device.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_START_ENCRYPTION
= "android.app.action.START_ENCRYPTION";
/**
* Called by an application that is administering the device to
* request that the storage system be encrypted. Depending
* on the returned status code, the caller may proceed in different
* ways. If the result is {@link #ENCRYPTION_STATUS_UNSUPPORTED}, the
* storage system does not support encryption. If the
* result is {@link #ENCRYPTION_STATUS_REQUESTED}, use {@link
* #ACTION_START_ENCRYPTION} to begin the process of encrypting or decrypting the
* storage. If the result is {@link #ENCRYPTION_STATUS_ACTIVATING} or
* {@link #ENCRYPTION_STATUS_ACTIVE}, no further action is required.
*
* <p>When multiple device administrators attempt to control device
* encryption, the most secure, supported setting will always be
* used. If any device administrator requests device encryption,
* it will be enabled; Conversely, if a device administrator
* attempts to disable device encryption while another
* device administrator has enabled it, the call to disable will
* fail (most commonly returning {@link #ENCRYPTION_STATUS_ACTIVE}).
*
* <p>This policy controls encryption of the secure (application data) storage area. Data
* written to other areas (e.g. the directory returned by
* {@link android.os.Environment#getExternalStorageDirectory()} may or may not be encrypted.
*
* <p>Important Note: On some devices, it is possible to encrypt storage without requiring
* the user to create a device PIN or Password. In this case, the storage is encrypted, but
* the encryption key may not be fully secured. For maximum security, the administrator should
* also require (and check for) a pattern, PIN, or password.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param encrypt true to request encryption, false to release any previous request
* @return current status of encryption
*/
public int setStorageEncryption(ComponentName admin, boolean encrypt) {
if (mService != null) {
try {
return mService.setStorageEncryption(admin, encrypt);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return ENCRYPTION_STATUS_UNSUPPORTED;
}
/**
* Called by an application that is administering the device to
* determine the encryption status of a specific storage system.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @return current status of encryption
*/
public int getStorageEncryption(ComponentName admin) {
if (mService != null) {
try {
return mService.getStorageEncryption(admin);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return ENCRYPTION_STATUS_UNSUPPORTED;
}
/**
* @hide
*/

View File

@@ -74,7 +74,10 @@ interface IDevicePolicyManager {
ComponentName setGlobalProxy(in ComponentName admin, String proxySpec, String exclusionList);
ComponentName getGlobalProxyAdmin();
int setStorageEncryption(in ComponentName who, boolean encrypt);
int getStorageEncryption(in ComponentName who);
void setActiveAdmin(in ComponentName policyReceiver, boolean refreshing);
boolean isAdminActive(in ComponentName policyReceiver);
List<ComponentName> getActiveAdmins();

View File

@@ -1411,6 +1411,11 @@
<!-- Description of policy access to enforce password expiration [CHAR LIMIT=110]-->
<string name="policydesc_expirePassword">Control how long before lockscreen password needs to be
changed</string>
<!-- Title of policy access to require encrypted storage [CHAR LIMIT=30]-->
<string name="policylab_encryptedStorage">Set storage encryption</string>
<!-- Description of policy access to require encrypted storage [CHAR LIMIT=110]-->
<string name="policydesc_encryptedStorage">Require that stored application data be encrypted
</string>
<!-- The order of these is important, don't reorder without changing Contacts.java --> <skip />
<!-- Phone number types from android.provider.Contacts. This could be used when adding a new phone number for a contact, for example. -->

View File

@@ -1822,6 +1822,41 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
exclusionList);
}
/**
* Set the storage encryption request.
*/
public int setStorageEncryption(ComponentName who, boolean encrypt) {
synchronized (this) {
// Check for permissions
if (who == null) {
throw new NullPointerException("ComponentName is null");
}
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_ENCRYPTED_STORAGE);
// TODO: (1) Record the value for the admin so it's sticky
// TODO: (2) Compute "max" for all admins (if any admin requests encryption, then
// we enable it.
// TODO: (3) Work with filesystem / mount service to start/stop encryption
return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
}
}
/**
* Get the current storage encryption status for a given storage domain.
*/
public int getStorageEncryption(ComponentName who) {
synchronized (this) {
// Check for permissions if a particular caller is specified
if (who != null) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_ENCRYPTED_STORAGE);
}
// TODO: Work with filesystem / mount service to query encryption status
return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
}
}
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)