Loading core/java/android/provider/Settings.java +38 −0 Original line number Diff line number Diff line Loading @@ -1025,6 +1025,9 @@ public final class Settings { MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_ENABLED); MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_VISIBLE); MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED); MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_SIZE); MOVED_TO_SECURE.add(Secure.LOCK_DOTS_VISIBLE); MOVED_TO_SECURE.add(Secure.LOCK_SHOW_ERROR_PATH); MOVED_TO_SECURE.add(Secure.LOGGING_ID); MOVED_TO_SECURE.add(Secure.PARENTAL_CONTROL_ENABLED); MOVED_TO_SECURE.add(Secure.PARENTAL_CONTROL_LAST_UPDATE); Loading Loading @@ -3347,6 +3350,18 @@ public final class Settings { */ public static final String PERFORMANCE_PROFILE = "performance_profile"; /** * Whether to unlock the screen with the home key. The value is boolean (1 or 0). * @hide */ public static final String HOME_UNLOCK_SCREEN = "home_unlock_screen"; /** * Whether the lockscreen vibrate should be enabled. * @hide */ public static final String LOCKSCREEN_VIBRATE_ENABLED = "lockscreen.vibrate_enabled"; /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. Loading Loading @@ -3437,6 +3452,7 @@ public final class Settings { POWER_MENU_AIRPLANE_ENABLED, POWER_MENU_SOUND_ENABLED, POWER_MENU_USER_ENABLED, LOCKSCREEN_VIBRATE_ENABLED, PHONE_BLACKLIST_ENABLED, PHONE_BLACKLIST_NOTIFY_ENABLED, PHONE_BLACKLIST_PRIVATE_NUMBER_MODE, Loading Loading @@ -3707,6 +3723,9 @@ public final class Settings { MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_ENABLED); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_VISIBLE); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_SIZE); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_DOTS_VISIBLE); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_SHOW_ERROR_PATH); MOVED_TO_GLOBAL = new HashSet<String>(); MOVED_TO_GLOBAL.add(Settings.Global.ADB_ENABLED); Loading Loading @@ -4399,6 +4418,24 @@ public final class Settings { public static final String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled"; /** * Determines the width and height of the LockPatternView widget * @hide */ public static final String LOCK_PATTERN_SIZE = "lock_pattern_size"; /** * Whether lock pattern will show dots (0 = false, 1 = true) * @hide */ public static final String LOCK_DOTS_VISIBLE = "lock_pattern_dotsvisible"; /** * Whether lockscreen error pattern is visible (0 = false, 1 = true) * @hide */ public static final String LOCK_SHOW_ERROR_PATH = "lock_pattern_show_error_path"; /** * This preference allows the device to be locked given time after screen goes off, * subject to current DeviceAdmin policy limits. Loading Loading @@ -4450,6 +4487,7 @@ public final class Settings { */ public static final String LOCK_BEFORE_UNLOCK = "lock_before_unlock"; /** * The Logging ID (a unique 64-bit value) as a hex string. * Used as a pseudonymous identifier for logging. Loading core/java/com/android/internal/widget/ILockSettings.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ interface ILockSettings { boolean getBoolean(in String key, in boolean defaultValue, in int userId); long getLong(in String key, in long defaultValue, in int userId); String getString(in String key, in String defaultValue, in int userId); byte getLockPatternSize(int userId); void setLockPattern(in String pattern, int userId); boolean checkPattern(in String pattern, int userId); void setLockPassword(in String password, int userId); Loading core/java/com/android/internal/widget/LockPatternUtils.java +48 −6 Original line number Diff line number Diff line Loading @@ -101,6 +101,11 @@ public class LockPatternUtils { */ public static final int MIN_LOCK_PATTERN_SIZE = 4; /** * The default size of the pattern lockscreen. Ex: 3x3 */ public static final byte PATTERN_SIZE_DEFAULT = 3; /** * The minimum number of dots the user must include in a wrong pattern * attempt for it to be counted against the counts that affect Loading Loading @@ -752,13 +757,16 @@ public class LockPatternUtils { * @param string The pattern serialized with {@link #patternToString} * @return The pattern. */ public static List<LockPatternView.Cell> stringToPattern(String string) { public List<LockPatternView.Cell> stringToPattern(String string) { List<LockPatternView.Cell> result = Lists.newArrayList(); final byte size = getLockPatternSize(); LockPatternView.Cell.updateSize(size); final byte[] bytes = string.getBytes(); for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; result.add(LockPatternView.Cell.of(b / 3, b % 3)); result.add(LockPatternView.Cell.of(b / size, b % size, size)); } return result; } Loading @@ -768,7 +776,7 @@ public class LockPatternUtils { * @param pattern The pattern. * @return The pattern in string form. */ public static String patternToString(List<LockPatternView.Cell> pattern) { public String patternToString(List<LockPatternView.Cell> pattern) { if (pattern == null) { return ""; } Loading @@ -777,7 +785,7 @@ public class LockPatternUtils { byte[] res = new byte[patternSize]; for (int i = 0; i < patternSize; i++) { LockPatternView.Cell cell = pattern.get(i); res[i] = (byte) (cell.getRow() * 3 + cell.getColumn()); res[i] = (byte) (cell.getRow() * getLockPatternSize() + cell.getColumn()); } return new String(res); } Loading @@ -789,7 +797,7 @@ public class LockPatternUtils { * @param pattern the gesture pattern. * @return the hash of the pattern in a byte array. */ public static byte[] patternToHash(List<LockPatternView.Cell> pattern) { public byte[] patternToHash(List<LockPatternView.Cell> pattern) { if (pattern == null) { return null; } Loading @@ -798,7 +806,7 @@ public class LockPatternUtils { byte[] res = new byte[patternSize]; for (int i = 0; i < patternSize; i++) { LockPatternView.Cell cell = pattern.get(i); res[i] = (byte) (cell.getRow() * 3 + cell.getColumn()); res[i] = (byte) (cell.getRow() * getLockPatternSize() + cell.getColumn()); } try { MessageDigest md = MessageDigest.getInstance("SHA-1"); Loading Loading @@ -966,6 +974,40 @@ public class LockPatternUtils { Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0; } /** * @return the pattern lockscreen size */ public byte getLockPatternSize() { try { return getLockSettings().getLockPatternSize(getCurrentOrCallingUserId()); } catch (RemoteException re) { return PATTERN_SIZE_DEFAULT; } } /** * Set the pattern lockscreen size */ public void setLockPatternSize(long size) { setLong(Settings.Secure.LOCK_PATTERN_SIZE, size); } public void setVisibleDotsEnabled(boolean enabled) { setBoolean(Settings.Secure.LOCK_DOTS_VISIBLE, enabled); } public boolean isVisibleDotsEnabled() { return getBoolean(Settings.Secure.LOCK_DOTS_VISIBLE, true); } public void setShowErrorPath(boolean enabled) { setBoolean(Settings.Secure.LOCK_SHOW_ERROR_PATH, enabled); } public boolean isShowErrorPath() { return getBoolean(Settings.Secure.LOCK_SHOW_ERROR_PATH, true); } /** * Set and store the lockout deadline, meaning the user can't attempt his/her unlock * pattern until the deadline has passed. Loading core/java/com/android/internal/widget/LockPatternView.java +138 −54 Original line number Diff line number Diff line Loading @@ -38,13 +38,14 @@ import android.view.View; import android.view.accessibility.AccessibilityManager; import com.android.internal.R; import com.android.internal.widget.LockPatternUtils; import java.util.ArrayList; import java.util.List; /** * Displays and detects the user's unlock attempt, which is a drag of a finger * across 9 regions of the screen. * across regions of the screen. * * Is also capable of displaying a static pattern in "in progress", "wrong" or * "correct" states. Loading @@ -68,6 +69,8 @@ public class LockPatternView extends View { */ private static final int MILLIS_PER_CIRCLE_ANIMATING = 700; private byte mPatternSize = LockPatternUtils.PATTERN_SIZE_DEFAULT; /** * This can be used to avoid updating the display for very small motions or noisy panels. * It didn't seem to have much impact on the devices tested, so currently set to 0. Loading @@ -75,7 +78,7 @@ public class LockPatternView extends View { private static final float DRAG_THRESHHOLD = 0.0f; private OnPatternListener mOnPatternListener; private ArrayList<Cell> mPattern = new ArrayList<Cell>(9); private ArrayList<Cell> mPattern = new ArrayList<Cell>(mPatternSize * mPatternSize); /** * Lookup table for the circles of the pattern we are currently drawing. Loading @@ -83,7 +86,7 @@ public class LockPatternView extends View { * in which case we use this to hold the cells we are drawing for the in * progress animation. */ private boolean[][] mPatternDrawLookup = new boolean[3][3]; private boolean[][] mPatternDrawLookup = new boolean[mPatternSize][mPatternSize]; /** * the in progress point: Loading @@ -100,6 +103,8 @@ public class LockPatternView extends View { private boolean mInStealthMode = false; private boolean mEnableHapticFeedback = true; private boolean mPatternInProgress = false; private boolean mVisibleDots = true; private boolean mShowErrorPath = true; private float mDiameterFactor = 0.10f; // TODO: move to attrs private final int mStrokeAlpha = 128; Loading Loading @@ -128,29 +133,27 @@ public class LockPatternView extends View { private final Matrix mArrowMatrix = new Matrix(); private final Matrix mCircleMatrix = new Matrix(); private LockPatternUtils mLockPatternUtils; /** * Represents a cell in the 3 X 3 matrix of the unlock pattern view. * Represents a cell in the matrix of the unlock pattern view. */ public static class Cell { int row; int column; // keep # objects limited to 9 static Cell[][] sCells = new Cell[3][3]; // keep # objects limited static Cell[][] sCells; static { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { sCells[i][j] = new Cell(i, j); } } updateSize(LockPatternUtils.PATTERN_SIZE_DEFAULT); } /** * @param row The row of the cell. * @param column The column of the cell. */ private Cell(int row, int column) { checkRange(row, column); private Cell(int row, int column, byte size) { checkRange(row, column, size); this.row = row; this.column = column; } Loading @@ -167,17 +170,26 @@ public class LockPatternView extends View { * @param row The row of the cell. * @param column The column of the cell. */ public static synchronized Cell of(int row, int column) { checkRange(row, column); public static synchronized Cell of(int row, int column, byte size) { checkRange(row, column, size); return sCells[row][column]; } private static void checkRange(int row, int column) { if (row < 0 || row > 2) { throw new IllegalArgumentException("row must be in range 0-2"); public static void updateSize(byte size) { sCells = new Cell[size][size]; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { sCells[i][j] = new Cell(i, j, size); } if (column < 0 || column > 2) { throw new IllegalArgumentException("column must be in range 0-2"); } } private static void checkRange(int row, int column, byte size) { if (row < 0 || row > size - 1) { throw new IllegalArgumentException("row must be in range 0-" + (size - 1)); } if (column < 0 || column > size - 1) { throw new IllegalArgumentException("column must be in range 0-" + (size - 1)); } } Loading Loading @@ -305,6 +317,13 @@ public class LockPatternView extends View { return mEnableHapticFeedback; } /** * @return the current pattern lockscreen size. */ public int getLockPatternSize() { return mPatternSize; } /** * Set whether the view is in stealth mode. If true, there will be no * visible feedback as the user enters the pattern. Loading @@ -315,6 +334,22 @@ public class LockPatternView extends View { mInStealthMode = inStealthMode; } public void setVisibleDots(boolean visibleDots) { mVisibleDots = visibleDots; } public boolean isVisibleDots() { return mVisibleDots; } public void setShowErrorPath(boolean showErrorPath) { mShowErrorPath = showErrorPath; } public boolean isShowErrorPath() { return mShowErrorPath; } /** * Set whether the view will use tactile feedback. If true, there will be * tactile feedback as the user enters the pattern. Loading @@ -325,6 +360,26 @@ public class LockPatternView extends View { mEnableHapticFeedback = tactileFeedbackEnabled; } /** * Set the pattern size of the lockscreen * * @param size The pattern size. */ public void setLockPatternSize(byte size) { mPatternSize = size; Cell.updateSize(size); mPattern = new ArrayList<Cell>(size * size); mPatternDrawLookup = new boolean[size][size]; } /** * Set the LockPatternUtil instance used to encode a pattern to a string * @param utils The instance. */ public void setLockPatternUtils(LockPatternUtils utils) { mLockPatternUtils = utils; } /** * Set the call back for pattern detection. * @param onPatternListener The call back. Loading Loading @@ -422,8 +477,8 @@ public class LockPatternView extends View { * Clear the pattern lookup table. */ private void clearPatternDrawLookup() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { for (int i = 0; i < mPatternSize; i++) { for (int j = 0; j < mPatternSize; j++) { mPatternDrawLookup[i][j] = false; } } Loading @@ -447,10 +502,10 @@ public class LockPatternView extends View { @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { final int width = w - mPaddingLeft - mPaddingRight; mSquareWidth = width / 3.0f; mSquareWidth = width / (float) mPatternSize; final int height = h - mPaddingTop - mPaddingBottom; mSquareHeight = height / 3.0f; mSquareHeight = height / (float) mPatternSize; } private int resolveMeasured(int measureSpec, int desired) Loading @@ -473,14 +528,14 @@ public class LockPatternView extends View { @Override protected int getSuggestedMinimumWidth() { // View should be large enough to contain 3 side-by-side target bitmaps return 3 * mBitmapWidth; // View should be large enough to contain side-by-side target bitmaps return mPatternSize * mBitmapWidth; } @Override protected int getSuggestedMinimumHeight() { // View should be large enough to contain 3 side-by-side target bitmaps return 3 * mBitmapWidth; // View should be large enough to contain side-by-side target bitmaps return mPatternSize * mBitmapWidth; } @Override Loading Loading @@ -517,7 +572,6 @@ public class LockPatternView extends View { if (cell != null) { // check for gaps in existing pattern Cell fillInGapCell = null; final ArrayList<Cell> pattern = mPattern; if (!pattern.isEmpty()) { final Cell lastCell = pattern.get(pattern.size() - 1); Loading @@ -527,21 +581,19 @@ public class LockPatternView extends View { int fillInRow = lastCell.row; int fillInColumn = lastCell.column; if (Math.abs(dRow) == 2 && Math.abs(dColumn) != 1) { fillInRow = lastCell.row + ((dRow > 0) ? 1 : -1); if (dRow == 0 || dColumn == 0 || Math.abs(dRow) == Math.abs(dColumn)) { while (true) { fillInRow += Integer.signum(dRow); fillInColumn += Integer.signum(dColumn); if (fillInRow == cell.row && fillInColumn == cell.column) break; Cell fillInGapCell = Cell.of(fillInRow, fillInColumn, mPatternSize); if (!mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) { addCellToPattern(fillInGapCell); } if (Math.abs(dColumn) == 2 && Math.abs(dRow) != 1) { fillInColumn = lastCell.column + ((dColumn > 0) ? 1 : -1); } fillInGapCell = Cell.of(fillInRow, fillInColumn); } if (fillInGapCell != null && !mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) { addCellToPattern(fillInGapCell); } addCellToPattern(cell); if (mEnableHapticFeedback) { performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, Loading Loading @@ -574,7 +626,7 @@ public class LockPatternView extends View { if (mPatternDrawLookup[rowHit][columnHit]) { return null; } return Cell.of(rowHit, columnHit); return Cell.of(rowHit, columnHit, mPatternSize); } /** Loading @@ -588,7 +640,7 @@ public class LockPatternView extends View { float hitSize = squareHeight * mHitFactor; float offset = mPaddingTop + (squareHeight - hitSize) / 2f; for (int i = 0; i < 3; i++) { for (int i = 0; i < mPatternSize; i++) { final float hitTop = offset + squareHeight * i; if (y >= hitTop && y <= hitTop + hitSize) { Loading @@ -608,7 +660,7 @@ public class LockPatternView extends View { float hitSize = squareWidth * mHitFactor; float offset = mPaddingLeft + (squareWidth - hitSize) / 2f; for (int i = 0; i < 3; i++) { for (int i = 0; i < mPatternSize; i++) { final float hitLeft = offset + squareWidth * i; if (x >= hitLeft && x <= hitLeft + hitSize) { Loading Loading @@ -857,10 +909,10 @@ public class LockPatternView extends View { final int paddingTop = mPaddingTop; final int paddingLeft = mPaddingLeft; for (int i = 0; i < 3; i++) { for (int i = 0; i < mPatternSize; i++) { float topY = paddingTop + i * squareHeight; //float centerY = mPaddingTop + i * mSquareHeight + (mSquareHeight / 2); for (int j = 0; j < 3; j++) { for (int j = 0; j < mPatternSize; j++) { float leftX = paddingLeft + j * squareWidth; drawCircle(canvas, (int) leftX, (int) topY, drawLookup[i][j]); } Loading @@ -870,7 +922,8 @@ public class LockPatternView extends View { // only the last segment of the path should be computed here // draw the path of the pattern (unless the user is in progress, and // we are in stealth mode) final boolean drawPath = (!mInStealthMode || mPatternDisplayMode == DisplayMode.Wrong); final boolean drawPath = ((!mInStealthMode && mPatternDisplayMode != DisplayMode.Wrong) || (mPatternDisplayMode == DisplayMode.Wrong && mShowErrorPath)); // draw the arrows associated with the path (unless the user is in progress, and // we are in stealth mode) Loading Loading @@ -973,8 +1026,11 @@ public class LockPatternView extends View { private void drawCircle(Canvas canvas, int leftX, int topY, boolean partOfPattern) { Bitmap outerCircle; Bitmap innerCircle; if (!partOfPattern || (mInStealthMode && mPatternDisplayMode != DisplayMode.Wrong)) { if (!partOfPattern || (mInStealthMode && mPatternDisplayMode != DisplayMode.Wrong) || (mPatternDisplayMode == DisplayMode.Wrong && !mShowErrorPath)) { if (!mVisibleDots) { return; } // unselected circle outerCircle = mBitmapCircleDefault; innerCircle = mBitmapBtnDefault; Loading Loading @@ -1021,9 +1077,9 @@ public class LockPatternView extends View { protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); return new SavedState(superState, LockPatternUtils.patternToString(mPattern), mPatternDisplayMode.ordinal(), mInputEnabled, mInStealthMode, mEnableHapticFeedback); mLockPatternUtils.patternToString(mPattern), mPatternDisplayMode.ordinal(), mPatternSize, mInputEnabled, mInStealthMode, mEnableHapticFeedback, mVisibleDots, mShowErrorPath); } @Override Loading @@ -1032,11 +1088,14 @@ public class LockPatternView extends View { super.onRestoreInstanceState(ss.getSuperState()); setPattern( DisplayMode.Correct, LockPatternUtils.stringToPattern(ss.getSerializedPattern())); mLockPatternUtils.stringToPattern(ss.getSerializedPattern())); mPatternDisplayMode = DisplayMode.values()[ss.getDisplayMode()]; mPatternSize = ss.getPatternSize(); mInputEnabled = ss.isInputEnabled(); mInStealthMode = ss.isInStealthMode(); mEnableHapticFeedback = ss.isTactileFeedbackEnabled(); mVisibleDots = ss.isVisibleDots(); mShowErrorPath = ss.isShowErrorPath(); } /** Loading @@ -1046,21 +1105,28 @@ public class LockPatternView extends View { private final String mSerializedPattern; private final int mDisplayMode; private final byte mPatternSize; private final boolean mInputEnabled; private final boolean mInStealthMode; private final boolean mTactileFeedbackEnabled; private final boolean mVisibleDots; private final boolean mShowErrorPath; /** * Constructor called from {@link LockPatternView#onSaveInstanceState()} */ private SavedState(Parcelable superState, String serializedPattern, int displayMode, boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled) { byte patternSize, boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled, boolean visibleDots, boolean showErrorPath) { super(superState); mSerializedPattern = serializedPattern; mDisplayMode = displayMode; mPatternSize = patternSize; mInputEnabled = inputEnabled; mInStealthMode = inStealthMode; mTactileFeedbackEnabled = tactileFeedbackEnabled; mVisibleDots = visibleDots; mShowErrorPath = showErrorPath; } /** Loading @@ -1070,9 +1136,12 @@ public class LockPatternView extends View { super(in); mSerializedPattern = in.readString(); mDisplayMode = in.readInt(); mPatternSize = (byte) in.readByte(); mInputEnabled = (Boolean) in.readValue(null); mInStealthMode = (Boolean) in.readValue(null); mTactileFeedbackEnabled = (Boolean) in.readValue(null); mVisibleDots = (Boolean) in.readValue(null); mShowErrorPath = (Boolean) in.readValue(null); } public String getSerializedPattern() { Loading @@ -1083,6 +1152,10 @@ public class LockPatternView extends View { return mDisplayMode; } public byte getPatternSize() { return mPatternSize; } public boolean isInputEnabled() { return mInputEnabled; } Loading @@ -1095,14 +1168,25 @@ public class LockPatternView extends View { return mTactileFeedbackEnabled; } public boolean isVisibleDots() { return mVisibleDots; } public boolean isShowErrorPath() { return mShowErrorPath; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeString(mSerializedPattern); dest.writeInt(mDisplayMode); dest.writeByte(mPatternSize); dest.writeValue(mInputEnabled); dest.writeValue(mInStealthMode); dest.writeValue(mTactileFeedbackEnabled); dest.writeValue(mVisibleDots); dest.writeValue(mShowErrorPath); } public static final Parcelable.Creator<SavedState> CREATOR = Loading packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +18 −1 Original line number Diff line number Diff line Loading @@ -1703,7 +1703,15 @@ public class KeyguardHostView extends KeyguardViewBase { final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen); final boolean isTestHarness = ActivityManager.isRunningInTestHarness(); final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists(); return !configDisabled || isTestHarness || fileOverride; final boolean menuOverride = Settings.System.getInt(getContext().getContentResolver(), Settings.System.MENU_UNLOCK_SCREEN, 0) == 1; return !configDisabled || isTestHarness || fileOverride || menuOverride; } private boolean shouldEnableHomeKey() { final boolean homeOverride = Settings.System.getInt(getContext().getContentResolver(), Settings.System.HOME_UNLOCK_SCREEN, 0) == 1; return homeOverride; } public void goToWidget(int appWidgetId) { Loading @@ -1720,6 +1728,15 @@ public class KeyguardHostView extends KeyguardViewBase { return false; } public boolean handleHomeKey() { // The following enables the HOME key to work for testing automation if (shouldEnableHomeKey()) { showNextSecurityScreenOrFinish(false); return true; } return false; } public boolean handleBackKey() { if (mCurrentSecuritySelection == SecurityMode.Account) { // go back to primary screen and re-disable back Loading Loading
core/java/android/provider/Settings.java +38 −0 Original line number Diff line number Diff line Loading @@ -1025,6 +1025,9 @@ public final class Settings { MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_ENABLED); MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_VISIBLE); MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED); MOVED_TO_SECURE.add(Secure.LOCK_PATTERN_SIZE); MOVED_TO_SECURE.add(Secure.LOCK_DOTS_VISIBLE); MOVED_TO_SECURE.add(Secure.LOCK_SHOW_ERROR_PATH); MOVED_TO_SECURE.add(Secure.LOGGING_ID); MOVED_TO_SECURE.add(Secure.PARENTAL_CONTROL_ENABLED); MOVED_TO_SECURE.add(Secure.PARENTAL_CONTROL_LAST_UPDATE); Loading Loading @@ -3347,6 +3350,18 @@ public final class Settings { */ public static final String PERFORMANCE_PROFILE = "performance_profile"; /** * Whether to unlock the screen with the home key. The value is boolean (1 or 0). * @hide */ public static final String HOME_UNLOCK_SCREEN = "home_unlock_screen"; /** * Whether the lockscreen vibrate should be enabled. * @hide */ public static final String LOCKSCREEN_VIBRATE_ENABLED = "lockscreen.vibrate_enabled"; /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. Loading Loading @@ -3437,6 +3452,7 @@ public final class Settings { POWER_MENU_AIRPLANE_ENABLED, POWER_MENU_SOUND_ENABLED, POWER_MENU_USER_ENABLED, LOCKSCREEN_VIBRATE_ENABLED, PHONE_BLACKLIST_ENABLED, PHONE_BLACKLIST_NOTIFY_ENABLED, PHONE_BLACKLIST_PRIVATE_NUMBER_MODE, Loading Loading @@ -3707,6 +3723,9 @@ public final class Settings { MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_ENABLED); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_VISIBLE); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_PATTERN_SIZE); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_DOTS_VISIBLE); MOVED_TO_LOCK_SETTINGS.add(Secure.LOCK_SHOW_ERROR_PATH); MOVED_TO_GLOBAL = new HashSet<String>(); MOVED_TO_GLOBAL.add(Settings.Global.ADB_ENABLED); Loading Loading @@ -4399,6 +4418,24 @@ public final class Settings { public static final String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled"; /** * Determines the width and height of the LockPatternView widget * @hide */ public static final String LOCK_PATTERN_SIZE = "lock_pattern_size"; /** * Whether lock pattern will show dots (0 = false, 1 = true) * @hide */ public static final String LOCK_DOTS_VISIBLE = "lock_pattern_dotsvisible"; /** * Whether lockscreen error pattern is visible (0 = false, 1 = true) * @hide */ public static final String LOCK_SHOW_ERROR_PATH = "lock_pattern_show_error_path"; /** * This preference allows the device to be locked given time after screen goes off, * subject to current DeviceAdmin policy limits. Loading Loading @@ -4450,6 +4487,7 @@ public final class Settings { */ public static final String LOCK_BEFORE_UNLOCK = "lock_before_unlock"; /** * The Logging ID (a unique 64-bit value) as a hex string. * Used as a pseudonymous identifier for logging. Loading
core/java/com/android/internal/widget/ILockSettings.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ interface ILockSettings { boolean getBoolean(in String key, in boolean defaultValue, in int userId); long getLong(in String key, in long defaultValue, in int userId); String getString(in String key, in String defaultValue, in int userId); byte getLockPatternSize(int userId); void setLockPattern(in String pattern, int userId); boolean checkPattern(in String pattern, int userId); void setLockPassword(in String password, int userId); Loading
core/java/com/android/internal/widget/LockPatternUtils.java +48 −6 Original line number Diff line number Diff line Loading @@ -101,6 +101,11 @@ public class LockPatternUtils { */ public static final int MIN_LOCK_PATTERN_SIZE = 4; /** * The default size of the pattern lockscreen. Ex: 3x3 */ public static final byte PATTERN_SIZE_DEFAULT = 3; /** * The minimum number of dots the user must include in a wrong pattern * attempt for it to be counted against the counts that affect Loading Loading @@ -752,13 +757,16 @@ public class LockPatternUtils { * @param string The pattern serialized with {@link #patternToString} * @return The pattern. */ public static List<LockPatternView.Cell> stringToPattern(String string) { public List<LockPatternView.Cell> stringToPattern(String string) { List<LockPatternView.Cell> result = Lists.newArrayList(); final byte size = getLockPatternSize(); LockPatternView.Cell.updateSize(size); final byte[] bytes = string.getBytes(); for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; result.add(LockPatternView.Cell.of(b / 3, b % 3)); result.add(LockPatternView.Cell.of(b / size, b % size, size)); } return result; } Loading @@ -768,7 +776,7 @@ public class LockPatternUtils { * @param pattern The pattern. * @return The pattern in string form. */ public static String patternToString(List<LockPatternView.Cell> pattern) { public String patternToString(List<LockPatternView.Cell> pattern) { if (pattern == null) { return ""; } Loading @@ -777,7 +785,7 @@ public class LockPatternUtils { byte[] res = new byte[patternSize]; for (int i = 0; i < patternSize; i++) { LockPatternView.Cell cell = pattern.get(i); res[i] = (byte) (cell.getRow() * 3 + cell.getColumn()); res[i] = (byte) (cell.getRow() * getLockPatternSize() + cell.getColumn()); } return new String(res); } Loading @@ -789,7 +797,7 @@ public class LockPatternUtils { * @param pattern the gesture pattern. * @return the hash of the pattern in a byte array. */ public static byte[] patternToHash(List<LockPatternView.Cell> pattern) { public byte[] patternToHash(List<LockPatternView.Cell> pattern) { if (pattern == null) { return null; } Loading @@ -798,7 +806,7 @@ public class LockPatternUtils { byte[] res = new byte[patternSize]; for (int i = 0; i < patternSize; i++) { LockPatternView.Cell cell = pattern.get(i); res[i] = (byte) (cell.getRow() * 3 + cell.getColumn()); res[i] = (byte) (cell.getRow() * getLockPatternSize() + cell.getColumn()); } try { MessageDigest md = MessageDigest.getInstance("SHA-1"); Loading Loading @@ -966,6 +974,40 @@ public class LockPatternUtils { Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0; } /** * @return the pattern lockscreen size */ public byte getLockPatternSize() { try { return getLockSettings().getLockPatternSize(getCurrentOrCallingUserId()); } catch (RemoteException re) { return PATTERN_SIZE_DEFAULT; } } /** * Set the pattern lockscreen size */ public void setLockPatternSize(long size) { setLong(Settings.Secure.LOCK_PATTERN_SIZE, size); } public void setVisibleDotsEnabled(boolean enabled) { setBoolean(Settings.Secure.LOCK_DOTS_VISIBLE, enabled); } public boolean isVisibleDotsEnabled() { return getBoolean(Settings.Secure.LOCK_DOTS_VISIBLE, true); } public void setShowErrorPath(boolean enabled) { setBoolean(Settings.Secure.LOCK_SHOW_ERROR_PATH, enabled); } public boolean isShowErrorPath() { return getBoolean(Settings.Secure.LOCK_SHOW_ERROR_PATH, true); } /** * Set and store the lockout deadline, meaning the user can't attempt his/her unlock * pattern until the deadline has passed. Loading
core/java/com/android/internal/widget/LockPatternView.java +138 −54 Original line number Diff line number Diff line Loading @@ -38,13 +38,14 @@ import android.view.View; import android.view.accessibility.AccessibilityManager; import com.android.internal.R; import com.android.internal.widget.LockPatternUtils; import java.util.ArrayList; import java.util.List; /** * Displays and detects the user's unlock attempt, which is a drag of a finger * across 9 regions of the screen. * across regions of the screen. * * Is also capable of displaying a static pattern in "in progress", "wrong" or * "correct" states. Loading @@ -68,6 +69,8 @@ public class LockPatternView extends View { */ private static final int MILLIS_PER_CIRCLE_ANIMATING = 700; private byte mPatternSize = LockPatternUtils.PATTERN_SIZE_DEFAULT; /** * This can be used to avoid updating the display for very small motions or noisy panels. * It didn't seem to have much impact on the devices tested, so currently set to 0. Loading @@ -75,7 +78,7 @@ public class LockPatternView extends View { private static final float DRAG_THRESHHOLD = 0.0f; private OnPatternListener mOnPatternListener; private ArrayList<Cell> mPattern = new ArrayList<Cell>(9); private ArrayList<Cell> mPattern = new ArrayList<Cell>(mPatternSize * mPatternSize); /** * Lookup table for the circles of the pattern we are currently drawing. Loading @@ -83,7 +86,7 @@ public class LockPatternView extends View { * in which case we use this to hold the cells we are drawing for the in * progress animation. */ private boolean[][] mPatternDrawLookup = new boolean[3][3]; private boolean[][] mPatternDrawLookup = new boolean[mPatternSize][mPatternSize]; /** * the in progress point: Loading @@ -100,6 +103,8 @@ public class LockPatternView extends View { private boolean mInStealthMode = false; private boolean mEnableHapticFeedback = true; private boolean mPatternInProgress = false; private boolean mVisibleDots = true; private boolean mShowErrorPath = true; private float mDiameterFactor = 0.10f; // TODO: move to attrs private final int mStrokeAlpha = 128; Loading Loading @@ -128,29 +133,27 @@ public class LockPatternView extends View { private final Matrix mArrowMatrix = new Matrix(); private final Matrix mCircleMatrix = new Matrix(); private LockPatternUtils mLockPatternUtils; /** * Represents a cell in the 3 X 3 matrix of the unlock pattern view. * Represents a cell in the matrix of the unlock pattern view. */ public static class Cell { int row; int column; // keep # objects limited to 9 static Cell[][] sCells = new Cell[3][3]; // keep # objects limited static Cell[][] sCells; static { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { sCells[i][j] = new Cell(i, j); } } updateSize(LockPatternUtils.PATTERN_SIZE_DEFAULT); } /** * @param row The row of the cell. * @param column The column of the cell. */ private Cell(int row, int column) { checkRange(row, column); private Cell(int row, int column, byte size) { checkRange(row, column, size); this.row = row; this.column = column; } Loading @@ -167,17 +170,26 @@ public class LockPatternView extends View { * @param row The row of the cell. * @param column The column of the cell. */ public static synchronized Cell of(int row, int column) { checkRange(row, column); public static synchronized Cell of(int row, int column, byte size) { checkRange(row, column, size); return sCells[row][column]; } private static void checkRange(int row, int column) { if (row < 0 || row > 2) { throw new IllegalArgumentException("row must be in range 0-2"); public static void updateSize(byte size) { sCells = new Cell[size][size]; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { sCells[i][j] = new Cell(i, j, size); } if (column < 0 || column > 2) { throw new IllegalArgumentException("column must be in range 0-2"); } } private static void checkRange(int row, int column, byte size) { if (row < 0 || row > size - 1) { throw new IllegalArgumentException("row must be in range 0-" + (size - 1)); } if (column < 0 || column > size - 1) { throw new IllegalArgumentException("column must be in range 0-" + (size - 1)); } } Loading Loading @@ -305,6 +317,13 @@ public class LockPatternView extends View { return mEnableHapticFeedback; } /** * @return the current pattern lockscreen size. */ public int getLockPatternSize() { return mPatternSize; } /** * Set whether the view is in stealth mode. If true, there will be no * visible feedback as the user enters the pattern. Loading @@ -315,6 +334,22 @@ public class LockPatternView extends View { mInStealthMode = inStealthMode; } public void setVisibleDots(boolean visibleDots) { mVisibleDots = visibleDots; } public boolean isVisibleDots() { return mVisibleDots; } public void setShowErrorPath(boolean showErrorPath) { mShowErrorPath = showErrorPath; } public boolean isShowErrorPath() { return mShowErrorPath; } /** * Set whether the view will use tactile feedback. If true, there will be * tactile feedback as the user enters the pattern. Loading @@ -325,6 +360,26 @@ public class LockPatternView extends View { mEnableHapticFeedback = tactileFeedbackEnabled; } /** * Set the pattern size of the lockscreen * * @param size The pattern size. */ public void setLockPatternSize(byte size) { mPatternSize = size; Cell.updateSize(size); mPattern = new ArrayList<Cell>(size * size); mPatternDrawLookup = new boolean[size][size]; } /** * Set the LockPatternUtil instance used to encode a pattern to a string * @param utils The instance. */ public void setLockPatternUtils(LockPatternUtils utils) { mLockPatternUtils = utils; } /** * Set the call back for pattern detection. * @param onPatternListener The call back. Loading Loading @@ -422,8 +477,8 @@ public class LockPatternView extends View { * Clear the pattern lookup table. */ private void clearPatternDrawLookup() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { for (int i = 0; i < mPatternSize; i++) { for (int j = 0; j < mPatternSize; j++) { mPatternDrawLookup[i][j] = false; } } Loading @@ -447,10 +502,10 @@ public class LockPatternView extends View { @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { final int width = w - mPaddingLeft - mPaddingRight; mSquareWidth = width / 3.0f; mSquareWidth = width / (float) mPatternSize; final int height = h - mPaddingTop - mPaddingBottom; mSquareHeight = height / 3.0f; mSquareHeight = height / (float) mPatternSize; } private int resolveMeasured(int measureSpec, int desired) Loading @@ -473,14 +528,14 @@ public class LockPatternView extends View { @Override protected int getSuggestedMinimumWidth() { // View should be large enough to contain 3 side-by-side target bitmaps return 3 * mBitmapWidth; // View should be large enough to contain side-by-side target bitmaps return mPatternSize * mBitmapWidth; } @Override protected int getSuggestedMinimumHeight() { // View should be large enough to contain 3 side-by-side target bitmaps return 3 * mBitmapWidth; // View should be large enough to contain side-by-side target bitmaps return mPatternSize * mBitmapWidth; } @Override Loading Loading @@ -517,7 +572,6 @@ public class LockPatternView extends View { if (cell != null) { // check for gaps in existing pattern Cell fillInGapCell = null; final ArrayList<Cell> pattern = mPattern; if (!pattern.isEmpty()) { final Cell lastCell = pattern.get(pattern.size() - 1); Loading @@ -527,21 +581,19 @@ public class LockPatternView extends View { int fillInRow = lastCell.row; int fillInColumn = lastCell.column; if (Math.abs(dRow) == 2 && Math.abs(dColumn) != 1) { fillInRow = lastCell.row + ((dRow > 0) ? 1 : -1); if (dRow == 0 || dColumn == 0 || Math.abs(dRow) == Math.abs(dColumn)) { while (true) { fillInRow += Integer.signum(dRow); fillInColumn += Integer.signum(dColumn); if (fillInRow == cell.row && fillInColumn == cell.column) break; Cell fillInGapCell = Cell.of(fillInRow, fillInColumn, mPatternSize); if (!mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) { addCellToPattern(fillInGapCell); } if (Math.abs(dColumn) == 2 && Math.abs(dRow) != 1) { fillInColumn = lastCell.column + ((dColumn > 0) ? 1 : -1); } fillInGapCell = Cell.of(fillInRow, fillInColumn); } if (fillInGapCell != null && !mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) { addCellToPattern(fillInGapCell); } addCellToPattern(cell); if (mEnableHapticFeedback) { performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, Loading Loading @@ -574,7 +626,7 @@ public class LockPatternView extends View { if (mPatternDrawLookup[rowHit][columnHit]) { return null; } return Cell.of(rowHit, columnHit); return Cell.of(rowHit, columnHit, mPatternSize); } /** Loading @@ -588,7 +640,7 @@ public class LockPatternView extends View { float hitSize = squareHeight * mHitFactor; float offset = mPaddingTop + (squareHeight - hitSize) / 2f; for (int i = 0; i < 3; i++) { for (int i = 0; i < mPatternSize; i++) { final float hitTop = offset + squareHeight * i; if (y >= hitTop && y <= hitTop + hitSize) { Loading @@ -608,7 +660,7 @@ public class LockPatternView extends View { float hitSize = squareWidth * mHitFactor; float offset = mPaddingLeft + (squareWidth - hitSize) / 2f; for (int i = 0; i < 3; i++) { for (int i = 0; i < mPatternSize; i++) { final float hitLeft = offset + squareWidth * i; if (x >= hitLeft && x <= hitLeft + hitSize) { Loading Loading @@ -857,10 +909,10 @@ public class LockPatternView extends View { final int paddingTop = mPaddingTop; final int paddingLeft = mPaddingLeft; for (int i = 0; i < 3; i++) { for (int i = 0; i < mPatternSize; i++) { float topY = paddingTop + i * squareHeight; //float centerY = mPaddingTop + i * mSquareHeight + (mSquareHeight / 2); for (int j = 0; j < 3; j++) { for (int j = 0; j < mPatternSize; j++) { float leftX = paddingLeft + j * squareWidth; drawCircle(canvas, (int) leftX, (int) topY, drawLookup[i][j]); } Loading @@ -870,7 +922,8 @@ public class LockPatternView extends View { // only the last segment of the path should be computed here // draw the path of the pattern (unless the user is in progress, and // we are in stealth mode) final boolean drawPath = (!mInStealthMode || mPatternDisplayMode == DisplayMode.Wrong); final boolean drawPath = ((!mInStealthMode && mPatternDisplayMode != DisplayMode.Wrong) || (mPatternDisplayMode == DisplayMode.Wrong && mShowErrorPath)); // draw the arrows associated with the path (unless the user is in progress, and // we are in stealth mode) Loading Loading @@ -973,8 +1026,11 @@ public class LockPatternView extends View { private void drawCircle(Canvas canvas, int leftX, int topY, boolean partOfPattern) { Bitmap outerCircle; Bitmap innerCircle; if (!partOfPattern || (mInStealthMode && mPatternDisplayMode != DisplayMode.Wrong)) { if (!partOfPattern || (mInStealthMode && mPatternDisplayMode != DisplayMode.Wrong) || (mPatternDisplayMode == DisplayMode.Wrong && !mShowErrorPath)) { if (!mVisibleDots) { return; } // unselected circle outerCircle = mBitmapCircleDefault; innerCircle = mBitmapBtnDefault; Loading Loading @@ -1021,9 +1077,9 @@ public class LockPatternView extends View { protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); return new SavedState(superState, LockPatternUtils.patternToString(mPattern), mPatternDisplayMode.ordinal(), mInputEnabled, mInStealthMode, mEnableHapticFeedback); mLockPatternUtils.patternToString(mPattern), mPatternDisplayMode.ordinal(), mPatternSize, mInputEnabled, mInStealthMode, mEnableHapticFeedback, mVisibleDots, mShowErrorPath); } @Override Loading @@ -1032,11 +1088,14 @@ public class LockPatternView extends View { super.onRestoreInstanceState(ss.getSuperState()); setPattern( DisplayMode.Correct, LockPatternUtils.stringToPattern(ss.getSerializedPattern())); mLockPatternUtils.stringToPattern(ss.getSerializedPattern())); mPatternDisplayMode = DisplayMode.values()[ss.getDisplayMode()]; mPatternSize = ss.getPatternSize(); mInputEnabled = ss.isInputEnabled(); mInStealthMode = ss.isInStealthMode(); mEnableHapticFeedback = ss.isTactileFeedbackEnabled(); mVisibleDots = ss.isVisibleDots(); mShowErrorPath = ss.isShowErrorPath(); } /** Loading @@ -1046,21 +1105,28 @@ public class LockPatternView extends View { private final String mSerializedPattern; private final int mDisplayMode; private final byte mPatternSize; private final boolean mInputEnabled; private final boolean mInStealthMode; private final boolean mTactileFeedbackEnabled; private final boolean mVisibleDots; private final boolean mShowErrorPath; /** * Constructor called from {@link LockPatternView#onSaveInstanceState()} */ private SavedState(Parcelable superState, String serializedPattern, int displayMode, boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled) { byte patternSize, boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled, boolean visibleDots, boolean showErrorPath) { super(superState); mSerializedPattern = serializedPattern; mDisplayMode = displayMode; mPatternSize = patternSize; mInputEnabled = inputEnabled; mInStealthMode = inStealthMode; mTactileFeedbackEnabled = tactileFeedbackEnabled; mVisibleDots = visibleDots; mShowErrorPath = showErrorPath; } /** Loading @@ -1070,9 +1136,12 @@ public class LockPatternView extends View { super(in); mSerializedPattern = in.readString(); mDisplayMode = in.readInt(); mPatternSize = (byte) in.readByte(); mInputEnabled = (Boolean) in.readValue(null); mInStealthMode = (Boolean) in.readValue(null); mTactileFeedbackEnabled = (Boolean) in.readValue(null); mVisibleDots = (Boolean) in.readValue(null); mShowErrorPath = (Boolean) in.readValue(null); } public String getSerializedPattern() { Loading @@ -1083,6 +1152,10 @@ public class LockPatternView extends View { return mDisplayMode; } public byte getPatternSize() { return mPatternSize; } public boolean isInputEnabled() { return mInputEnabled; } Loading @@ -1095,14 +1168,25 @@ public class LockPatternView extends View { return mTactileFeedbackEnabled; } public boolean isVisibleDots() { return mVisibleDots; } public boolean isShowErrorPath() { return mShowErrorPath; } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeString(mSerializedPattern); dest.writeInt(mDisplayMode); dest.writeByte(mPatternSize); dest.writeValue(mInputEnabled); dest.writeValue(mInStealthMode); dest.writeValue(mTactileFeedbackEnabled); dest.writeValue(mVisibleDots); dest.writeValue(mShowErrorPath); } public static final Parcelable.Creator<SavedState> CREATOR = Loading
packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +18 −1 Original line number Diff line number Diff line Loading @@ -1703,7 +1703,15 @@ public class KeyguardHostView extends KeyguardViewBase { final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen); final boolean isTestHarness = ActivityManager.isRunningInTestHarness(); final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists(); return !configDisabled || isTestHarness || fileOverride; final boolean menuOverride = Settings.System.getInt(getContext().getContentResolver(), Settings.System.MENU_UNLOCK_SCREEN, 0) == 1; return !configDisabled || isTestHarness || fileOverride || menuOverride; } private boolean shouldEnableHomeKey() { final boolean homeOverride = Settings.System.getInt(getContext().getContentResolver(), Settings.System.HOME_UNLOCK_SCREEN, 0) == 1; return homeOverride; } public void goToWidget(int appWidgetId) { Loading @@ -1720,6 +1728,15 @@ public class KeyguardHostView extends KeyguardViewBase { return false; } public boolean handleHomeKey() { // The following enables the HOME key to work for testing automation if (shouldEnableHomeKey()) { showNextSecurityScreenOrFinish(false); return true; } return false; } public boolean handleBackKey() { if (mCurrentSecuritySelection == SecurityMode.Account) { // go back to primary screen and re-disable back Loading