OSDN Git Service

More work on the Crypt Keeper.
authorJason parks <jparks@google.com>
Wed, 26 Jan 2011 19:11:42 +0000 (13:11 -0600)
committerJason parks <jparks@google.com>
Thu, 27 Jan 2011 17:26:58 +0000 (11:26 -0600)
* 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

AndroidManifest.xml
res/drawable-xlarge-mdpi/encryption_bg_complete.png [new file with mode: 0644]
res/layout-xlarge/crypt_keeper_progress.xml
res/values/strings.xml
src/com/android/settings/CryptKeeper.java
src/com/android/settings/CryptKeeperComfirm.java [deleted file]
src/com/android/settings/CryptKeeperConfirm.java [new file with mode: 0644]
src/com/android/settings/CryptKeeperSettings.java
src/com/android/settings/SecuritySettings.java

index 1ef8a46..69f91ed 100644 (file)
             android:theme="@style/CryptKeeperBlankTheme"
         />
 
+        <activity android:name=".CryptKeeperConfirm$Blank"
+            android:immersive="true"
+            android:launchMode="singleTop"
+            android:theme="@style/CryptKeeperBlankTheme"
+        />
+
         <!-- Pseudo-activity used to provide an intent-filter entry point to encryption settings -->
         <activity android:name="Settings$CryptKeeperSettingsActivity"
                 android:theme="@android:style/Theme.Holo"
diff --git a/res/drawable-xlarge-mdpi/encryption_bg_complete.png b/res/drawable-xlarge-mdpi/encryption_bg_complete.png
new file mode 100644 (file)
index 0000000..f53cb23
Binary files /dev/null and b/res/drawable-xlarge-mdpi/encryption_bg_complete.png differ
index 7c6c363..5a33a9e 100644 (file)
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:paddingTop="60dip"
+    android:paddingTop="154dip"
     android:paddingLeft="128dip"
     android:paddingRight="128dip"
     android:paddingBottom="0dip" 
     android:orientation="vertical"
+    android:background="@drawable/encryption_bg_waiting"
 >
 
     <TextView
         />
     </RelativeLayout>
     
-    
     <TextView
+        android:id="@+id/status"
         android:layout_width="match_parent"
         android:layout_height="0dip"
         android:layout_weight="1"
-        android:layout_marginLeft="16dip"
+        android:paddingLeft="152dip"
+        android:paddingTop="21dip"
+        android:textSize="18dip"
+        android:textColor="#ffffffff"
         android:text="@string/crypt_keeper_setup_description"
     />
 
index 8dc3f0c..38536cf 100644 (file)
     
     <string name="crypt_keeper_setup_title">Encrypting</string>
 
-    <string name="crypt_keeper_setup_description" product="tablet">Please wait while your tablet is being encrypted.</string>
-    <string name="crypt_keeper_setup_description" product="default">Please wait while your phone is being encrypted.</string>
-    
+    <string name="crypt_keeper_setup_description" product="tablet">Please wait while your tablet is being encrypted. ^1% complete.</string>
+    <string name="crypt_keeper_setup_description" product="default">Please wait while your phone is being encrypted. ^1% complete.</string>
+
     <string name="crypt_keeper_cooldown">Try again in ^1 seconds.</string>
     
     <!-- Unlock Picker Settings --><skip />
index 5afc3f6..6f847f3 100644 (file)
@@ -64,49 +64,20 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
     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 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
                 | 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);
+
+        mWakeLock.acquire();
+
+        ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar);
+        progressBar.setIndeterminate(true);
 
-        wakeLock.acquire();
+        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());
+        }
 
-        mHandler.sendEmptyMessage(UPDATE_PROGRESS);
+        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 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
                     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 (file)
index cf72ec8..0000000
+++ /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 (file)
index 0000000..0269c2b
--- /dev/null
@@ -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;
+    }
+}
index d26e5ff..e584a3d 100644 (file)
@@ -58,10 +58,10 @@ public class CryptKeeperSettings extends Fragment {
         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 @@ public class CryptKeeperSettings extends Fragment {
 
     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);
index e413915..3f061b8 100644 (file)
@@ -29,7 +29,6 @@ import android.content.Intent;
 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 @@ public class SecuritySettings extends SettingsPreferenceFragment
 
 
         // 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) {