summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/CryptKeeper.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/settings/CryptKeeper.java')
-rw-r--r--src/com/android/settings/CryptKeeper.java173
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);
+ }
+ }
}