More UI tweaks and fixes.

* Actually post the correct message every 5 second for the progress bar.
* Update the text for the settings to a more finalish version.
* Check the battery status before allowing encryption to proceed.
* Display a place holder message if no password is set for the device.

Change-Id: I2734300c9a81467dbd0401427d8b656922ab4819
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6131eb7..9724e60 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -587,12 +587,12 @@
     <string name="crypt_keeper_encrypt_summary">Requires you to set a device unlock pin or password</string>
     <string name="crypt_keeper_confirm_title">Confirm encrypt</string>
     
-    <string name="crypt_keeper_desc">Device encryption will convert user data to an ecrypted state, including your accounts, system data, downloaded applications and data, photos, movies, musics, etc.\n\nEncyrption cannot be undone without performing a factory data reset, which would then erase all data.\n\nYou must set up a device lock pin or password to proceed.\n\nThis operation may take up to an hour and may not be interrupted. You must have a fully charged battery and plug in the device to initiate encryption. Running out of power during encryption will cause data loss.</string>
+    <string name="crypt_keeper_desc">You can encrypt your accounts, settings, downloaded applications and their data, media, and other files. Once you encrypt your tablet, you can\'t unencrypt it except by performing a factory data reset, erasing all the data on your tablet.\n\nEncryption takes up to an hour. You must start with a charged battery and keep your tablet plugged in until encryption is complete. If you interrupt the encryption process, you will lose some or all of your data.</string>
     
     <string name="crypt_keeper_button_text" product="tablet">Encrypt tablet</string>
     <string name="crypt_keeper_button_text" product="default">Encrypt phone</string>
     
-    <string name="crypt_keeper_final_desc">Encrypt user data? This operation is not reversible and may not be interrupted without loos of data! Encryption may take up to an hour.</string>
+    <string name="crypt_keeper_final_desc">Encrypt user data? This operation is not reversible and may not be interrupted without loss of data! Encryption may take up to an hour.</string>
     
     <string name="crypt_keeper_setup_title">Encrypting</string>
 
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
index 25bb242..222e954 100644
--- a/src/com/android/settings/CryptKeeper.java
+++ b/src/com/android/settings/CryptKeeper.java
@@ -75,9 +75,9 @@
                 } catch (Exception e) {
                     Log.w(TAG, "Error parsing progress: " + e.toString());
                 }
-                
-                // Check the status every 1 second
-                sendEmptyMessageDelayed(0, 1000);
+
+                // Check the status every 5 second
+                sendEmptyMessageDelayed(UPDATE_PROGRESS, 5000);
                 break;
             
             case COOLDOWN:
@@ -128,6 +128,12 @@
             setContentView(R.layout.crypt_keeper_password_entry);
             passwordEntryInit();
         }
+
+        // Disable the status bar
+        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);
     }
     
     private void encryptionProgressInit() {
@@ -151,12 +157,6 @@
         String dateFormatString = getString(com.android.internal.R.string.full_wday_month_day_no_year);
         TextView date = (TextView) findViewById(R.id.date);
         date.setText(DateFormat.format(dateFormatString, new Date()));
-
-        // Disable the status bar
-        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);
     }
 
     private IMountService getMountService() {
@@ -184,12 +184,10 @@
             try {
                 service.decryptStorage(password);
 
-                // For now the only way to get here is for the password to be
-                // wrong.
+                if (mFailedAttempts == 0) {
+                    // Success. Do something here within 2 seconds
 
-                mFailedAttempts++;
-                
-                if (mFailedAttempts == MAX_FAILED_ATTEMPTS) {
+                } else if (mFailedAttempts == MAX_FAILED_ATTEMPTS) {
                     // Factory reset the device.
                     sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
                 } else if ((mFailedAttempts % COOL_DOWN_ATTEMPTS) == 0) {
diff --git a/src/com/android/settings/CryptKeeperSettings.java b/src/com/android/settings/CryptKeeperSettings.java
index 8b60ca7..26483ec 100644
--- a/src/com/android/settings/CryptKeeperSettings.java
+++ b/src/com/android/settings/CryptKeeperSettings.java
@@ -17,9 +17,14 @@
 package com.android.settings;
 
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.app.Fragment;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.res.Resources;
+import android.os.BatteryManager;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
@@ -45,6 +50,72 @@
 
     private View mContentView;
     private Button mInitiateButton;
+    private IntentFilter mIntentFilter;
+
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        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);
+
+                if (status == BatteryManager.BATTERY_STATUS_CHARGING && level >= 80) {
+                    mInitiateButton.setEnabled(true);
+                } else {
+                    mInitiateButton.setEnabled(false);
+                }
+            }
+        }
+    };
+
+    /**
+     * If the user clicks to begin the reset sequence, we next require a
+     * keyguard confirmation if the user has currently enabled one.  If there
+     * is no keyguard available, we prompt the user to set a password.
+     */
+    private Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
+
+        public void onClick(View v) {
+            if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
+                // TODO remove with proper flow
+                new AlertDialog.Builder(getActivity())
+                    .setTitle("No password set")
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage("Before you enable encryption you must set a device password.")
+                    .setPositiveButton(android.R.string.ok, null)
+                    .create()
+                    .show();
+            }
+        }
+    };
+
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+        mContentView = inflater.inflate(R.layout.crypt_keeper_settings, null);
+
+        mIntentFilter = new IntentFilter();
+        mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
+
+        mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_encrypt);
+        mInitiateButton.setOnClickListener(mInitiateListener);
+        mInitiateButton.setEnabled(false);
+
+        return mContentView;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        getActivity().registerReceiver(mIntentReceiver, mIntentFilter);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        getActivity().unregisterReceiver(mIntentReceiver);
+    }
 
     /**
      * Keyguard validation is run using the standard {@link ConfirmLockPattern}
@@ -67,14 +138,12 @@
         if (requestCode != KEYGUARD_REQUEST) {
             return;
         }
-        
+
         // If the user entered a valid keyguard trace, present the final
         // confirmation prompt; otherwise, go back to the initial state.
         if (resultCode == Activity.RESULT_OK) {
             String password = data.getStringExtra("password");
             showFinalConfirmation(password);
-        } else {
-            establishInitialState();
         }
     }
 
@@ -85,45 +154,5 @@
         preference.getExtras().putString("password", password);
         ((PreferenceActivity) getActivity()).onPreferenceStartFragment(null, preference);
     }
-
-    /**
-     * If the user clicks to begin the reset sequence, we next require a
-     * keyguard confirmation if the user has currently enabled one.  If there
-     * is no keyguard available, we simply go to the final confirmation prompt.
-     */
-    private Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
-
-        public void onClick(View v) {
-            if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
-                // TODO: Need to request a password
-               // showFinalConfirmation();
-            }
-        }
-    };
-
-    /**
-     * In its initial state, the activity presents a button for the user to
-     * click in order to initiate a confirmation sequence.  This method is
-     * called from various other points in the code to reset the activity to
-     * this base state.
-     *
-     * <p>Reinflating views from resources is expensive and prevents us from
-     * caching widget pointers, so we use a single-inflate pattern:  we lazy-
-     * inflate each view, caching all of the widget pointers we'll need at the
-     * time, then simply reuse the inflated views directly whenever we need
-     * to change contents.
-     */
-    private void establishInitialState() {
-        mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_encrypt);
-        mInitiateButton.setOnClickListener(mInitiateListener);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        mContentView = inflater.inflate(R.layout.crypt_keeper_settings, null);
-
-        establishInitialState();
-        return mContentView;
-    }
 }