More work on the Crypt Keeper.

* Use the DPM to determine if we are encrypted.
* Fix misspelling (Comfirm -> Confirm).
* Animate to black when enabling encryption.
* Add holo droid background.
* Change the progress bar to indterminate.
* Display the percentage complete in the status line.
* Fixed bug 3388097. You will no longer have to unplug your device to start encryption. This line is intentionally long. I could make it shorter but I am proving a point: <magic>overflow: auto;</magic>.
* Actually hold onto the wakelock to prvent the device from sleeping.
* Implement onStop() as a orientation change can happen at boot. This will start the activity twice and there will be multiple handlers with messages.

Change-Id: Ia752d106c39e0d81431e856f8f500182e8ec1abd
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
index 5afc3f6..6f847f3 100644
--- a/src/com/android/settings/CryptKeeper.java
+++ b/src/com/android/settings/CryptKeeper.java
@@ -64,49 +64,20 @@
     private Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
-
             switch (msg.what) {
-
             case UPDATE_PROGRESS:
-                String state = SystemProperties.get("vold.encrypt_progress");
-
-                ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar);
-                progressBar.setProgress(0);
-
-                try {
-                    int progress = Integer.parseInt(state);
-                    progressBar.setProgress(progress);
-                } catch (Exception e) {
-                    Log.w(TAG, "Error parsing progress: " + e.toString());
-                }
-
-                // Check the status every 5 second
-                sendEmptyMessageDelayed(UPDATE_PROGRESS, 5000);
+                updateProgress();
                 break;
 
             case COOLDOWN:
-                TextView tv = (TextView) findViewById(R.id.status);
-                if (mCooldown <= 0) {
-                    // Re-enable the password entry
-                    EditText passwordEntry = (EditText) findViewById(R.id.passwordEntry);
-                    passwordEntry.setEnabled(true);
-
-                    tv.setText(R.string.try_again);
-
-                } else {
-
-                    CharSequence tempalte = getText(R.string.crypt_keeper_cooldown);
-                    tv.setText(TextUtils.expandTemplate(tempalte, Integer.toString(mCooldown)));
-
-                    mCooldown--;
-                    mHandler.sendEmptyMessageDelayed(COOLDOWN, 1000); // Tick every second
-                }
+                cooldown();
                 break;
             }
         }
     };
 
     private int mCooldown;
+    PowerManager.WakeLock mWakeLock;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -139,17 +110,71 @@
                 | StatusBarManager.DISABLE_SYSTEM_INFO | StatusBarManager.DISABLE_NAVIGATION);
     }
 
+    @Override
+    public void onStop() {
+        super.onStop();
+
+        mHandler.removeMessages(COOLDOWN);
+        mHandler.removeMessages(UPDATE_PROGRESS);
+
+        if (mWakeLock != null) {
+            mWakeLock.release();
+            mWakeLock = null;
+        }
+    }
+
     private void encryptionProgressInit() {
         // Accquire a partial wakelock to prevent the device from sleeping. Note
         // we never release this wakelock as we will be restarted after the device
         // is encrypted.
 
         PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
-        PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG);
+        mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
 
-        wakeLock.acquire();
+        mWakeLock.acquire();
 
-        mHandler.sendEmptyMessage(UPDATE_PROGRESS);
+        ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar);
+        progressBar.setIndeterminate(true);
+
+        updateProgress();
+    }
+
+    private void updateProgress() {
+        String state = SystemProperties.get("vold.encrypt_progress");
+
+        int progress = 0;
+        try {
+            progress = Integer.parseInt(state);
+        } catch (Exception e) {
+            Log.w(TAG, "Error parsing progress: " + e.toString());
+        }
+
+        CharSequence status = getText(R.string.crypt_keeper_setup_description);
+        TextView tv = (TextView) findViewById(R.id.status);
+        tv.setText(TextUtils.expandTemplate(status, Integer.toString(progress)));
+
+        // Check the progress every 5 seconds
+        mHandler.removeMessages(UPDATE_PROGRESS);
+        mHandler.sendEmptyMessageDelayed(UPDATE_PROGRESS, 5000);
+    }
+
+    private void cooldown() {
+        TextView tv = (TextView) findViewById(R.id.status);
+        if (mCooldown <= 0) {
+            // Re-enable the password entry
+            EditText passwordEntry = (EditText) findViewById(R.id.passwordEntry);
+            passwordEntry.setEnabled(true);
+
+            tv.setText(R.string.try_again);
+
+        } else {
+            CharSequence tempalte = getText(R.string.crypt_keeper_cooldown);
+            tv.setText(TextUtils.expandTemplate(tempalte, Integer.toString(mCooldown)));
+
+            mCooldown--;
+            mHandler.removeMessages(COOLDOWN);
+            mHandler.sendEmptyMessageDelayed(COOLDOWN, 1000); // Tick every second
+        }
     }
 
     private void passwordEntryInit() {
@@ -211,7 +236,7 @@
                     mCooldown = COOL_DOWN_INTERVAL;
                     EditText passwordEntry = (EditText) findViewById(R.id.passwordEntry);
                     passwordEntry.setEnabled(false);
-                    mHandler.sendEmptyMessage(COOLDOWN);
+                    cooldown();
                 } else {
                     TextView tv = (TextView) findViewById(R.id.status);
                     tv.setText(R.string.try_again);
diff --git a/src/com/android/settings/CryptKeeperComfirm.java b/src/com/android/settings/CryptKeeperComfirm.java
deleted file mode 100644
index cf72ec8..0000000
--- a/src/com/android/settings/CryptKeeperComfirm.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ServiceManager;
-import android.os.storage.IMountService;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-public class CryptKeeperComfirm extends Fragment {
-
-    private View mContentView;
-    private Button mFinalButton;
-    private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
-
-        public void onClick(View v) {
-            if (Utils.isMonkeyRunning()) {
-                return;
-            }
-            
-            IBinder service = ServiceManager.getService("mount");
-            if (service == null) {
-                return;
-            }
-
-            IMountService mountService = IMountService.Stub.asInterface(service);
-            try {
-                Bundle args = getArguments();
-                mountService.encryptStorage(args.getString("password"));
-            } catch (Exception e) {
-                Log.e("CryptKeeper", "Error while encrypting...", e);
-            }
-        }
-    };
-
-    private void establishFinalConfirmationState() {
-        mFinalButton = (Button) mContentView.findViewById(R.id.execute_encrypt);
-        mFinalButton.setOnClickListener(mFinalClickListener);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        mContentView = inflater.inflate(R.layout.crypt_keeper_confirm, null);
-        establishFinalConfirmationState();
-        return mContentView;
-    }
-}
diff --git a/src/com/android/settings/CryptKeeperConfirm.java b/src/com/android/settings/CryptKeeperConfirm.java
new file mode 100644
index 0000000..0269c2b
--- /dev/null
+++ b/src/com/android/settings/CryptKeeperConfirm.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.os.storage.IMountService;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+public class CryptKeeperConfirm extends Fragment {
+
+    public static class Blank extends Activity {
+        private Handler mHandler = new Handler();
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            if (Utils.isMonkeyRunning()) {
+                finish();
+            }
+
+            StatusBarManager sbm = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
+            sbm.disable(StatusBarManager.DISABLE_EXPAND
+                    | StatusBarManager.DISABLE_NOTIFICATION_ICONS
+                    | StatusBarManager.DISABLE_NOTIFICATION_ALERTS
+                    | StatusBarManager.DISABLE_SYSTEM_INFO
+                    | StatusBarManager.DISABLE_NAVIGATION);
+
+            // Post a delayed message in 700 milliseconds to enable encryption.
+            // NOTE: The animation on this activity is set for 500 milliseconds
+            // I am giving it a little extra time to complete.
+            mHandler.postDelayed(new Runnable() {
+                public void run() {
+                    IBinder service = ServiceManager.getService("mount");
+                    if (service == null) {
+                        return;
+                    }
+
+                    IMountService mountService = IMountService.Stub.asInterface(service);
+                    try {
+                        Bundle args = getIntent().getExtras();
+                        Log.d("CryptKeeper", "### password = " + args.getString("password"));
+                        mountService.encryptStorage(args.getString("password"));
+                    } catch (Exception e) {
+                        Log.e("CryptKeeper", "Error while encrypting...", e);
+                    }
+                }
+            }, 700);
+        }
+    }
+
+    private View mContentView;
+    private Button mFinalButton;
+    private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
+
+        public void onClick(View v) {
+            if (Utils.isMonkeyRunning()) {
+                return;
+            }
+
+            Intent intent = new Intent(getActivity(), Blank.class);
+            intent.putExtras(getArguments());
+
+            startActivity(intent);
+        }
+    };
+
+    private void establishFinalConfirmationState() {
+        mFinalButton = (Button) mContentView.findViewById(R.id.execute_encrypt);
+        mFinalButton.setOnClickListener(mFinalClickListener);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        mContentView = inflater.inflate(R.layout.crypt_keeper_confirm, null);
+        establishFinalConfirmationState();
+        return mContentView;
+    }
+}
diff --git a/src/com/android/settings/CryptKeeperSettings.java b/src/com/android/settings/CryptKeeperSettings.java
index d26e5ff..e584a3d 100644
--- a/src/com/android/settings/CryptKeeperSettings.java
+++ b/src/com/android/settings/CryptKeeperSettings.java
@@ -58,10 +58,10 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
-                int level = intent.getIntExtra("level", 0);
-                int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
+                int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+                int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
 
-                if (status == BatteryManager.BATTERY_STATUS_CHARGING && level >= 80) {
+                if (plugged == BatteryManager.BATTERY_PLUGGED_AC && level >= 80) {
                     mInitiateButton.setEnabled(true);
                 } else {
                     mInitiateButton.setEnabled(false);
@@ -171,7 +171,7 @@
 
     private void showFinalConfirmation(String password) {
         Preference preference = new Preference(getActivity());
-        preference.setFragment(CryptKeeperComfirm.class.getName());
+        preference.setFragment(CryptKeeperConfirm.class.getName());
         preference.setTitle(R.string.crypt_keeper_confirm_title);
         preference.getExtras().putString("password", password);
         ((PreferenceActivity) getActivity()).onPreferenceStartFragment(null, preference);
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index e413915..3f061b8 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -29,7 +29,6 @@
 import android.database.Cursor;
 import android.location.LocationManager;
 import android.os.Bundle;
-import android.os.SystemProperties;
 import android.os.Vibrator;
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
@@ -188,17 +187,20 @@
 
 
         // Add options for device encryption
+        DevicePolicyManager dpm =
+                (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
 
-        String status = SystemProperties.get("ro.crypto.state", "unsupported");
-        if ("encrypted".equalsIgnoreCase(status)) {
-            // The device is currently encrypted
+        switch (dpm.getStorageEncryptionStatus()) {
+        case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
+            // The device is currently encrypted.
             addPreferencesFromResource(R.xml.security_settings_encrypted);
-        } else if ("unencrypted".equalsIgnoreCase(status)) {
-            // This device support encryption but isn't encrypted
+            break;
+        case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE:
+            // This device supports encryption but isn't encrypted.
             addPreferencesFromResource(R.xml.security_settings_unencrypted);
+            break;
         }
 
-
         // lock after preference
         mLockAfter = (ListPreference) root.findPreference(KEY_LOCK_AFTER_TIMEOUT);
         if (mLockAfter != null) {