Add encryption status controls

* Enable, disable, and activate encryption
* Report encryption status

Change-Id: Ia76cf6033fe00ebdfd3369f8123f5d1ec109f3a9
diff --git a/samples/ApiDemos/res/layout/device_admin_sample.xml b/samples/ApiDemos/res/layout/device_admin_sample.xml
index a7cb0d9..78d7c4c 100644
--- a/samples/ApiDemos/res/layout/device_admin_sample.xml
+++ b/samples/ApiDemos/res/layout/device_admin_sample.xml
@@ -272,6 +272,48 @@
 
         </LinearLayout>
 
+        <!-- Encryption Status Controls -->
+        <LinearLayout
+            android:orientation="horizontal"
+            android:gravity="center"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" >
+
+            <Button android:id="@+id/encryption_enable_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/encryption_enable_label" />
+
+            <Button android:id="@+id/encryption_disable_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/encryption_disable_label" />
+
+            <Button android:id="@+id/encryption_activate_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/encryption_activate_label" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:gravity="center"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" >
+
+            <TextView android:id="@+id/encryption_status"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content" />
+
+            <Button android:id="@+id/encryption_update_status_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android_layout_gravity="east|center_vertical"
+                android:text="@string/update_encryption_status_label" />
+
+        </LinearLayout>
+
     </LinearLayout>
 
 </ScrollView>
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 0b2a42a..576ee4b 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -614,6 +614,11 @@
     <string name="proxylist_hint">No proxy for domain1,domain2</string>
     <string name="set_proxy_label">Set Global Proxy</string>
 
+    <string name="encryption_enable_label">Enable Encryption</string>
+    <string name="encryption_disable_label">Disable Encryption</string>
+    <string name="encryption_activate_label">Activate Encryption</string>
+    <string name="update_encryption_status_label">Update Status</string>
+
     <!-- ============================== -->
     <!--  app/voice recognition examples strings  -->
     <!-- ============================== -->
diff --git a/samples/ApiDemos/res/xml/device_admin_sample.xml b/samples/ApiDemos/res/xml/device_admin_sample.xml
index 432bbcd..f3ca22a 100644
--- a/samples/ApiDemos/res/xml/device_admin_sample.xml
+++ b/samples/ApiDemos/res/xml/device_admin_sample.xml
@@ -24,6 +24,7 @@
         <wipe-data />
         <set-global-proxy />
         <expire-password />
+        <encrypted-storage />
     </uses-policies>
 </device-admin>
 <!-- END_INCLUDE(meta_data) -->
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
index 06a2c19..559daea 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.java
@@ -141,7 +141,10 @@
      * all together; typically this code would appear in some separate class.
      */
     public static class Controller extends Activity {
-        static final int RESULT_ENABLE = 1;
+
+        static final int REQUEST_CODE_ENABLE_ADMIN = 1;
+        static final int REQUEST_CODE_START_ENCRYPTION = 2;
+
         private static final long MS_PER_MINUTE = 60*1000;
 
         DevicePolicyManager mDPM;
@@ -195,6 +198,12 @@
         private TextView mPasswordExpirationStatus;
         private Button mPasswordExpirationStatusButton;
 
+        private Button mEnableEncryptionButton;
+        private Button mDisableEncryptionButton;
+        private Button mActivateEncryptionButton;
+        private Button mEncryptionStatusButton;
+        private TextView mEncryptionStatus;
+
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
@@ -395,6 +404,16 @@
             mProxyList = (EditText) findViewById(R.id.proxylist);
             mProxyButton = (Button) findViewById(R.id.set_proxy);
             mProxyButton.setOnClickListener(mSetProxyListener);
+
+            mEnableEncryptionButton = (Button) findViewById(R.id.encryption_enable_button);
+            mEnableEncryptionButton.setOnClickListener(mEncryptionButtonListener);
+            mDisableEncryptionButton = (Button) findViewById(R.id.encryption_disable_button);
+            mDisableEncryptionButton.setOnClickListener(mEncryptionButtonListener);
+            mActivateEncryptionButton = (Button) findViewById(R.id.encryption_activate_button);
+            mActivateEncryptionButton.setOnClickListener(mEncryptionButtonListener);
+            mEncryptionStatusButton = (Button) findViewById(R.id.encryption_update_status_button);
+            mEncryptionStatusButton.setOnClickListener(mEncryptionButtonListener);
+            mEncryptionStatus = (TextView) findViewById(R.id.encryption_status);
         }
 
         void updateButtonStates() {
@@ -417,6 +436,10 @@
                 mForceLockButton.setEnabled(true);
                 mWipeDataButton.setEnabled(true);
                 mWipeAllDataButton.setEnabled(true);
+                mEnableEncryptionButton.setEnabled(true);
+                mDisableEncryptionButton.setEnabled(true);
+                mActivateEncryptionButton.setEnabled(true);
+                mEncryptionStatusButton.setEnabled(true);
             } else {
                 mEnableButton.setEnabled(true);
                 mDisableButton.setEnabled(false);
@@ -435,6 +458,10 @@
                 mForceLockButton.setEnabled(false);
                 mWipeDataButton.setEnabled(false);
                 mWipeAllDataButton.setEnabled(false);
+                mEnableEncryptionButton.setEnabled(false);
+                mDisableEncryptionButton.setEnabled(false);
+                mActivateEncryptionButton.setEnabled(false);
+                mEncryptionStatusButton.setEnabled(false);
             }
         }
 
@@ -622,13 +649,16 @@
         @Override
         protected void onActivityResult(int requestCode, int resultCode, Intent data) {
             switch (requestCode) {
-                case RESULT_ENABLE:
+                case REQUEST_CODE_ENABLE_ADMIN:
                     if (resultCode == Activity.RESULT_OK) {
                         Log.i(TAG, "Admin enabled!");
                     } else {
                         Log.i(TAG, "Admin enable FAILED!");
                     }
                     return;
+                case REQUEST_CODE_START_ENCRYPTION:
+                    updateEncryptionStatus();
+                    return;
             }
 
             super.onActivityResult(requestCode, resultCode, data);
@@ -642,7 +672,7 @@
                         mDeviceAdminSample);
                 intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                         "Additional text explaining why this needs to be added.");
-                startActivityForResult(intent, RESULT_ENABLE);
+                startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
             }
         };
 
@@ -801,5 +831,62 @@
             }
         };
 
+        private OnClickListener mEncryptionButtonListener = new OnClickListener() {
+            public void onClick(View v) {
+                int buttonId = v.getId();
+                if (buttonId == R.id.encryption_enable_button) {
+                    mDPM.setStorageEncryption(mDeviceAdminSample, true);
+                } else if (buttonId == R.id.encryption_disable_button) {
+                    mDPM.setStorageEncryption(mDeviceAdminSample, false);
+                } else if (buttonId == R.id.encryption_activate_button) {
+                    if (ActivityManager.isUserAMonkey()) {
+                        // Don't trust monkeys to do the right thing!
+                        AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
+                        builder.setMessage("You can't activate encryption, you're a monkey!");
+                        builder.setPositiveButton("I admit defeat", null);
+                        builder.show();
+                        return;
+                    }
+                    if (mDPM.getStorageEncryption(mDeviceAdminSample) ==
+                            DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED) {
+                        AlertDialog.Builder builder = new AlertDialog.Builder(Controller.this);
+                        builder.setMessage("Encryption is unsupported on this device.");
+                        builder.setPositiveButton("OK", null);
+                        builder.show();
+                        return;
+                    }
+                    // Launch the activity to activate encryption.  May or may not return!
+                    Intent intent = new Intent(DevicePolicyManager.ACTION_START_ENCRYPTION);
+                    startActivityForResult(intent, REQUEST_CODE_START_ENCRYPTION);
+                }
+
+                // In all cases, fall through to update status
+                updateEncryptionStatus();
+            }
+        };
+
+        private void updateEncryptionStatus() {
+            String newStatus = "unknown";
+            int newStatusCode = mDPM.getStorageEncryption(mDeviceAdminSample);
+            switch (newStatusCode) {
+                case DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED:
+                    newStatus = "unsupported";
+                    break;
+                case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE:
+                    newStatus = "inactive";
+                    break;
+                case DevicePolicyManager.ENCRYPTION_STATUS_REQUESTED:
+                    newStatus = "requested";
+                    break;
+                case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING:
+                    newStatus = "activating";
+                    break;
+                case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
+                    newStatus = "active";
+                    break;
+            }
+            mEncryptionStatus.setText(newStatus);
+        }
     }
 }
+