diff options
Diffstat (limited to 'src/com/android/settings/CryptKeeper.java')
-rw-r--r-- | src/com/android/settings/CryptKeeper.java | 173 |
1 files changed, 138 insertions, 35 deletions
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java index 45b4ff1..cfb27e1 100644 --- a/src/com/android/settings/CryptKeeper.java +++ b/src/com/android/settings/CryptKeeper.java @@ -48,6 +48,8 @@ import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; import android.view.View.OnClickListener; import android.view.View.OnKeyListener; import android.view.View.OnTouchListener; @@ -66,6 +68,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockPatternView.Cell; +import java.util.ArrayList; import java.util.List; import static com.android.internal.widget.LockPatternView.DisplayMode; @@ -84,7 +87,7 @@ import static com.android.internal.widget.LockPatternView.DisplayMode; * </pre> */ public class CryptKeeper extends Activity implements TextView.OnEditorActionListener, - OnKeyListener, OnTouchListener, TextWatcher { + OnKeyListener, OnTouchListener, TextWatcher, OnClickListener { private static final String TAG = "CryptKeeper"; private static final String DECRYPT_STATE = "trigger_restart_framework"; @@ -115,6 +118,8 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList private boolean mEncryptionGoneBad; /** If gone bad, should we show encryption failed (false) or corrupt (true)*/ private boolean mCorrupt; + /** If gone bad and mdtp is activated we should not allow recovery screen, only wipe the data */ + private boolean mMdtpActivated; /** A flag to indicate when the back event should be ignored */ /** When set, blocks unlocking. Set every COOL_DOWN_ATTEMPTS attempts, only cleared by power cycling phone. */ @@ -123,6 +128,15 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList PowerManager.WakeLock mWakeLock; private EditText mPasswordEntry; private LockPatternView mLockPatternView; + private TextView mStatusText; + private List<Button> mLockPatternButtons = new ArrayList<>(); + private static final int[] LOCK_BUTTON_IDS = new int[] { + R.id.lock_pattern_size_3, + R.id.lock_pattern_size_4, + R.id.lock_pattern_size_5, + R.id.lock_pattern_size_6 + }; + /** Number of calls to {@link #notifyUser()} to ignore before notifying. */ private int mNotificationCountdown = 0; /** Number of calls to {@link #notifyUser()} before we release the wakelock */ @@ -176,6 +190,9 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList @Override protected void onPreExecute() { super.onPreExecute(); + if (mLockPatternView != null) { + mLockPatternView.removeCallbacks(mFakeUnlockAttemptRunnable); + } beginAttempt(); } @@ -199,23 +216,36 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList mLockPatternView.removeCallbacks(mClearPatternRunnable); mLockPatternView.postDelayed(mClearPatternRunnable, RIGHT_PATTERN_CLEAR_TIMEOUT_MS); } - final TextView status = (TextView) findViewById(R.id.status); - status.setText(R.string.starting_android); + mStatusText.setText(R.string.starting_android); hide(R.id.passwordEntry); hide(R.id.switch_ime_button); hide(R.id.lockPattern); hide(R.id.owner_info); hide(R.id.emergencyCallButton); + hide(R.id.pattern_sizes); } else if (failedAttempts == MAX_FAILED_ATTEMPTS) { // Factory reset the device. - Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); - intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); - intent.putExtra(Intent.EXTRA_REASON, "CryptKeeper.MAX_FAILED_ATTEMPTS"); - sendBroadcast(intent); + if(mMdtpActivated){ + Log.d(TAG, + " CryptKeeper.MAX_FAILED_ATTEMPTS, calling encryptStorage with wipe"); + try { + final IMountService service = getMountService(); + service.encryptWipeStorage(StorageManager.CRYPT_TYPE_DEFAULT, ""); + + } catch (RemoteException e) { + Log.w(TAG, "Unable to call MountService properly"); + return; + } + } else { + Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); + intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + intent.putExtra(Intent.EXTRA_REASON, "CryptKeeper.MAX_FAILED_ATTEMPTS"); + sendBroadcast(intent); + } } else if (failedAttempts == -1) { // Right password, but decryption failed. Tell user bad news ... setContentView(R.layout.crypt_keeper_progress); - showFactoryReset(true); + showFactoryReset(true, false); return; } else { handleBadAttempt(failedAttempts); @@ -224,8 +254,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList } private void beginAttempt() { - final TextView status = (TextView) findViewById(R.id.status); - status.setText(R.string.checking_decryption); + mStatusText.setText(R.string.checking_decryption); } private void handleBadAttempt(Integer failedAttempts) { @@ -241,14 +270,12 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList // at this point. cooldown(); } else { - final TextView status = (TextView) findViewById(R.id.status); - int remainingAttempts = MAX_FAILED_ATTEMPTS - failedAttempts; if (remainingAttempts < COOL_DOWN_ATTEMPTS) { CharSequence warningTemplate = getText(R.string.crypt_keeper_warn_wipe); CharSequence warning = TextUtils.expandTemplate(warningTemplate, Integer.toString(remainingAttempts)); - status.setText(warning); + mStatusText.setText(warning); } else { int passwordType = StorageManager.CRYPT_TYPE_PASSWORD; try { @@ -259,17 +286,18 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList } if (passwordType == StorageManager.CRYPT_TYPE_PIN) { - status.setText(R.string.cryptkeeper_wrong_pin); + mStatusText.setText(R.string.cryptkeeper_wrong_pin); } else if (passwordType == StorageManager.CRYPT_TYPE_PATTERN) { - status.setText(R.string.cryptkeeper_wrong_pattern); + mStatusText.setText(R.string.cryptkeeper_wrong_pattern); } else { - status.setText(R.string.cryptkeeper_wrong_password); + mStatusText.setText(R.string.cryptkeeper_wrong_password); } } if (mLockPatternView != null) { mLockPatternView.setDisplayMode(DisplayMode.Wrong); mLockPatternView.setEnabled(true); + setPatternButtonsEnabled(true); } // Reenable the password entry @@ -296,10 +324,13 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList Log.w(TAG, "Unexpectedly in CryptKeeper even though there is no encryption."); return true; // Unexpected, but fine, I guess... } - return state == IMountService.ENCRYPTION_STATE_OK; + mMdtpActivated = (state == IMountService.ENCRYPTION_STATE_ERROR_MDTP_ACTIVATED) || + (state == IMountService.ENCRYPTION_STATE_OK_MDTP_ACTIVATED); + return (state == IMountService.ENCRYPTION_STATE_OK) || + (state == IMountService.ENCRYPTION_STATE_OK_MDTP_ACTIVATED); } catch (RemoteException e) { Log.w(TAG, "Unable to get encryption state properly"); - return true; + return false; } } @@ -400,6 +431,13 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar + | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar + | View.SYSTEM_UI_FLAG_IMMERSIVE); + // If we are not encrypted or encrypting, get out quickly. final String state = SystemProperties.get("vold.decrypt"); if (!isDebugView() && ("".equals(state) || DECRYPT_STATE.equals(state))) { @@ -456,7 +494,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList private void setupUi() { if (mEncryptionGoneBad || isDebugView(FORCE_VIEW_ERROR)) { setContentView(R.layout.crypt_keeper_progress); - showFactoryReset(mCorrupt); + showFactoryReset(mCorrupt, mMdtpActivated); return; } @@ -502,8 +540,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList setContentView(R.layout.crypt_keeper_password_entry); mStatusString = R.string.enter_password; } - final TextView status = (TextView) findViewById(R.id.status); - status.setText(mStatusString); + mStatusText.setText(mStatusString); final TextView ownerInfo = (TextView) findViewById(R.id.owner_info); ownerInfo.setText(owner_info); @@ -562,6 +599,12 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList } } + @Override + public void setContentView(int layoutResID) { + super.setContentView(layoutResID); + mStatusText = (TextView) findViewById(R.id.status); + } + /** * Start encrypting the device. */ @@ -590,8 +633,10 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList * there is nothing else we can do * @param corrupt true if userdata is corrupt, false if encryption failed * partway through + * @param mdtp_activated true if MDTP is activated according to MountService + * state. */ - private void showFactoryReset(final boolean corrupt) { + private void showFactoryReset(final boolean corrupt, final boolean mdtp_activated) { // Hide the encryption-bot to make room for the "factory reset" button findViewById(R.id.encroid).setVisibility(View.GONE); @@ -601,12 +646,24 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - // Factory reset the device. - Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); - intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); - intent.putExtra(Intent.EXTRA_REASON, - "CryptKeeper.showFactoryReset() corrupt=" + corrupt); - sendBroadcast(intent); + if(mdtp_activated){ + Log.d(TAG, " Calling encryptStorage with wipe"); + try { + final IMountService service = getMountService(); + service.encryptWipeStorage(StorageManager.CRYPT_TYPE_DEFAULT, ""); + + } catch (RemoteException e) { + Log.w(TAG, "Unable to call MountService properly"); + return; + } + } else { + // Factory reset the device. + Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR); + intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + intent.putExtra(Intent.EXTRA_REASON, + "CryptKeeper.showFactoryReset() corrupt=" + corrupt); + sendBroadcast(intent); + } } }); @@ -630,7 +687,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList final String state = SystemProperties.get("vold.encrypt_progress"); if ("error_partially_encrypted".equals(state)) { - showFactoryReset(false); + showFactoryReset(false, false); return; } @@ -660,9 +717,8 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList // Will happen if no time etc - show percentage } - final TextView tv = (TextView) findViewById(R.id.status); - if (tv != null) { - tv.setText(TextUtils.expandTemplate(status, progress)); + if (mStatusText != null) { + mStatusText.setText(TextUtils.expandTemplate(status, progress)); } // Check the progress every 1 seconds @@ -678,12 +734,13 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList if (mPasswordEntry != null) { mPasswordEntry.setEnabled(false); } + if (mLockPatternView != null) { mLockPatternView.setEnabled(false); + setPatternButtonsEnabled(false); } - final TextView status = (TextView) findViewById(R.id.status); - status.setText(R.string.crypt_keeper_force_power_cycle); + mStatusText.setText(R.string.crypt_keeper_force_power_cycle); } /** @@ -708,18 +765,21 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList @Override public void onPatternStart() { + setPatternButtonsEnabled(false); mLockPatternView.removeCallbacks(mClearPatternRunnable); } @Override public void onPatternCleared() { + setPatternButtonsEnabled(true); } @Override public void onPatternDetected(List<LockPatternView.Cell> pattern) { mLockPatternView.setEnabled(false); if (pattern.size() >= MIN_LENGTH_BEFORE_REPORT) { - new DecryptTask().execute(LockPatternUtils.patternToString(pattern)); + new DecryptTask().execute(LockPatternUtils.patternToString(pattern, + mLockPatternView.getLockPatternSize())); } else { // Allow user to make as many of these as they want. fakeUnlockAttempt(mLockPatternView); @@ -743,10 +803,18 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList mPasswordEntry.addTextChangedListener(this); } + mLockPatternButtons.clear(); // Pattern case mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern); if (mLockPatternView != null) { mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener); + for (int id : LOCK_BUTTON_IDS) { + Button btn = (Button) findViewById(id); + if (btn != null) { + btn.setOnClickListener(this); + mLockPatternButtons.add(btn); + } + } } // Disable the Emergency call button if the device has no voice telephone capability @@ -1026,4 +1094,39 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); } + + @Override + public void onClick(View v) { + if (mLockPatternView == null || !mLockPatternView.isEnabled()) { + return; + } + byte size; + switch (v.getId()) { + default: + case R.id.lock_pattern_size_3: + size = 3; + break; + case R.id.lock_pattern_size_4: + size = 4; + break; + case R.id.lock_pattern_size_5: + size = 5; + break; + case R.id.lock_pattern_size_6: + size = 6; + break; + } + setContentView(R.layout.crypt_keeper_pattern_entry); + passwordEntryInit(); + + mStatusText.setText(mStatusString = R.string.enter_pattern); + mLockPatternView.setLockPatternSize(size); + mLockPatternView.postInvalidate(); + } + + private void setPatternButtonsEnabled(boolean enabled) { + for (Button btn : mLockPatternButtons) { + btn.setEnabled(enabled); + } + } } |