CryptKeeper.java revision 9597406aa1b83867b03a47d1a5162969b924f2fc
18fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks/* 28fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * Copyright (C) 2011 The Android Open Source Project 38fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * 48fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * Licensed under the Apache License, Version 2.0 (the "License"); 58fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * you may not use this file except in compliance with the License. 68fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * You may obtain a copy of the License at 78fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * 88fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * http://www.apache.org/licenses/LICENSE-2.0 98fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * 108fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * Unless required by applicable law or agreed to in writing, software 118fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * distributed under the License is distributed on an "AS IS" BASIS, 128fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * See the License for the specific language governing permissions and 148fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks * limitations under the License. 158fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks */ 168fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks 178fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parkspackage com.android.settings; 188fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks 198fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport com.android.internal.widget.PasswordEntryKeyboardHelper; 208fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport com.android.internal.widget.PasswordEntryKeyboardView; 218fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks 228fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.app.Activity; 238fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.app.StatusBarManager; 248fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.content.ComponentName; 258fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.content.Context; 26ec5a45e79cb7161adfabf475342c1e1b25994276Jason parksimport android.content.Intent; 278fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.content.pm.PackageManager; 288fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.inputmethodservice.KeyboardView; 298fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.os.Bundle; 30ec5a45e79cb7161adfabf475342c1e1b25994276Jason parksimport android.os.Handler; 318fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.os.IBinder; 32ec5a45e79cb7161adfabf475342c1e1b25994276Jason parksimport android.os.Message; 3335933812b16f0b4221280bbcc3c32f6540996bf2Jason parksimport android.os.PowerManager; 348fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.os.ServiceManager; 358fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.os.SystemProperties; 368fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.os.storage.IMountService; 37ec5a45e79cb7161adfabf475342c1e1b25994276Jason parksimport android.text.TextUtils; 388fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.util.Log; 398fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.view.KeyEvent; 4013d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadlerimport android.view.View; 4113d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadlerimport android.view.View.OnClickListener; 428fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.view.inputmethod.EditorInfo; 4313d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadlerimport android.widget.Button; 44ec5a45e79cb7161adfabf475342c1e1b25994276Jason parksimport android.widget.EditText; 45ec5a45e79cb7161adfabf475342c1e1b25994276Jason parksimport android.widget.ProgressBar; 468fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parksimport android.widget.TextView; 478fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks 488fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parkspublic class CryptKeeper extends Activity implements TextView.OnEditorActionListener { 49ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks private static final String TAG = "CryptKeeper"; 5035933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 518fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks private static final String DECRYPT_STATE = "trigger_restart_framework"; 52ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks 53ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks private static final int UPDATE_PROGRESS = 1; 54ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks private static final int COOLDOWN = 2; 55ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks 56ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks private static final int MAX_FAILED_ATTEMPTS = 30; 57ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks private static final int COOL_DOWN_ATTEMPTS = 10; 58ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks private static final int COOL_DOWN_INTERVAL = 30; // 30 seconds 59ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks 601499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler private int mCooldown; 611499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler PowerManager.WakeLock mWakeLock; 621499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler 631499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler /** 641499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler * Used to propagate state through configuration changes (e.g. screen rotation) 651499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler */ 661499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler private static class NonConfigurationInstanceState { 671499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler final PowerManager.WakeLock wakelock; 681499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler 691499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler NonConfigurationInstanceState(PowerManager.WakeLock _wakelock) { 701499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler wakelock = _wakelock; 711499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler } 721499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler } 731499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler 74f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks // This activity is used to fade the screen to black after the password is entered. 75f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks public static class Blank extends Activity { 7613d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler @Override 7713d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler public void onCreate(Bundle savedInstanceState) { 7813d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler super.onCreate(savedInstanceState); 7913d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler setContentView(R.layout.crypt_keeper_blank); 8013d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler } 81f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks } 82ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks 83ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks private Handler mHandler = new Handler() { 84ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks @Override 85ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks public void handleMessage(Message msg) { 86ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks switch (msg.what) { 87ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks case UPDATE_PROGRESS: 88f8217304073b5cd13823a0602568394be93bf310Jason parks updateProgress(); 89ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks break; 9035933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 91ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks case COOLDOWN: 92f8217304073b5cd13823a0602568394be93bf310Jason parks cooldown(); 93ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks break; 94ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks } 95ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks } 96ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks }; 9735933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 988fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks @Override 998fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks public void onCreate(Bundle savedInstanceState) { 1008fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks super.onCreate(savedInstanceState); 10135933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 1029597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler // If we are not encrypted or encrypting, get out quickly. 1038fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks String state = SystemProperties.get("vold.decrypt"); 1048fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks if ("".equals(state) || DECRYPT_STATE.equals(state)) { 10535933812b16f0b4221280bbcc3c32f6540996bf2Jason parks // Disable the crypt keeper. 1068fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks PackageManager pm = getPackageManager(); 1078fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks ComponentName name = new ComponentName(this, CryptKeeper.class); 1088fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0); 1098fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks return; 1108fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks } 11135933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 11239f1e04079976d3d10fdd8e5dd36c833bab8a371Jason parks // Disable the status bar 11339f1e04079976d3d10fdd8e5dd36c833bab8a371Jason parks StatusBarManager sbm = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE); 11413d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler sbm.disable(StatusBarManager.DISABLE_EXPAND 11513d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler | StatusBarManager.DISABLE_NOTIFICATION_ICONS 11639f1e04079976d3d10fdd8e5dd36c833bab8a371Jason parks | StatusBarManager.DISABLE_NOTIFICATION_ALERTS 11713d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler | StatusBarManager.DISABLE_SYSTEM_INFO 11813d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler | StatusBarManager.DISABLE_NAVIGATION 11913d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler | StatusBarManager.DISABLE_BACK); 1201499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler 1211499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler // Check for (and recover) retained instance data 1221499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler Object lastInstance = getLastNonConfigurationInstance(); 1231499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler if (lastInstance instanceof NonConfigurationInstanceState) { 1241499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler NonConfigurationInstanceState retained = (NonConfigurationInstanceState) lastInstance; 1251499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler mWakeLock = retained.wakelock; 1261499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler } 127ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks } 12835933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 1299597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler /** 1309597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler * Note, we defer the state check and screen setup to onStart() because this will be 1319597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler * re-run if the user clicks the power button (sleeping/waking the screen), and this is 1329597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler * especially important if we were to lose the wakelock for any reason. 1339597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler */ 1349597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler @Override 1359597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler public void onStart() { 1369597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler super.onStart(); 1379597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler 1389597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler // Check to see why we were started. 1399597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler String progress = SystemProperties.get("vold.encrypt_progress"); 1409597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler if (!"".equals(progress)) { 1419597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler setContentView(R.layout.crypt_keeper_progress); 1429597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler encryptionProgressInit(); 1439597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler } else { 1449597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler setContentView(R.layout.crypt_keeper_password_entry); 1459597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler passwordEntryInit(); 1469597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler } 1479597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler } 1489597406aa1b83867b03a47d1a5162969b924f2fcAndy Stadler 149f8217304073b5cd13823a0602568394be93bf310Jason parks @Override 150f8217304073b5cd13823a0602568394be93bf310Jason parks public void onStop() { 151f8217304073b5cd13823a0602568394be93bf310Jason parks super.onStop(); 152f8217304073b5cd13823a0602568394be93bf310Jason parks 153f8217304073b5cd13823a0602568394be93bf310Jason parks mHandler.removeMessages(COOLDOWN); 154f8217304073b5cd13823a0602568394be93bf310Jason parks mHandler.removeMessages(UPDATE_PROGRESS); 1551499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler } 1561499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler 1571499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler /** 1581499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler * Reconfiguring, so propagate the wakelock to the next instance. This runs between onStop() 1591499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler * and onDestroy() and only if we are changing configuration (e.g. rotation). Also clears 1601499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler * mWakeLock so the subsequent call to onDestroy does not release it. 1611499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler */ 1621499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler @Override 1631499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler public Object onRetainNonConfigurationInstance() { 1641499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler NonConfigurationInstanceState state = new NonConfigurationInstanceState(mWakeLock); 1651499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler mWakeLock = null; 1661499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler return state; 1671499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler } 1681499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler 1691499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler @Override 1701499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler public void onDestroy() { 1711499740c13af5fbd5766a87825c3e789b37bab24Andy Stadler super.onDestroy(); 172f8217304073b5cd13823a0602568394be93bf310Jason parks 173f8217304073b5cd13823a0602568394be93bf310Jason parks if (mWakeLock != null) { 174f8217304073b5cd13823a0602568394be93bf310Jason parks mWakeLock.release(); 175f8217304073b5cd13823a0602568394be93bf310Jason parks mWakeLock = null; 176f8217304073b5cd13823a0602568394be93bf310Jason parks } 177f8217304073b5cd13823a0602568394be93bf310Jason parks } 178f8217304073b5cd13823a0602568394be93bf310Jason parks 179ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks private void encryptionProgressInit() { 18035933812b16f0b4221280bbcc3c32f6540996bf2Jason parks // Accquire a partial wakelock to prevent the device from sleeping. Note 18135933812b16f0b4221280bbcc3c32f6540996bf2Jason parks // we never release this wakelock as we will be restarted after the device 18235933812b16f0b4221280bbcc3c32f6540996bf2Jason parks // is encrypted. 18335933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 18435933812b16f0b4221280bbcc3c32f6540996bf2Jason parks PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 185f8217304073b5cd13823a0602568394be93bf310Jason parks mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); 186f8217304073b5cd13823a0602568394be93bf310Jason parks 187f8217304073b5cd13823a0602568394be93bf310Jason parks mWakeLock.acquire(); 188f8217304073b5cd13823a0602568394be93bf310Jason parks 189f8217304073b5cd13823a0602568394be93bf310Jason parks ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar); 190f8217304073b5cd13823a0602568394be93bf310Jason parks progressBar.setIndeterminate(true); 19135933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 192f8217304073b5cd13823a0602568394be93bf310Jason parks updateProgress(); 193f8217304073b5cd13823a0602568394be93bf310Jason parks } 194f8217304073b5cd13823a0602568394be93bf310Jason parks 19513d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler private void showFactoryReset() { 19613d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler // Hide the encryption-bot to make room for the "factory reset" button 19713d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler findViewById(R.id.encroid).setVisibility(View.GONE); 19813d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler 19913d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler // Show the reset button, failure text, and a divider 20013d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler Button button = (Button) findViewById(R.id.factory_reset); 20113d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler button.setVisibility(View.VISIBLE); 20213d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler button.setOnClickListener(new OnClickListener() { 20313d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler public void onClick(View v) { 20413d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler // Factory reset the device. 20513d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR")); 20613d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler } 20713d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler }); 20813d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler 20913d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler TextView tv = (TextView) findViewById(R.id.title); 21013d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler tv.setText(R.string.crypt_keeper_failed_title); 21113d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler 21213d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler tv = (TextView) findViewById(R.id.status); 21313d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler tv.setText(R.string.crypt_keeper_failed_summary); 21413d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler 21513d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler View view = findViewById(R.id.bottom_divider); 21613d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler view.setVisibility(View.VISIBLE); 21713d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler } 21813d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler 219f8217304073b5cd13823a0602568394be93bf310Jason parks private void updateProgress() { 220f8217304073b5cd13823a0602568394be93bf310Jason parks String state = SystemProperties.get("vold.encrypt_progress"); 221f8217304073b5cd13823a0602568394be93bf310Jason parks 22213d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler if ("error_partially_encrypted".equals(state)) { 22313d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler showFactoryReset(); 22413d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler return; 22513d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler } 22613d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler 227f8217304073b5cd13823a0602568394be93bf310Jason parks int progress = 0; 228f8217304073b5cd13823a0602568394be93bf310Jason parks try { 229f8217304073b5cd13823a0602568394be93bf310Jason parks progress = Integer.parseInt(state); 230f8217304073b5cd13823a0602568394be93bf310Jason parks } catch (Exception e) { 231f8217304073b5cd13823a0602568394be93bf310Jason parks Log.w(TAG, "Error parsing progress: " + e.toString()); 232f8217304073b5cd13823a0602568394be93bf310Jason parks } 23335933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 234f8217304073b5cd13823a0602568394be93bf310Jason parks CharSequence status = getText(R.string.crypt_keeper_setup_description); 235f8217304073b5cd13823a0602568394be93bf310Jason parks TextView tv = (TextView) findViewById(R.id.status); 236f8217304073b5cd13823a0602568394be93bf310Jason parks tv.setText(TextUtils.expandTemplate(status, Integer.toString(progress))); 237f8217304073b5cd13823a0602568394be93bf310Jason parks 238f8217304073b5cd13823a0602568394be93bf310Jason parks // Check the progress every 5 seconds 239f8217304073b5cd13823a0602568394be93bf310Jason parks mHandler.removeMessages(UPDATE_PROGRESS); 240f8217304073b5cd13823a0602568394be93bf310Jason parks mHandler.sendEmptyMessageDelayed(UPDATE_PROGRESS, 5000); 241f8217304073b5cd13823a0602568394be93bf310Jason parks } 242f8217304073b5cd13823a0602568394be93bf310Jason parks 243f8217304073b5cd13823a0602568394be93bf310Jason parks private void cooldown() { 244f8217304073b5cd13823a0602568394be93bf310Jason parks TextView tv = (TextView) findViewById(R.id.status); 24513d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler 246f8217304073b5cd13823a0602568394be93bf310Jason parks if (mCooldown <= 0) { 247f8217304073b5cd13823a0602568394be93bf310Jason parks // Re-enable the password entry 248f8217304073b5cd13823a0602568394be93bf310Jason parks EditText passwordEntry = (EditText) findViewById(R.id.passwordEntry); 249f8217304073b5cd13823a0602568394be93bf310Jason parks passwordEntry.setEnabled(true); 250f8217304073b5cd13823a0602568394be93bf310Jason parks 25113d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler tv.setVisibility(View.GONE); 252f8217304073b5cd13823a0602568394be93bf310Jason parks } else { 25313d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler CharSequence template = getText(R.string.crypt_keeper_cooldown); 25413d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler tv.setText(TextUtils.expandTemplate(template, Integer.toString(mCooldown))); 25513d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler 25613d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler tv.setVisibility(View.VISIBLE); 257f8217304073b5cd13823a0602568394be93bf310Jason parks 258f8217304073b5cd13823a0602568394be93bf310Jason parks mCooldown--; 259f8217304073b5cd13823a0602568394be93bf310Jason parks mHandler.removeMessages(COOLDOWN); 260f8217304073b5cd13823a0602568394be93bf310Jason parks mHandler.sendEmptyMessageDelayed(COOLDOWN, 1000); // Tick every second 261f8217304073b5cd13823a0602568394be93bf310Jason parks } 262ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks } 26335933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 264ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks private void passwordEntryInit() { 2658fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks TextView passwordEntry = (TextView) findViewById(R.id.passwordEntry); 2668fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks passwordEntry.setOnEditorActionListener(this); 26735933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 2688fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks KeyboardView keyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard); 26935933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 2708fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks PasswordEntryKeyboardHelper keyboardHelper = new PasswordEntryKeyboardHelper(this, 2718fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks keyboardView, passwordEntry, false); 2728fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks keyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA); 2738fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks } 2748fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks 2758fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks private IMountService getMountService() { 2768fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks IBinder service = ServiceManager.getService("mount"); 2778fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks if (service != null) { 2788fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks return IMountService.Stub.asInterface(service); 2798fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks } 2808fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks return null; 2818fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks } 2828fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks 2838fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks @Override 2848fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 2858fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks if (actionId == EditorInfo.IME_NULL) { 2868fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks // Get the password 2878fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks String password = v.getText().toString(); 2888fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks 289ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks if (TextUtils.isEmpty(password)) { 290ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks return true; 291ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks } 29235933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 2938fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks // Now that we have the password clear the password field. 2948fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks v.setText(null); 2958fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks 2968fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks IMountService service = getMountService(); 2978fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks try { 298f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks int failedAttempts = service.decryptStorage(password); 299f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks 300f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks if (failedAttempts == 0) { 301f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks // The password was entered successfully. Start the Blank activity 302f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks // so this activity animates to black before the devices starts. Note 303f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks // It has 1 second to complete the animation or it will be frozen 304f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks // until the boot animation comes back up. 305f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks Intent intent = new Intent(this, Blank.class); 306f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks finish(); 307f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks startActivity(intent); 308f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks } else if (failedAttempts == MAX_FAILED_ATTEMPTS) { 309ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks // Factory reset the device. 310ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR")); 311f1dbf55819e01f6cf1a99d38a292b15de1262a29Jason parks } else if ((failedAttempts % COOL_DOWN_ATTEMPTS) == 0) { 312ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks mCooldown = COOL_DOWN_INTERVAL; 313ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks EditText passwordEntry = (EditText) findViewById(R.id.passwordEntry); 314ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks passwordEntry.setEnabled(false); 315f8217304073b5cd13823a0602568394be93bf310Jason parks cooldown(); 316ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks } else { 317ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks TextView tv = (TextView) findViewById(R.id.status); 318ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks tv.setText(R.string.try_again); 31913d62049f7c96c47356f23eaee7f0997612fdf9fAndy Stadler tv.setVisibility(View.VISIBLE); 320ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks } 3218fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks } catch (Exception e) { 322ec5a45e79cb7161adfabf475342c1e1b25994276Jason parks Log.e(TAG, "Error while decrypting...", e); 3238fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks } 32435933812b16f0b4221280bbcc3c32f6540996bf2Jason parks 3258fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks return true; 3268fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks } 3278fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks return false; 3288fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks } 3298fd5bc9e6ff0d02012df670a6bf4bcdaf903c09dJason parks}