Add a setting to enable encryption.

This isn't final and it will wipe your device.

Change-Id: I7fecded92a745844435878d0409d620bfa571472
diff --git a/res/layout-xlarge-land/crypt_keeper.xml b/res/layout-xlarge-land/crypt_keeper.xml
index 892cf52..76d2278 100644
--- a/res/layout-xlarge-land/crypt_keeper.xml
+++ b/res/layout-xlarge-land/crypt_keeper.xml
@@ -20,8 +20,51 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical"
+    android:orientation="horizontal"
 >
-    <include layout="@layout/crypt_keeper_content" />
+    <LinearLayout
+           android:layout_height="match_parent"
+           android:layout_weight="1"
+           android:layout_width="0dip"
+           android:orientation="vertical"
+           android:gravity="center_vertical"
+               >
+       <include layout="@layout/crypt_keeper_status" />
+   </LinearLayout>
+   
+   <!-- right side: password -->
+   <LinearLayout
+       android:layout_width="0dip"
+       android:layout_height="match_parent"
+       android:orientation="vertical"
+       android:layout_weight="1"
+       android:gravity="center">
+
+       <!-- Password entry field -->
+       <EditText android:id="@+id/passwordEntry"
+           android:layout_height="wrap_content"
+           android:layout_width="450dip"
+           android:singleLine="true"
+           android:textStyle="normal"
+           android:inputType="textPassword"
+           android:gravity="center"
+           android:layout_gravity="center"
+           android:textSize="24sp"
+           android:layout_marginTop="120dip"
+           android:layout_marginBottom="5dip"
+           android:textAppearance="?android:attr/textAppearanceMedium"
+           android:textColor="#ffffffff"
+           android:editable="false"
+        />
+
+       <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+           android:layout_width="450dip"
+           android:layout_height="230dip"
+           android:background="#00000000"
+           android:keyBackground="@*android:drawable/btn_keyboard_key_fulltrans"
+           android:visibility="visible"
+       />
+       
+   </LinearLayout>
     
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout-xlarge/crypt_keeper.xml b/res/layout-xlarge/crypt_keeper.xml
index 7cd82c5..4dce67a 100644
--- a/res/layout-xlarge/crypt_keeper.xml
+++ b/res/layout-xlarge/crypt_keeper.xml
@@ -20,8 +20,49 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="horizontal"
+    android:orientation="vertical"
 >
-    <include layout="@layout/crypt_keeper_content" />
+    <LinearLayout
+           android:layout_height="wrap_content"
+           android:layout_width="match_parent"
+           android:orientation="vertical"
+           android:gravity="center_vertical"
+               >
+       <include layout="@layout/crypt_keeper_status" />
+   </LinearLayout>
+   
+   <!-- right side: password -->
+   <LinearLayout
+       android:layout_width="match_parent"
+       android:layout_height="match_parent"
+       android:orientation="vertical"
+       android:gravity="center">
+
+       <!-- Password entry field -->
+       <EditText android:id="@+id/passwordEntry"
+           android:layout_height="wrap_content"
+           android:layout_width="450dip"
+           android:singleLine="true"
+           android:textStyle="normal"
+           android:inputType="textPassword"
+           android:gravity="center"
+           android:layout_gravity="center"
+           android:textSize="24sp"
+           android:layout_marginTop="120dip"
+           android:layout_marginBottom="5dip"
+           android:textAppearance="?android:attr/textAppearanceMedium"
+           android:textColor="#ffffffff"
+           android:editable="false"
+        />
+
+       <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+           android:layout_width="450dip"
+           android:layout_height="230dip"
+           android:background="#00000000"
+           android:keyBackground="@*android:drawable/btn_keyboard_key_fulltrans"
+           android:visibility="visible"
+       />
+       
+   </LinearLayout>
     
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/crypt_keeper_content.xml b/res/layout/crypt_keeper.xml
similarity index 84%
rename from res/layout/crypt_keeper_content.xml
rename to res/layout/crypt_keeper.xml
index fa337e8..4dce67a 100644
--- a/res/layout/crypt_keeper_content.xml
+++ b/res/layout/crypt_keeper.xml
@@ -17,11 +17,14 @@
 */
 -->
 
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-   <LinearLayout
-           android:layout_height="match_parent"
-           android:layout_weight="1"
-           android:layout_width="0dip"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+>
+    <LinearLayout
+           android:layout_height="wrap_content"
+           android:layout_width="match_parent"
            android:orientation="vertical"
            android:gravity="center_vertical"
                >
@@ -30,10 +33,9 @@
    
    <!-- right side: password -->
    <LinearLayout
-       android:layout_width="0dip"
+       android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
-       android:layout_weight="1"
        android:gravity="center">
 
        <!-- Password entry field -->
@@ -62,4 +64,5 @@
        />
        
    </LinearLayout>
-</merge>
\ No newline at end of file
+    
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1a6dcd6..30f7b20 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -576,6 +576,10 @@
     <!-- In the security screen, the header title for settings related to  Passwords-->
     <string name="security_passwords_title">Passwords</string>
 
+    <string name="encryption_settings_title">Device encryption</string>
+    <string name="encrypt_title">Encrypt data on device</string>
+    <string name="encrypt_summary">Requires you to set a device unlock pin or password</string>
+
     <!-- Unlock Picker Settings --><skip />
 
     <!-- Security Picker --><skip />
diff --git a/res/xml/security_settings_encryption.xml b/res/xml/security_settings_encryption.xml
new file mode 100644
index 0000000..fa6d70e
--- /dev/null
+++ b/res/xml/security_settings_encryption.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <PreferenceCategory
+        android:key="security_category"
+        android:title="@string/encryption_settings_title">
+
+        <PreferenceScreen
+            android:key="encryption"
+            android:title="@string/encrypt_title"
+            android:summary="@string/encrypt_summary"
+            android:persistent="false"/>
+
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 704eacd..ea6232d 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -32,8 +32,11 @@
 import android.database.Cursor;
 import android.location.LocationManager;
 import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.Vibrator;
+import android.os.storage.IMountService;
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
@@ -62,6 +65,8 @@
         implements OnPreferenceChangeListener {
     private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
 
+    private static final String KEY_ENCRYPTION = "encryption";
+
     // Lock Settings
     private static final String PACKAGE = "com.android.settings";
     private static final String ICC_LOCK_SETTINGS = PACKAGE + ".IccLockSettings";
@@ -184,6 +189,12 @@
         }
 
         PreferenceManager pm = getPreferenceManager();
+        
+        // Add options for device encryption
+        // TODO: It still needs to be determined how a device specifies that it supports
+        // encryption. That mechanism needs to be checked before adding the following code
+        
+        addPreferencesFromResource(R.xml.security_settings_encryption);
 
         // Add options for lock/unlock screen
         int resid = 0;
@@ -407,6 +418,8 @@
         } else if (preference == mAssistedGps) {
             Settings.Secure.putInt(getContentResolver(), Settings.Secure.ASSISTED_GPS_ENABLED,
                     mAssistedGps.isChecked() ? 1 : 0);
+        } else if (KEY_ENCRYPTION.equals(key)) {
+            new Encryption().showPasswordDialog();
         } else {
             // If we didn't handle it, let preferences handle it.
             return super.onPreferenceTreeClick(preferenceScreen, preference);
@@ -445,6 +458,89 @@
         createPreferenceHierarchy();
     }
 
+    private class Encryption implements DialogInterface.OnClickListener,
+            DialogInterface.OnDismissListener {
+
+        private boolean mSubmit;
+
+        public void showPasswordDialog() {
+            View view = View.inflate(SecuritySettings.this.getActivity(),
+                    R.layout.credentials_password_dialog, null);
+
+            Dialog dialog = new AlertDialog.Builder(SecuritySettings.this.getActivity())
+                    .setView(view).setTitle(R.string.credentials_set_password)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setNegativeButton(android.R.string.cancel, this).create();
+            dialog.setOnDismissListener(this);
+            dialog.show();
+        }
+
+        public void onClick(DialogInterface dialog, int button) {
+            if (button == DialogInterface.BUTTON_POSITIVE) {
+                mSubmit = true;
+            }
+        }
+
+        public void onDismiss(DialogInterface dialog) {
+            if (mSubmit) {
+                mSubmit = false;
+                if (!checkPassword((Dialog) dialog)) {
+                    ((Dialog) dialog).show();
+                    return;
+                }
+            }
+        }
+
+        // Return true if there is no error.
+        private boolean checkPassword(Dialog dialog) {
+            String newPassword = getText(dialog, R.id.new_password);
+            String confirmPassword = getText(dialog, R.id.confirm_password);
+
+            if (newPassword == null || confirmPassword == null || newPassword.length() == 0
+                    || confirmPassword.length() == 0) {
+                showError(dialog, R.string.credentials_passwords_empty);
+            } else if (!newPassword.equals(confirmPassword)) {
+                showError(dialog, R.string.credentials_passwords_mismatch);
+            } else {
+
+                IBinder service = ServiceManager.getService("mount");
+                if (service == null) {
+                    return false;
+                }
+
+                IMountService mountService = IMountService.Stub.asInterface(service);
+                try {
+                    mountService.encryptStorage(newPassword);
+                } catch (Exception e) {
+                    Log.e(TAG, "Error while encrypting...", e);
+                }
+
+                return true;
+            }
+
+            return false;
+        }
+
+        private String getText(Dialog dialog, int viewId) {
+            TextView view = (TextView) dialog.findViewById(viewId);
+            return (view == null || view.getVisibility() == View.GONE) ? null : view.getText()
+                    .toString();
+        }
+
+        private void showError(Dialog dialog, int stringId, Object... formatArgs) {
+            TextView view = (TextView) dialog.findViewById(R.id.error);
+            if (view != null) {
+                if (formatArgs == null || formatArgs.length == 0) {
+                    view.setText(stringId);
+                } else {
+                    view.setText(dialog.getContext().getString(stringId, formatArgs));
+                }
+                view.setVisibility(View.VISIBLE);
+            }
+        }
+
+    }
+
     private class CredentialStorage implements DialogInterface.OnClickListener,
             DialogInterface.OnDismissListener, Preference.OnPreferenceChangeListener,
             Preference.OnPreferenceClickListener {