diff --git a/Android.mk b/Android.mk index 77d9cb2c980ea..026cd23fb89be 100644 --- a/Android.mk +++ b/Android.mk @@ -500,7 +500,10 @@ web_docs_sample_code_flags := \ -samplecode $(sample_dir)/XmlAdapters \ resources/samples/XmlAdapters "XML Adapters" \ -samplecode $(sample_dir)/TtsEngine \ - resources/samples/TtsEngine "Text To Speech Engine" + resources/samples/TtsEngine "Text To Speech Engine" \ + -samplecode $(sample_dir)/training/device-management-policy \ + resources/samples/training/device-management-policy "Device Management Policy" + ## SDK version identifiers used in the published docs # major[.minor] version for current SDK. (full releases only) diff --git a/docs/html/images/training/device-mgmt-activate-device-admin.png b/docs/html/images/training/device-mgmt-activate-device-admin.png new file mode 100755 index 0000000000000..1be1831e39c1a Binary files /dev/null and b/docs/html/images/training/device-mgmt-activate-device-admin.png differ diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js index d96bfde7add7b..779525a6d5342 100644 --- a/docs/html/resources/resources-data.js +++ b/docs/html/resources/resources-data.js @@ -507,6 +507,16 @@ var ANDROID_RESOURCES = [ en: 'An application that demonstrates how to create a live wallpaper and bundle it in an application that users can install on their devices.' } }, + { + tags: ['sample', 'new'], + path: 'samples/training/device-management-policy/index.html', + title: { + en: 'Device Policy Management' + }, + description: { + en: 'This is a security-aware sample application that demonstrates the enforcement of device administration policies on Android 2.2 or above platforms.' + } + }, { tags: ['sample'], path: 'samples/Home/index.html', diff --git a/docs/html/shareables/training/DeviceManagement.zip b/docs/html/shareables/training/DeviceManagement.zip new file mode 100644 index 0000000000000..9f7ec694af479 Binary files /dev/null and b/docs/html/shareables/training/DeviceManagement.zip differ diff --git a/docs/html/training/enterprise/device-management-policy.jd b/docs/html/training/enterprise/device-management-policy.jd new file mode 100644 index 0000000000000..52f0e37027bf0 --- /dev/null +++ b/docs/html/training/enterprise/device-management-policy.jd @@ -0,0 +1,220 @@ +page.title=Enhancing Security with Device Management Policies +parent.title=Developing Android Applications for the Enterprise +parent.link=index.html +@jd:body + + +
+
+ +

This lesson teaches you to

+
    +
  1. Define and Declare Your Policy
  2. +
  3. Create a Device Administration Receiver
  4. +
  5. Activate the Device Administrator
  6. +
  7. Implement the Device Policy Controller
  8. +
+ + +

You should also read

+ + +

Try it out

+ +
+ Download the sample +

DeviceManagement.zip

+
+ +
+
+ + +

Since Android 2.2 (API level 8), the Android platform offes system-level device management +capabilities through the Device Administration APIs.

+ +

In this lesson, you will learn how to create a security-aware application that manages access to +its content by enforcing device management policies. Specifically, the application can be configured +such that it ensures a screen-lock password of sufficient strength is set up before displaying +restricted content to the user.

+ + +

Define and Declare Your Policy

+ +

First, you need to define the kinds of policy to support at the functional level. Policies may +cover screen-lock password strength, expiration timeout, encryption, etc.

+ +

You must declare the selected policy set, which will be enforced by the application, in the +res/xml/device_admin.xml file. The Android manifest should also reference the +declared policy set.

+ +

Each declared policy corresponds to some number of related device policy methods in {@link +android.app.admin.DevicePolicyManager} (defining minimum password length and minimum number of +uppercase characters are two examples). If an application attempts to invoke methods whose +corresponding policy is not declared in the XML, this will result in a {@link +java.lang.SecurityException} at runtime. Other permissions, +such as force-lock, are available if the application intends to manage +other kinds of policy. As you'll see later, as part of the device administrator activation process, +the list of declared policies will be presented to the user on a system screen.

+ +

The following snippet declares the limit password policy in res/xml/device_admin.xml:

+ +
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-policies>
+        <limit-password />
+    </uses-policies>
+</device-admin>
+
+ +

Policy declaration XML referenced in Android manifest:

+ +
+<receiver android:name=".Policy$PolicyAdmin"
+    android:permission="android.permission.BIND_DEVICE_ADMIN">
+    <meta-data android:name="android.app.device_admin"
+        android:resource="@xml/device_admin" />
+    <intent-filter>
+        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+    </intent-filter>
+</receiver>
+
+ + +

Create a Device Administration Receiver

+ +

Create a Device Administration broadcast receiver, which gets notified of events related to the policies you’ve declared to support. An application can selectively override callback methods.

+ +

In the sample application, Device Admin, when the device administrator is deactivated by the +user, the configured policy is erased from the shared preference. You should consider implementing +business logic that is relevant to your use case. For example, the application might take some +actions to mitigate security risk by implementing some combination of deleting sensitive data on the +device, disabling remote synchronization, alerting an administrator, etc.

+ +

For the broadcast receiver to work, be sure to register it in the Android manifest as illustrated in the above snippet.

+ +
+public static class PolicyAdmin extends DeviceAdminReceiver {
+
+    @Override
+    public void onDisabled(Context context, Intent intent) {
+        // Called when the app is about to be deactivated as a device administrator.
+        // Deletes previously stored password policy.
+        super.onDisabled(context, intent);
+        SharedPreferences prefs = context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE);
+        prefs.edit().clear().commit();
+    }
+}
+
+ + +

Activate the Device Administrator

+ +

Before enforcing any policies, the user needs to manually activate the application as a device +administrator. The snippet below illustrates how to trigger the settings activity in which the +user can activate your application. It is good practice to include the explanatory text to highlight +to users why the application is requesting to be a device administrator, by specifying the +{@link android.app.admin.DevicePolicyManager#EXTRA_ADD_EXPLANATION} extra in the intent.

+ +
+ +

Figure 1. The user activation screen in which you can +provide a description of your device policies.

+
+ +
+if (!mPolicy.isAdminActive()) {
+
+    Intent activateDeviceAdminIntent =
+        new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
+
+    activateDeviceAdminIntent.putExtra(
+        DevicePolicyManager.EXTRA_DEVICE_ADMIN,
+        mPolicy.getPolicyAdmin());
+
+    // It is good practice to include the optional explanation text to
+    // explain to user why the application is requesting to be a device
+    // administrator. The system will display this message on the activation
+    // screen.
+    activateDeviceAdminIntent.putExtra(
+        DevicePolicyManager.EXTRA_ADD_EXPLANATION,
+        getResources().getString(R.string.device_admin_activation_message));
+
+    startActivityForResult(activateDeviceAdminIntent,
+        REQ_ACTIVATE_DEVICE_ADMIN);
+}
+
+ +

If the user chooses "Activate," the application becomes a device administrator and can begin +configuring and enforcing the policy.

+ +

The application also needs to be prepared to handle set back situations where the user abandons +the activation process by hitting the Cancel button, the Back key, or the Home key. Therefore, +{@link android.app.Activity#onResume onResume()} in the Policy Set Up Activity needs to have logic +to reevaluate the condition and present the Device Administrator Activation option to the user if +needed.

+ + +

Implement the Device Policy Controller

+ +

After the device administrator is activated successfully, the application then configures Device +Policy Manager with the requested policy. Keep in mind that new policies are being added to +Android with each release. It is appropriate to perform version checks in your application if using +new policies while supporting older versions of the platform. For example, the Password Minimum +Upper Case policy is only available with API level 11 (Honeycomb) and above. The following code +demonstrates how you can check the version at runtime.

+ +
+DevicePolicyManager mDPM = (DevicePolicyManager)
+        context.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ComponentName mPolicyAdmin = new ComponentName(context, PolicyAdmin.class);
+...
+mDPM.setPasswordQuality(mPolicyAdmin, PASSWORD_QUALITY_VALUES[mPasswordQuality]);
+mDPM.setPasswordMinimumLength(mPolicyAdmin, mPasswordLength);
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+    mDPM.setPasswordMinimumUpperCase(mPolicyAdmin, mPasswordMinUpperCase);
+}
+
+ +

At this point, the application is able to enforce the policy. While the application has no access +to the actual screen-lock password used, through the Device Policy Manager API it can determine +whether the existing password satisfies the required policy. If it turns out that the existing +screen-lock password is not sufficient, the device administration API does not automatically take +corrective action. It is the application’s responsibility to explicitly launch the system +password-change screen in the Settings app. For example:

+ +
+if (!mDPM.isActivePasswordSufficient()) {
+    ...
+    // Triggers password change screen in Settings.
+    Intent intent =
+        new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+    startActivity(intent);
+}
+
+ +

Normally, the user can select from one of the available lock mechanisms, such as None, Pattern, +PIN (numeric), or Password (alphanumeric). When a password policy is configured, those password +types that are weaker than those defined in the policy are disabled. For example, if the +“Numeric” password quality is configured, the user can select either PIN (numeric) or Password +(alphanumeric) password only.

+ +

Once the device is properly secured by setting up a proper screen-lock password, the application +allows access to the secured content.

+ +
+if (!mDPM.isAdminActive(..)) {
+    // Activates device administrator.
+    ...
+} else if (!mDPM.isActivePasswordSufficient()) {
+    // Launches password set-up screen in Settings.
+    ...
+} else {
+    // Grants access to secure content.
+    ...
+    startActivity(new Intent(context, SecureActivity.class));
+}
+
diff --git a/docs/html/training/enterprise/index.jd b/docs/html/training/enterprise/index.jd new file mode 100644 index 0000000000000..05bb29c5b55b6 --- /dev/null +++ b/docs/html/training/enterprise/index.jd @@ -0,0 +1,51 @@ +page.title=Developing Android Applications for the Enterprise + +trainingnavtop=true +startpage=true +next.title=Enhancing Security with Device Management Policies +next.link=device-management-policy.html + +@jd:body + +
+
+ + +

Dependencies and prerequisites

+ + + +

You should also read

+ + +

Try it out

+ +
+ Download the sample +

DeviceManagement.zip

+
+ +
+
+ + +

In this class, you'll learn APIs and techniques you can use when developing applications +for the enterprise.

+ + +

Lessons

+ + +
+
Enhancing Security with Device Management +Policies
+
In this lesson, you will learn how to create a security-aware application that manages +access to its content by enforcing device management policies
+