+ android:title="@string/encryption_settings_title">
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
deleted file mode 100644
index 7e75ee27851..00000000000
--- a/src/com/android/settings/CryptKeeper.java
+++ /dev/null
@@ -1,1034 +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.Activity;
-import android.app.StatusBarManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources.NotFoundException;
-import android.media.AudioManager;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.os.storage.IStorageManager;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.sysprop.VoldProperties;
-import android.telecom.TelecomManager;
-import android.telephony.TelephonyManager;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnKeyListener;
-import android.view.View.OnTouchListener;
-import android.view.WindowManager;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
-import android.widget.Button;
-import android.widget.ImeAwareEditText;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternView;
-import com.android.internal.widget.LockPatternView.Cell;
-import com.android.internal.widget.LockPatternView.DisplayMode;
-
-import java.util.List;
-
-/**
- * Settings screens to show the UI flows for encrypting/decrypting the device.
- *
- * This may be started via adb for debugging the UI layout, without having to go through
- * encryption flows everytime. It should be noted that starting the activity in this manner
- * is only useful for verifying UI-correctness - the behavior will not be identical.
- *
- * $ adb shell pm enable com.android.settings/.CryptKeeper
- * $ adb shell am start \
- * -e "com.android.settings.CryptKeeper.DEBUG_FORCE_VIEW" "progress" \
- * -n com.android.settings/.CryptKeeper
- *
- */
-public class CryptKeeper extends Activity implements TextView.OnEditorActionListener,
- OnKeyListener, OnTouchListener, TextWatcher {
- private static final String TAG = "CryptKeeper";
-
- private static final String DECRYPT_STATE = "trigger_restart_framework";
-
- /** Message sent to us to indicate encryption update progress. */
- private static final int MESSAGE_UPDATE_PROGRESS = 1;
- /** Message sent to us to indicate alerting the user that we are waiting for password entry */
- private static final int MESSAGE_NOTIFY = 2;
-
- // Constants used to control policy.
- private static final int MAX_FAILED_ATTEMPTS = 30;
- private static final int COOL_DOWN_ATTEMPTS = 10;
-
- // Intent action for launching the Emergency Dialer activity.
- static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
-
- // Debug Intent extras so that this Activity may be started via adb for debugging UI layouts
- private static final String EXTRA_FORCE_VIEW =
- "com.android.settings.CryptKeeper.DEBUG_FORCE_VIEW";
- private static final String FORCE_VIEW_PROGRESS = "progress";
- private static final String FORCE_VIEW_ERROR = "error";
- private static final String FORCE_VIEW_PASSWORD = "password";
-
- private static final String STATE_COOLDOWN = "cooldown";
-
- /** When encryption is detected, this flag indicates whether or not we've checked for errors. */
- private boolean mValidationComplete;
- private boolean mValidationRequested;
- /** A flag to indicate that the volume is in a bad state (e.g. partially encrypted). */
- private boolean mEncryptionGoneBad;
- /** If gone bad, should we show encryption failed (false) or corrupt (true)*/
- private boolean mCorrupt;
- /** 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. */
- private boolean mCooldown = false;
-
- PowerManager.WakeLock mWakeLock;
- private ImeAwareEditText mPasswordEntry;
- private LockPatternView mLockPatternView;
- /** 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 */
- private int mReleaseWakeLockCountdown = 0;
- private int mStatusString = R.string.enter_password;
-
- // how long we wait to clear a wrong pattern
- private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 1500;
-
- // how long we wait to clear a right pattern
- private static final int RIGHT_PATTERN_CLEAR_TIMEOUT_MS = 500;
-
- // When the user enters a short pin/password, run this to show an error,
- // but don't count it against attempts.
- private final Runnable mFakeUnlockAttemptRunnable = new Runnable() {
- @Override
- public void run() {
- handleBadAttempt(1 /* failedAttempt */);
- }
- };
-
- // TODO: this should be tuned to match minimum decryption timeout
- private static final int FAKE_ATTEMPT_DELAY = 1000;
-
- private final Runnable mClearPatternRunnable = new Runnable() {
- @Override
- public void run() {
- mLockPatternView.clearPattern();
- }
- };
-
- /**
- * Used to propagate state through configuration changes (e.g. screen rotation)
- */
- private static class NonConfigurationInstanceState {
- final PowerManager.WakeLock wakelock;
-
- NonConfigurationInstanceState(PowerManager.WakeLock _wakelock) {
- wakelock = _wakelock;
- }
- }
-
- private class DecryptTask extends AsyncTask {
- private void hide(int id) {
- View view = findViewById(id);
- if (view != null) {
- view.setVisibility(View.GONE);
- }
- }
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- beginAttempt();
- }
-
- @Override
- protected Integer doInBackground(String... params) {
- final IStorageManager service = getStorageManager();
- try {
- return service.decryptStorage(params[0]);
- } catch (Exception e) {
- Log.e(TAG, "Error while decrypting...", e);
- return -1;
- }
- }
-
- @Override
- protected void onPostExecute(Integer failedAttempts) {
- if (failedAttempts == 0) {
- // The password was entered successfully. Simply do nothing
- // and wait for the service restart to switch to surfacefligner
- if (mLockPatternView != null) {
- 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);
- hide(R.id.passwordEntry);
- hide(R.id.switch_ime_button);
- hide(R.id.lockPattern);
- hide(R.id.owner_info);
- hide(R.id.emergencyCallButton);
- } else if (failedAttempts == MAX_FAILED_ATTEMPTS) {
- // Factory reset the device.
- Intent intent = new Intent(Intent.ACTION_FACTORY_RESET);
- intent.setPackage("android");
- 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);
- return;
- } else {
- handleBadAttempt(failedAttempts);
- }
- }
- }
-
- private void beginAttempt() {
- final TextView status = (TextView) findViewById(R.id.status);
- status.setText(R.string.checking_decryption);
- }
-
- private void handleBadAttempt(Integer failedAttempts) {
- // Wrong entry. Handle pattern case.
- if (mLockPatternView != null) {
- mLockPatternView.setDisplayMode(DisplayMode.Wrong);
- mLockPatternView.removeCallbacks(mClearPatternRunnable);
- mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
- }
- if ((failedAttempts % COOL_DOWN_ATTEMPTS) == 0) {
- mCooldown = true;
- // No need to setBackFunctionality(false) - it's already done
- // 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);
- } else {
- int passwordType = StorageManager.CRYPT_TYPE_PASSWORD;
- try {
- final IStorageManager service = getStorageManager();
- passwordType = service.getPasswordType();
- } catch (Exception e) {
- Log.e(TAG, "Error calling mount service " + e);
- }
-
- if (passwordType == StorageManager.CRYPT_TYPE_PIN) {
- status.setText(R.string.cryptkeeper_wrong_pin);
- } else if (passwordType == StorageManager.CRYPT_TYPE_PATTERN) {
- status.setText(R.string.cryptkeeper_wrong_pattern);
- } else {
- status.setText(R.string.cryptkeeper_wrong_password);
- }
- }
-
- if (mLockPatternView != null) {
- mLockPatternView.setDisplayMode(DisplayMode.Wrong);
- mLockPatternView.setEnabled(true);
- }
-
- // Reenable the password entry
- if (mPasswordEntry != null) {
- mPasswordEntry.setEnabled(true);
- mPasswordEntry.scheduleShowSoftInput();
- setBackFunctionality(true);
- }
- }
- }
-
- private class ValidationTask extends AsyncTask {
- int state;
-
- @Override
- protected Boolean doInBackground(Void... params) {
- final IStorageManager service = getStorageManager();
- try {
- Log.d(TAG, "Validating encryption state.");
- state = service.getEncryptionState();
- if (state == StorageManager.ENCRYPTION_STATE_NONE) {
- Log.w(TAG, "Unexpectedly in CryptKeeper even though there is no encryption.");
- return true; // Unexpected, but fine, I guess...
- }
- return state == StorageManager.ENCRYPTION_STATE_OK;
- } catch (RemoteException e) {
- Log.w(TAG, "Unable to get encryption state properly");
- return true;
- }
- }
-
- @Override
- protected void onPostExecute(Boolean result) {
- mValidationComplete = true;
- if (Boolean.FALSE.equals(result)) {
- Log.w(TAG, "Incomplete, or corrupted encryption detected. Prompting user to wipe.");
- mEncryptionGoneBad = true;
- mCorrupt = state == StorageManager.ENCRYPTION_STATE_ERROR_CORRUPT;
- } else {
- Log.d(TAG, "Encryption state validated. Proceeding to configure UI");
- }
- setupUi();
- }
- }
-
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_UPDATE_PROGRESS:
- updateProgress();
- break;
-
- case MESSAGE_NOTIFY:
- notifyUser();
- break;
- }
- }
- };
-
- private AudioManager mAudioManager;
- /** The status bar where back/home/recent buttons are shown. */
- private StatusBarManager mStatusBar;
-
- /** All the widgets to disable in the status bar */
- final private static int sWidgetsToDisable = StatusBarManager.DISABLE_EXPAND
- | StatusBarManager.DISABLE_NOTIFICATION_ICONS
- | StatusBarManager.DISABLE_NOTIFICATION_ALERTS
- | StatusBarManager.DISABLE_HOME
- | StatusBarManager.DISABLE_SEARCH
- | StatusBarManager.DISABLE_RECENT;
-
- protected static final int MIN_LENGTH_BEFORE_REPORT = LockPatternUtils.MIN_LOCK_PATTERN_SIZE;
-
- /** @return whether or not this Activity was started for debugging the UI only. */
- private boolean isDebugView() {
- return getIntent().hasExtra(EXTRA_FORCE_VIEW);
- }
-
- /** @return whether or not this Activity was started for debugging the specific UI view only. */
- private boolean isDebugView(String viewType /* non-nullable */) {
- return viewType.equals(getIntent().getStringExtra(EXTRA_FORCE_VIEW));
- }
-
- /**
- * Notify the user that we are awaiting input. Currently this sends an audio alert.
- */
- private void notifyUser() {
- if (mNotificationCountdown > 0) {
- --mNotificationCountdown;
- } else if (mAudioManager != null) {
- try {
- // Play the standard keypress sound at full volume. This should be available on
- // every device. We cannot play a ringtone here because media services aren't
- // available yet. A DTMF-style tone is too soft to be noticed, and might not exist
- // on tablet devices. The idea is to alert the user that something is needed: this
- // does not have to be pleasing.
- mAudioManager.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD, 100);
- } catch (Exception e) {
- Log.w(TAG, "notifyUser: Exception while playing sound: " + e);
- }
- }
- // Notify the user again in 5 seconds.
- mHandler.removeMessages(MESSAGE_NOTIFY);
- mHandler.sendEmptyMessageDelayed(MESSAGE_NOTIFY, 5 * 1000);
-
- if (mWakeLock.isHeld()) {
- if (mReleaseWakeLockCountdown > 0) {
- --mReleaseWakeLockCountdown;
- } else {
- mWakeLock.release();
- }
- }
- }
-
- /**
- * Ignore back events from this activity always - there's nowhere to go back
- * to
- */
- @Override
- public void onBackPressed() {
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // If we are not encrypted or encrypting, get out quickly.
- final String state = VoldProperties.decrypt().orElse("");
- if (!isDebugView() && ("".equals(state) || DECRYPT_STATE.equals(state))) {
- disableCryptKeeperComponent(this);
- // Typically CryptKeeper is launched as the home app. We didn't
- // want to be running, so need to finish this activity. We can count
- // on the activity manager re-launching the new home app upon finishing
- // this one, since this will leave the activity stack empty.
- // NOTE: This is really grungy. I think it would be better for the
- // activity manager to explicitly launch the crypt keeper instead of
- // home in the situation where we need to decrypt the device
- finish();
- return;
- }
-
- try {
- if (getResources().getBoolean(R.bool.crypt_keeper_allow_rotation)) {
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- }
- } catch (NotFoundException e) {
- }
-
- // Disable the status bar, but do NOT disable back because the user needs a way to go
- // from keyboard settings and back to the password screen.
- mStatusBar = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
- mStatusBar.disable(sWidgetsToDisable);
-
- if (savedInstanceState != null) {
- mCooldown = savedInstanceState.getBoolean(STATE_COOLDOWN);
- }
-
- setAirplaneModeIfNecessary();
- mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- // Check for (and recover) retained instance data
- final Object lastInstance = getLastNonConfigurationInstance();
- if (lastInstance instanceof NonConfigurationInstanceState) {
- NonConfigurationInstanceState retained = (NonConfigurationInstanceState) lastInstance;
- mWakeLock = retained.wakelock;
- Log.d(TAG, "Restoring wakelock from NonConfigurationInstanceState");
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle savedInstanceState) {
- savedInstanceState.putBoolean(STATE_COOLDOWN, mCooldown);
- }
-
- /**
- * Note, we defer the state check and screen setup to onStart() because this will be
- * re-run if the user clicks the power button (sleeping/waking the screen), and this is
- * especially important if we were to lose the wakelock for any reason.
- */
- @Override
- public void onStart() {
- super.onStart();
- setupUi();
- }
-
- /**
- * Initializes the UI based on the current state of encryption.
- * This is idempotent - calling repeatedly will simply re-initialize the UI.
- */
- private void setupUi() {
- if (mEncryptionGoneBad || isDebugView(FORCE_VIEW_ERROR)) {
- setContentView(R.layout.crypt_keeper_progress);
- showFactoryReset(mCorrupt);
- return;
- }
-
- final String progress = VoldProperties.encrypt_progress().orElse("");
- if (!"".equals(progress) || isDebugView(FORCE_VIEW_PROGRESS)) {
- setContentView(R.layout.crypt_keeper_progress);
- encryptionProgressInit();
- } else if (mValidationComplete || isDebugView(FORCE_VIEW_PASSWORD)) {
- new AsyncTask() {
- int passwordType = StorageManager.CRYPT_TYPE_PASSWORD;
- String owner_info;
- boolean pattern_visible;
- boolean password_visible;
-
- @Override
- public Void doInBackground(Void... v) {
- try {
- final IStorageManager service = getStorageManager();
- passwordType = service.getPasswordType();
- owner_info = service.getField(StorageManager.OWNER_INFO_KEY);
- pattern_visible = !("0".equals(service.getField(StorageManager.PATTERN_VISIBLE_KEY)));
- password_visible = !("0".equals(service.getField(StorageManager.PASSWORD_VISIBLE_KEY)));
- } catch (Exception e) {
- Log.e(TAG, "Error calling mount service " + e);
- }
-
- return null;
- }
-
- @Override
- public void onPostExecute(java.lang.Void v) {
- Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
- password_visible ? 1 : 0);
-
- if (passwordType == StorageManager.CRYPT_TYPE_PIN) {
- setContentView(R.layout.crypt_keeper_pin_entry);
- mStatusString = R.string.enter_pin;
- } else if (passwordType == StorageManager.CRYPT_TYPE_PATTERN) {
- setContentView(R.layout.crypt_keeper_pattern_entry);
- setBackFunctionality(false);
- mStatusString = R.string.enter_pattern;
- } else {
- setContentView(R.layout.crypt_keeper_password_entry);
- mStatusString = R.string.enter_password;
- }
- final TextView status = (TextView) findViewById(R.id.status);
- status.setText(mStatusString);
-
- final TextView ownerInfo = (TextView) findViewById(R.id.owner_info);
- ownerInfo.setText(owner_info);
- ownerInfo.setSelected(true); // Required for marquee'ing to work
-
- passwordEntryInit();
-
- findViewById(android.R.id.content).setSystemUiVisibility(View.STATUS_BAR_DISABLE_BACK);
-
- if (mLockPatternView != null) {
- mLockPatternView.setInStealthMode(!pattern_visible);
- }
- if (mCooldown) {
- // in case we are cooling down and coming back from emergency dialler
- setBackFunctionality(false);
- cooldown();
- }
-
- }
- }.execute();
- } else if (!mValidationRequested) {
- // We're supposed to be encrypted, but no validation has been done.
- new ValidationTask().execute((Void[]) null);
- mValidationRequested = true;
- }
- }
-
- @Override
- public void onStop() {
- super.onStop();
- mHandler.removeMessages(MESSAGE_UPDATE_PROGRESS);
- mHandler.removeMessages(MESSAGE_NOTIFY);
- }
-
- /**
- * Reconfiguring, so propagate the wakelock to the next instance. This runs between onStop()
- * and onDestroy() and only if we are changing configuration (e.g. rotation). Also clears
- * mWakeLock so the subsequent call to onDestroy does not release it.
- */
- @Override
- public Object onRetainNonConfigurationInstance() {
- NonConfigurationInstanceState state = new NonConfigurationInstanceState(mWakeLock);
- Log.d(TAG, "Handing wakelock off to NonConfigurationInstanceState");
- mWakeLock = null;
- return state;
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- if (mWakeLock != null) {
- Log.d(TAG, "Releasing and destroying wakelock");
- mWakeLock.release();
- mWakeLock = null;
- }
- }
-
- /**
- * Start encrypting the device.
- */
- 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.
- Log.d(TAG, "Encryption progress screen initializing.");
- if (mWakeLock == null) {
- Log.d(TAG, "Acquiring wakelock.");
- PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
- mWakeLock.acquire();
- }
-
- ((ProgressBar) findViewById(R.id.progress_bar)).setIndeterminate(true);
- // Ignore all back presses from now, both hard and soft keys.
- setBackFunctionality(false);
- // Start the first run of progress manually. This method sets up messages to occur at
- // repeated intervals.
- updateProgress();
- }
-
- /**
- * Show factory reset screen allowing the user to reset their phone when
- * there is nothing else we can do
- * @param corrupt true if userdata is corrupt, false if encryption failed
- * partway through
- */
- private void showFactoryReset(final boolean corrupt) {
- // Hide the encryption-bot to make room for the "factory reset" button
- findViewById(R.id.encroid).setVisibility(View.GONE);
-
- // Show the reset button, failure text, and a divider
- final Button button = (Button) findViewById(R.id.factory_reset);
- button.setVisibility(View.VISIBLE);
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // Factory reset the device.
- Intent intent = new Intent(Intent.ACTION_FACTORY_RESET);
- intent.setPackage("android");
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- intent.putExtra(Intent.EXTRA_REASON,
- "CryptKeeper.showFactoryReset() corrupt=" + corrupt);
- sendBroadcast(intent);
- }
- });
-
- // Alert the user of the failure.
- if (corrupt) {
- ((TextView) findViewById(R.id.title)).setText(R.string.crypt_keeper_data_corrupt_title);
- ((TextView) findViewById(R.id.status)).setText(R.string.crypt_keeper_data_corrupt_summary);
- } else {
- ((TextView) findViewById(R.id.title)).setText(R.string.crypt_keeper_failed_title);
- ((TextView) findViewById(R.id.status)).setText(R.string.crypt_keeper_failed_summary);
- }
-
- final View view = findViewById(R.id.bottom_divider);
- // TODO(viki): Why would the bottom divider be missing in certain layouts? Investigate.
- if (view != null) {
- view.setVisibility(View.VISIBLE);
- }
- }
-
- private void updateProgress() {
- final String state = VoldProperties.encrypt_progress().orElse("");
-
- if ("error_partially_encrypted".equals(state)) {
- showFactoryReset(false);
- return;
- }
-
- // Get status as percentage first
- CharSequence status = getText(R.string.crypt_keeper_setup_description);
- int percent = 0;
- try {
- // Force a 50% progress state when debugging the view.
- percent = isDebugView() ? 50 : Integer.parseInt(state);
- } catch (Exception e) {
- Log.w(TAG, "Error parsing progress: " + e.toString());
- }
- String progress = Integer.toString(percent);
-
- // Now try to get status as time remaining and replace as appropriate
- Log.v(TAG, "Encryption progress: " + progress);
- try {
- int time = VoldProperties.encrypt_time_remaining().get();
- if (time >= 0) {
- // Round up to multiple of 10 - this way display is less jerky
- time = (time + 9) / 10 * 10;
- progress = DateUtils.formatElapsedTime(time);
- status = getText(R.string.crypt_keeper_setup_time_remaining);
- }
- } catch (Exception e) {
- // 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));
- }
-
- // Check the progress every 1 seconds
- mHandler.removeMessages(MESSAGE_UPDATE_PROGRESS);
- mHandler.sendEmptyMessageDelayed(MESSAGE_UPDATE_PROGRESS, 1000);
- }
-
- /** Insist on a power cycle to force the user to waste time between retries.
- *
- * Call setBackFunctionality(false) before calling this. */
- private void cooldown() {
- // Disable the password entry.
- if (mPasswordEntry != null) {
- mPasswordEntry.setEnabled(false);
- }
- if (mLockPatternView != null) {
- mLockPatternView.setEnabled(false);
- }
-
- final TextView status = (TextView) findViewById(R.id.status);
- status.setText(R.string.crypt_keeper_force_power_cycle);
- }
-
- /**
- * Sets the back status: enabled or disabled according to the parameter.
- * @param isEnabled true if back is enabled, false otherwise.
- */
- private final void setBackFunctionality(boolean isEnabled) {
- if (isEnabled) {
- mStatusBar.disable(sWidgetsToDisable);
- } else {
- mStatusBar.disable(sWidgetsToDisable | StatusBarManager.DISABLE_BACK);
- }
- }
-
- private void fakeUnlockAttempt(View postingView) {
- beginAttempt();
- postingView.postDelayed(mFakeUnlockAttemptRunnable, FAKE_ATTEMPT_DELAY);
- }
-
- protected LockPatternView.OnPatternListener mChooseNewLockPatternListener =
- new LockPatternView.OnPatternListener() {
-
- @Override
- public void onPatternStart() {
- mLockPatternView.removeCallbacks(mClearPatternRunnable);
- }
-
- @Override
- public void onPatternCleared() {
- }
-
- @Override
- public void onPatternDetected(List pattern) {
- mLockPatternView.setEnabled(false);
- if (pattern.size() >= MIN_LENGTH_BEFORE_REPORT) {
- new DecryptTask().execute(new String(LockPatternUtils.patternToByteArray(pattern)));
- } else {
- // Allow user to make as many of these as they want.
- fakeUnlockAttempt(mLockPatternView);
- }
- }
-
- @Override
- public void onPatternCellAdded(List pattern) {
- }
- };
-
- private void passwordEntryInit() {
- // Password/pin case
- mPasswordEntry = (ImeAwareEditText) findViewById(R.id.passwordEntry);
- if (mPasswordEntry != null){
- mPasswordEntry.setOnEditorActionListener(this);
- mPasswordEntry.requestFocus();
- // Become quiet when the user interacts with the Edit text screen.
- mPasswordEntry.setOnKeyListener(this);
- mPasswordEntry.setOnTouchListener(this);
- mPasswordEntry.addTextChangedListener(this);
- }
-
- // Pattern case
- mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
- if (mLockPatternView != null) {
- mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
- }
-
- // Disable the Emergency call button if the device has no voice telephone capability
- if (!getTelephonyManager().isVoiceCapable()) {
- final View emergencyCall = findViewById(R.id.emergencyCallButton);
- if (emergencyCall != null) {
- Log.d(TAG, "Removing the emergency Call button");
- emergencyCall.setVisibility(View.GONE);
- }
- }
-
- final View imeSwitcher = findViewById(R.id.switch_ime_button);
- final InputMethodManager imm = (InputMethodManager) getSystemService(
- Context.INPUT_METHOD_SERVICE);
- if (imeSwitcher != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) {
- imeSwitcher.setVisibility(View.VISIBLE);
- imeSwitcher.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- imm.showInputMethodPickerFromSystem(false /* showAuxiliarySubtypes */,
- v.getDisplay().getDisplayId());
- }
- });
- }
-
- // We want to keep the screen on while waiting for input. In minimal boot mode, the device
- // is completely non-functional, and we want the user to notice the device and enter a
- // password.
- if (mWakeLock == null) {
- Log.d(TAG, "Acquiring wakelock.");
- final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
- if (pm != null) {
- mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
- mWakeLock.acquire();
- // Keep awake for 10 minutes - if the user hasn't been alerted by then
- // best not to just drain their battery
- mReleaseWakeLockCountdown = 96; // 96 * 5 secs per click + 120 secs before we show this = 600
- }
- }
-
- // Make sure that the IME is shown when everything becomes ready.
- if (mLockPatternView == null && !mCooldown) {
- getWindow().setSoftInputMode(
- WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
- if (mPasswordEntry != null) {
- mPasswordEntry.scheduleShowSoftInput();
- }
- }
-
- updateEmergencyCallButtonState();
- // Notify the user in 120 seconds that we are waiting for him to enter the password.
- mHandler.removeMessages(MESSAGE_NOTIFY);
- mHandler.sendEmptyMessageDelayed(MESSAGE_NOTIFY, 120 * 1000);
-
- // Dismiss secure & non-secure keyguards while this screen is showing.
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
- | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
- }
-
- /**
- * Method adapted from com.android.inputmethod.latin.Utils
- *
- * @param imm The input method manager
- * @param shouldIncludeAuxiliarySubtypes
- * @return true if we have multiple IMEs to choose from
- */
- private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
- final boolean shouldIncludeAuxiliarySubtypes) {
- final List enabledImis = imm.getEnabledInputMethodList();
-
- // Number of the filtered IMEs
- int filteredImisCount = 0;
-
- for (InputMethodInfo imi : enabledImis) {
- // We can return true immediately after we find two or more filtered IMEs.
- if (filteredImisCount > 1) return true;
- final List subtypes =
- imm.getEnabledInputMethodSubtypeList(imi, true);
- // IMEs that have no subtypes should be counted.
- if (subtypes.isEmpty()) {
- ++filteredImisCount;
- continue;
- }
-
- int auxCount = 0;
- for (InputMethodSubtype subtype : subtypes) {
- if (subtype.isAuxiliary()) {
- ++auxCount;
- }
- }
- final int nonAuxCount = subtypes.size() - auxCount;
-
- // IMEs that have one or more non-auxiliary subtypes should be counted.
- // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
- // subtypes should be counted as well.
- if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
- ++filteredImisCount;
- continue;
- }
- }
-
- return filteredImisCount > 1
- // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
- // input method subtype (The current IME should be LatinIME.)
- || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
- }
-
- private IStorageManager getStorageManager() {
- final IBinder service = ServiceManager.getService("mount");
- if (service != null) {
- return IStorageManager.Stub.asInterface(service);
- }
- return null;
- }
-
- @Override
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE) {
- // Get the password
- final String password = v.getText().toString();
-
- if (TextUtils.isEmpty(password)) {
- return true;
- }
-
- // Now that we have the password clear the password field.
- v.setText(null);
-
- // Disable the password entry and back keypress while checking the password. These
- // we either be re-enabled if the password was wrong or after the cooldown period.
- mPasswordEntry.setEnabled(false);
- setBackFunctionality(false);
-
- if (password.length() >= LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) {
- new DecryptTask().execute(password);
- } else {
- // Allow user to make as many of these as they want.
- fakeUnlockAttempt(mPasswordEntry);
- }
-
- return true;
- }
- return false;
- }
-
- /**
- * Set airplane mode on the device if it isn't an LTE device.
- * Full story: In minimal boot mode, we cannot save any state. In particular, we cannot save
- * any incoming SMS's. So SMSs that are received here will be silently dropped to the floor.
- * That is bad. Also, we cannot receive any telephone calls in this state. So to avoid
- * both these problems, we turn the radio off. However, on certain networks turning on and
- * off the radio takes a long time. In such cases, we are better off leaving the radio
- * running so the latency of an E911 call is short.
- * The behavior after this is:
- * 1. Emergency dialing: the emergency dialer has logic to force the device out of
- * airplane mode and restart the radio.
- * 2. Full boot: we read the persistent settings from the previous boot and restore the
- * radio to whatever it was before it restarted. This also happens when rebooting a
- * phone that has no encryption.
- */
- private final void setAirplaneModeIfNecessary() {
- if (!getTelephonyManager().isLteCdmaEvdoGsmWcdmaEnabled()) {
- Log.d(TAG, "Going into airplane mode.");
- Settings.Global.putInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
- final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- intent.putExtra("state", true);
- sendBroadcastAsUser(intent, UserHandle.ALL);
- }
- }
-
- /**
- * Code to update the state of, and handle clicks from, the "Emergency call" button.
- *
- * This code is mostly duplicated from the corresponding code in
- * LockPatternUtils and LockPatternKeyguardView under frameworks/base.
- */
- private void updateEmergencyCallButtonState() {
- final Button emergencyCall = (Button) findViewById(R.id.emergencyCallButton);
- // The button isn't present at all in some configurations.
- if (emergencyCall == null)
- return;
-
- if (isEmergencyCallCapable()) {
- emergencyCall.setVisibility(View.VISIBLE);
- emergencyCall.setOnClickListener(new View.OnClickListener() {
- @Override
-
- public void onClick(View v) {
- takeEmergencyCallAction();
- }
- });
- } else {
- emergencyCall.setVisibility(View.GONE);
- return;
- }
-
- int textId;
- if (getTelecomManager().isInCall()) {
- // Show "return to call"
- textId = R.string.cryptkeeper_return_to_call;
- } else {
- textId = R.string.cryptkeeper_emergency_call;
- }
- emergencyCall.setText(textId);
- }
-
- private boolean isEmergencyCallCapable() {
- return getTelephonyManager().isVoiceCapable();
- }
-
- private void takeEmergencyCallAction() {
- TelecomManager telecomManager = getTelecomManager();
- if (telecomManager.isInCall()) {
- telecomManager.showInCallScreen(false /* showDialpad */);
- } else {
- launchEmergencyDialer();
- }
- }
-
-
- private void launchEmergencyDialer() {
- final Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- setBackFunctionality(true);
- startActivity(intent);
- }
-
- private TelephonyManager getTelephonyManager() {
- return (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
- }
-
- private TelecomManager getTelecomManager() {
- return (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
- }
-
- /**
- * Listen to key events so we can disable sounds when we get a keyinput in EditText.
- */
- private void delayAudioNotification() {
- mNotificationCountdown = 20;
- }
-
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- delayAudioNotification();
- return false;
- }
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- delayAudioNotification();
- return false;
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- return;
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- delayAudioNotification();
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- return;
- }
-
- private static void disableCryptKeeperComponent(Context context) {
- PackageManager pm = context.getPackageManager();
- ComponentName name = new ComponentName(context, CryptKeeper.class);
- Log.d(TAG, "Disabling component " + name);
- pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- }
-}
diff --git a/src/com/android/settings/CryptKeeperConfirm.java b/src/com/android/settings/CryptKeeperConfirm.java
deleted file mode 100644
index 49d027ba492..00000000000
--- a/src/com/android/settings/CryptKeeperConfirm.java
+++ /dev/null
@@ -1,176 +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.annotation.Nullable;
-import android.app.Activity;
-import android.app.StatusBarManager;
-import android.app.settings.SettingsEnums;
-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.UserHandle;
-import android.os.storage.IStorageManager;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.core.InstrumentedFragment;
-
-import java.util.Arrays;
-import java.util.Locale;
-
-public class CryptKeeperConfirm extends InstrumentedFragment {
-
- private static final String TAG = "CryptKeeperConfirm";
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.CRYPT_KEEPER_CONFIRM;
- }
-
- public static class Blank extends Activity {
- private Handler mHandler = new Handler();
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.crypt_keeper_blank);
-
- 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_HOME
- | StatusBarManager.DISABLE_SEARCH
- | StatusBarManager.DISABLE_RECENT
- | StatusBarManager.DISABLE_BACK);
-
- // 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) {
- Log.e("CryptKeeper", "Failed to find the mount service");
- finish();
- return;
- }
-
- IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
- try {
- Bundle args = getIntent().getExtras();
- // TODO(b/120484642): Update vold to accept a password as a byte array
- byte[] passwordBytes = args.getByteArray("password");
- String password = passwordBytes != null ? new String(passwordBytes) : null;
- Arrays.fill(passwordBytes, (byte) 0);
- storageManager.encryptStorage(args.getInt("type", -1),
- 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;
- }
-
- /* WARNING - nasty hack!
- Settings for the lock screen are not available to the crypto
- screen (CryptKeeper) at boot. We duplicate the ones that
- CryptKeeper needs to the crypto key/value store when they are
- modified (see LockPatternUtils).
- However, prior to encryption, the crypto key/value store is not
- persisted across reboots, thus modified settings are lost to
- CryptKeeper.
- In order to make sure CryptKeeper had the correct settings after
- first encrypting, we thus need to rewrite them, which ensures the
- crypto key/value store is up to date. On encryption, this store
- is then persisted, and the settings will be there on future
- reboots.
- */
-
- // 1. The owner info.
- LockPatternUtils utils = new LockPatternUtils(getActivity());
- utils.setVisiblePatternEnabled(
- utils.isVisiblePatternEnabled(UserHandle.USER_SYSTEM),
- UserHandle.USER_SYSTEM);
- if (utils.isOwnerInfoEnabled(UserHandle.USER_SYSTEM)) {
- utils.setOwnerInfo(utils.getOwnerInfo(UserHandle.USER_SYSTEM),
- UserHandle.USER_SYSTEM);
- }
- int value = Settings.System.getInt(getContext().getContentResolver(),
- Settings.System.TEXT_SHOW_PASSWORD,
- 1);
- utils.setVisiblePasswordEnabled(value != 0, UserHandle.USER_SYSTEM);
-
- Intent intent = new Intent(getActivity(), Blank.class);
- intent.putExtras(getArguments());
- startActivity(intent);
-
- // 2. The system locale.
- try {
- IBinder service = ServiceManager.getService("mount");
- IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
- storageManager.setField("SystemLocale", Locale.getDefault().toLanguageTag());
- } catch (Exception e) {
- Log.e(TAG, "Error storing locale for decryption UI", e);
- }
- }
- };
-
- private void establishFinalConfirmationState() {
- mFinalButton = (Button) mContentView.findViewById(R.id.execute_encrypt);
- mFinalButton.setOnClickListener(mFinalClickListener);
- }
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.crypt_keeper_confirm_title);
- }
-
- @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/Settings.java b/src/com/android/settings/Settings.java
index 61d1180aed3..bf655aea9e6 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -255,7 +255,6 @@ public class Settings extends SettingsActivity {
public static class BatterySaverScheduleSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccountSyncSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccountSyncSettingsInAddAccountActivity extends SettingsActivity { /* empty */ }
- public static class CryptKeeperSettingsActivity extends SettingsActivity { /* empty */ }
public static class DeviceAdminSettingsActivity extends SettingsActivity { /* empty */ }
public static class DataUsageSummaryActivity extends SettingsActivity { /* empty */ }
public static class MobileDataUsageListActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index dcf78977c74..93ec8030b9e 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -23,7 +23,6 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
-import android.os.storage.StorageManager;
import android.text.BidiFormatter;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -86,16 +85,6 @@ public class AccessibilityServiceWarning {
return ad;
}
- /**
- * Returns whether the device is encrypted with legacy full disk encryption. Newer devices
- * should be using File Based Encryption.
- *
- * @return true if device is encrypted
- */
- private static boolean isFullDiskEncrypted() {
- return StorageManager.isNonDefaultBlockEncrypted();
- }
-
private static View createEnableDialogContentView(Context context,
@NonNull AccessibilityServiceInfo info, View.OnClickListener listener,
UninstallActionPerformer performer) {
@@ -105,17 +94,6 @@ public class AccessibilityServiceWarning {
View content = inflater.inflate(R.layout.enable_accessibility_service_dialog_content,
null);
- TextView encryptionWarningView = (TextView) content.findViewById(
- R.id.encryption_warning);
- if (isFullDiskEncrypted()) {
- String text = context.getString(R.string.enable_service_encryption_warning,
- getServiceName(context, info));
- encryptionWarningView.setText(text);
- encryptionWarningView.setVisibility(View.VISIBLE);
- } else {
- encryptionWarningView.setVisibility(View.GONE);
- }
-
final Drawable icon;
if (info.getResolveInfo().getIconResource() == 0) {
icon = ContextCompat.getDrawable(context, R.drawable.ic_accessibility_generic);
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index fd987a3caa3..04b5347346e 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -21,9 +21,7 @@ import static com.android.settings.accessibility.AccessibilityStatsLogUtils.logA
import static com.android.settings.accessibility.PreferredShortcuts.retrieveUserShortcutType;
import android.accessibilityservice.AccessibilityServiceInfo;
-import android.app.Activity;
import android.app.Dialog;
-import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -39,9 +37,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
@@ -52,11 +47,9 @@ import android.widget.Switch;
import androidx.annotation.Nullable;
-import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.password.ConfirmDeviceCredentialActivity;
import com.android.settingslib.accessibility.AccessibilityUtils;
import java.util.List;
@@ -67,9 +60,7 @@ public class ToggleAccessibilityServicePreferenceFragment extends
ToggleFeaturePreferenceFragment {
private static final String TAG = "ToggleAccessibilityServicePreferenceFragment";
- private static final int ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION = 1;
private static final String KEY_HAS_LOGGED = "has_logged";
- private LockPatternUtils mLockPatternUtils;
private AtomicBoolean mIsDialogShown = new AtomicBoolean(/* initialValue= */ false);
private static final String EMPTY_STRING = "";
@@ -110,7 +101,6 @@ public class ToggleAccessibilityServicePreferenceFragment extends
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mLockPatternUtils = new LockPatternUtils(getPrefContext());
if (savedInstanceState != null) {
if (savedInstanceState.containsKey(KEY_HAS_LOGGED)) {
mDisabledStateLogged = savedInstanceState.getBoolean(KEY_HAS_LOGGED);
@@ -263,33 +253,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
.contains(mComponentName);
}
- /**
- * Return whether the device is encrypted with legacy full disk encryption. Newer devices
- * should be using File Based Encryption.
- *
- * @return true if device is encrypted
- */
- private boolean isFullDiskEncrypted() {
- return StorageManager.isNonDefaultBlockEncrypted();
- }
-
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION) {
- if (resultCode == Activity.RESULT_OK) {
- handleConfirmServiceEnabled(/* confirmed= */ true);
- // The user confirmed that they accept weaker encryption when
- // enabling the accessibility service, so change encryption.
- // Since we came here asynchronously, check encryption again.
- if (isFullDiskEncrypted()) {
- mLockPatternUtils.clearEncryptionPassword();
- Settings.Global.putInt(getContentResolver(),
- Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, 0);
- }
- } else {
- handleConfirmServiceEnabled(/* confirmed= */ false);
- }
- }
}
private void registerPackageRemoveReceiver() {
@@ -341,23 +306,6 @@ public class ToggleAccessibilityServicePreferenceFragment extends
onPreferenceToggled(mPreferenceKey, confirmed);
}
- private String createConfirmCredentialReasonMessage() {
- int resId = R.string.enable_service_password_reason;
- switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
- case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: {
- resId = R.string.enable_service_pattern_reason;
- }
- break;
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: {
- resId = R.string.enable_service_pin_reason;
- }
- break;
- }
- return getString(resId, getAccessibilityServiceInfo().getResolveInfo()
- .loadLabel(getPackageManager()));
- }
-
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
if (isChecked != isAccessibilityServiceEnabled()) {
@@ -483,20 +431,11 @@ public class ToggleAccessibilityServicePreferenceFragment extends
}
private void onAllowButtonFromEnableToggleClicked() {
- if (isFullDiskEncrypted()) {
- final String title = createConfirmCredentialReasonMessage();
- final Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, /* details= */
- null);
- startActivityForResult(intent,
- ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
- } else {
- handleConfirmServiceEnabled(/* confirmed= */ true);
- if (isServiceSupportAccessibilityButton()) {
- mIsDialogShown.set(false);
- showPopupDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL);
- }
+ handleConfirmServiceEnabled(/* confirmed= */ true);
+ if (isServiceSupportAccessibilityButton()) {
+ mIsDialogShown.set(false);
+ showPopupDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL);
}
-
mDialog.dismiss();
}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 583766e8797..2f0e8b3b4e2 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -148,7 +148,6 @@ import com.android.settings.password.ChooseLockPattern;
import com.android.settings.print.PrintJobSettingsFragment;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.privacy.PrivacyDashboardFragment;
-import com.android.settings.security.CryptKeeperSettings;
import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.SecurityAdvancedSettings;
import com.android.settings.security.SecuritySettings;
@@ -246,7 +245,6 @@ public class SettingsGateway {
PickupGestureSettings.class.getName(),
DoubleTwistGestureSettings.class.getName(),
SystemNavigationGestureSettings.class.getName(),
- CryptKeeperSettings.class.getName(),
DataUsageSummary.class.getName(),
DreamSettings.class.getName(),
UserSettings.class.getName(),
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index a1826ba0cbc..2d6f6b0278d 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -614,7 +614,6 @@ public class ChooseLockGeneric extends SettingsActivity {
disableUnusablePreferences();
updatePreferenceText();
updateCurrentPreference();
- updatePreferenceSummaryIfNeeded();
} else if (!isRecreatingActivity) {
// Don't start the activity again if we are recreated for configuration change
updateUnlockMethodAndFinish(quality, false, true /* chooseLockSkipped */);
@@ -715,13 +714,6 @@ public class ChooseLockGeneric extends SettingsActivity {
}
}
- private void setPreferenceSummary(ScreenLockType lock, @StringRes int summary) {
- Preference preference = findPreference(lock.preferenceKey);
- if (preference != null) {
- preference.setSummary(summary);
- }
- }
-
private void updateCurrentPreference() {
String currentKey = getKeyForCurrent();
Preference preference = findPreference(currentKey);
@@ -764,28 +756,6 @@ public class ChooseLockGeneric extends SettingsActivity {
}
}
- private void updatePreferenceSummaryIfNeeded() {
- // On a default block encrypted device with accessibility, add a warning
- // that your data is not credential encrypted
- if (!StorageManager.isBlockEncrypted()) {
- return;
- }
-
- if (StorageManager.isNonDefaultBlockEncrypted()) {
- return;
- }
-
- if (AccessibilityManager.getInstance(getActivity()).getEnabledAccessibilityServiceList(
- AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) {
- return;
- }
-
- setPreferenceSummary(ScreenLockType.PATTERN, R.string.secure_lock_encryption_warning);
- setPreferenceSummary(ScreenLockType.PIN, R.string.secure_lock_encryption_warning);
- setPreferenceSummary(ScreenLockType.PASSWORD, R.string.secure_lock_encryption_warning);
- setPreferenceSummary(ScreenLockType.MANAGED, R.string.secure_lock_encryption_warning);
- }
-
protected Intent getLockManagedPasswordIntent(LockscreenCredential password) {
return mManagedPasswordProvider.createIntent(false, password);
}
diff --git a/src/com/android/settings/security/CryptKeeperSettings.java b/src/com/android/settings/security/CryptKeeperSettings.java
deleted file mode 100644
index 2b65bf1102d..00000000000
--- a/src/com/android/settings/security/CryptKeeperSettings.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2008 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.security;
-
-import android.app.Activity;
-import android.app.admin.DevicePolicyManager;
-import android.app.settings.SettingsEnums;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.os.BatteryManager;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.storage.StorageManager;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.preference.Preference;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockscreenCredential;
-import com.android.settings.CryptKeeperConfirm;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.core.InstrumentedPreferenceFragment;
-import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.settings.password.ConfirmLockPattern;
-
-public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
- private static final String TAG = "CryptKeeper";
- private static final String TYPE = "type";
- private static final String PASSWORD = "password";
-
- private static final int KEYGUARD_REQUEST = 55;
-
- // Minimum battery charge level (in percent) to launch encryption. If the battery charge is
- // lower than this, encryption should not be activated.
- private static final int MIN_BATTERY_LEVEL = 80;
-
- private View mContentView;
- private Button mInitiateButton;
- private View mPowerWarning;
- private View mBatteryWarning;
- private IntentFilter mIntentFilter;
-
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
- final int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
- final int invalidCharger = intent.getIntExtra(
- BatteryManager.EXTRA_INVALID_CHARGER, 0);
-
- final boolean levelOk = level >= MIN_BATTERY_LEVEL;
- final boolean pluggedOk =
- ((plugged & BatteryManager.BATTERY_PLUGGED_ANY) != 0) &&
- invalidCharger == 0;
-
- // Update UI elements based on power/battery status
- mInitiateButton.setEnabled(levelOk && pluggedOk);
- mPowerWarning.setVisibility(pluggedOk ? View.GONE : View.VISIBLE );
- mBatteryWarning.setVisibility(levelOk ? View.GONE : View.VISIBLE);
- }
- }
- };
-
- /**
- * If the user clicks to begin the reset sequence, we next require a
- * keyguard confirmation if the user has currently enabled one. If there
- * is no keyguard available, we prompt the user to set a password.
- */
- private Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
- // TODO replace (or follow) this dialog with an explicit launch into password UI
- new AlertDialog.Builder(getActivity())
- .setTitle(R.string.crypt_keeper_dialog_need_password_title)
- .setMessage(R.string.crypt_keeper_dialog_need_password_message)
- .setPositiveButton(android.R.string.ok, null)
- .create()
- .show();
- }
- }
- };
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
- mContentView = inflater.inflate(R.layout.crypt_keeper_settings, null);
-
- mIntentFilter = new IntentFilter();
- mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
-
- mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_encrypt);
- mInitiateButton.setOnClickListener(mInitiateListener);
- mInitiateButton.setEnabled(false);
-
- mPowerWarning = mContentView.findViewById(R.id.warning_unplugged);
- mBatteryWarning = mContentView.findViewById(R.id.warning_low_charge);
-
- return mContentView;
- }
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.CRYPT_KEEPER;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- getActivity().registerReceiver(mIntentReceiver, mIntentFilter,
- Context.RECEIVER_EXPORTED_UNAUDITED);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- getActivity().unregisterReceiver(mIntentReceiver);
- }
-
- /**
- * If encryption is already started, and this launched via a "start encryption" intent,
- * then exit immediately - it's already up and running, so there's no point in "starting" it.
- */
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- Activity activity = getActivity();
- Intent intent = activity.getIntent();
- if (DevicePolicyManager.ACTION_START_ENCRYPTION.equals(intent.getAction())) {
- DevicePolicyManager dpm = (DevicePolicyManager)
- activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (dpm != null) {
- int status = dpm.getStorageEncryptionStatus();
- if (status != DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE) {
- // There is nothing to do here, so simply finish() (which returns to caller)
- activity.finish();
- }
- }
- }
- activity.setTitle(R.string.crypt_keeper_encrypt_title);
- }
-
- /**
- * Keyguard validation is run using the standard {@link ConfirmLockPattern}
- * component as a subactivity
- * @param request the request code to be returned once confirmation finishes
- * @return true if confirmation launched
- */
- private boolean runKeyguardConfirmation(int request) {
- final LockPatternUtils utils = new LockPatternUtils(getActivity());
- if (utils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())
- == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
- showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, "".getBytes());
- return true;
- }
-
- final Resources res = getActivity().getResources();
- final ChooseLockSettingsHelper.Builder builder =
- new ChooseLockSettingsHelper.Builder(getActivity(), this);
- return builder.setRequestCode(request)
- .setTitle(res.getText(R.string.crypt_keeper_encrypt_title))
- .setReturnCredentials(true)
- .show();
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode != KEYGUARD_REQUEST) {
- return;
- }
-
- // If the user entered a valid keyguard trace, present the final
- // confirmation prompt; otherwise, go back to the initial state.
- if (resultCode == Activity.RESULT_OK && data != null) {
- int type = data.getIntExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, -1);
- LockscreenCredential password = data.getParcelableExtra(
- ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
- if (password != null && !password.isNone()) {
- showFinalConfirmation(type, password.getCredential());
- }
- }
- }
-
- private void showFinalConfirmation(int type, byte[] password) {
- Preference preference = new Preference(getPreferenceManager().getContext());
- preference.setFragment(CryptKeeperConfirm.class.getName());
- preference.setTitle(R.string.crypt_keeper_confirm_title);
- addEncryptionInfoToPreference(preference, type, password);
- ((SettingsActivity) getActivity()).onPreferenceStartFragment(null, preference);
- }
-
- private void addEncryptionInfoToPreference(Preference preference, int type, byte[] password) {
- Activity activity = getActivity();
- DevicePolicyManager dpm = (DevicePolicyManager)
- activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (dpm.getDoNotAskCredentialsOnBoot()) {
- preference.getExtras().putInt(TYPE, StorageManager.CRYPT_TYPE_DEFAULT);
- preference.getExtras().putByteArray(PASSWORD, "".getBytes());
- } else {
- preference.getExtras().putInt(TYPE, type);
- preference.getExtras().putByteArray(PASSWORD, password);
- }
- }
-}
diff --git a/src/com/android/settings/security/EncryptionStatusPreferenceController.java b/src/com/android/settings/security/EncryptionStatusPreferenceController.java
index 322be10a1dd..d83579822d4 100644
--- a/src/com/android/settings/security/EncryptionStatusPreferenceController.java
+++ b/src/com/android/settings/security/EncryptionStatusPreferenceController.java
@@ -55,15 +55,9 @@ public class EncryptionStatusPreferenceController extends BasePreferenceControll
public void updateState(Preference preference) {
final boolean encryptionEnabled = LockPatternUtils.isDeviceEncryptionEnabled();
if (encryptionEnabled) {
- if (TextUtils.equals(getPreferenceKey(), PREF_KEY_ENCRYPTION_DETAIL_PAGE)) {
- preference.setFragment(null);
- }
- preference.setSummary(R.string.crypt_keeper_encrypted_summary);
+ preference.setSummary(R.string.encrypted_summary);
} else {
- if (TextUtils.equals(getPreferenceKey(), PREF_KEY_ENCRYPTION_DETAIL_PAGE)) {
- preference.setFragment(CryptKeeperSettings.class.getName());
- }
- preference.setSummary(R.string.decryption_settings_summary);
+ preference.setSummary(R.string.not_encrypted_summary);
}
}
diff --git a/tests/robotests/src/com/android/settings/security/EncryptionStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/EncryptionStatusPreferenceControllerTest.java
index 9f0e115f0f3..970564aa04f 100644
--- a/tests/robotests/src/com/android/settings/security/EncryptionStatusPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/EncryptionStatusPreferenceControllerTest.java
@@ -94,23 +94,23 @@ public class EncryptionStatusPreferenceControllerTest {
assertThat(mPreference.getFragment()).isNull();
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getText(R.string.crypt_keeper_encrypted_summary));
+ .isEqualTo(mContext.getText(R.string.encrypted_summary));
}
@Test
- public void updateSummary_unencrypted_shouldHasEncryptionFragment() {
+ public void updateSummary_unencrypted_shouldSayUnencrypted() {
ShadowLockPatternUtils.setDeviceEncryptionEnabled(false);
mController.updateState(mPreference);
- final CharSequence summary = mContext.getText(R.string.decryption_settings_summary);
+ final CharSequence summary = mContext.getText(R.string.not_encrypted_summary);
assertThat(mPreference.getSummary()).isEqualTo(summary);
assertThat(mController.getPreferenceKey()).isNotEqualTo(PREF_KEY_ENCRYPTION_SECURITY_PAGE);
- assertThat(mPreference.getFragment()).isEqualTo(CryptKeeperSettings.class.getName());
+ assertThat(mPreference.getFragment()).isNull();
}
@Test
- public void updateSummary_unencrypted_securityPage_shouldNotHaveEncryptionFragment() {
+ public void updateSummary_unencrypted_securityPage_shouldSayUnencrypted() {
mController =
new EncryptionStatusPreferenceController(mContext,
PREF_KEY_ENCRYPTION_SECURITY_PAGE);
@@ -118,9 +118,8 @@ public class EncryptionStatusPreferenceControllerTest {
mController.updateState(mPreference);
- final CharSequence summary = mContext.getText(R.string.decryption_settings_summary);
+ final CharSequence summary = mContext.getText(R.string.not_encrypted_summary);
assertThat(mPreference.getSummary()).isEqualTo(summary);
-
- assertThat(mPreference.getFragment()).isNotEqualTo(CryptKeeperSettings.class.getName());
+ assertThat(mPreference.getFragment()).isNull();
}
}
|