diff options
author | Michael Bestas <mikeioannina@gmail.com> | 2015-04-03 14:33:37 -0700 |
---|---|---|
committer | Roman Birg <roman@cyngn.com> | 2015-12-11 11:42:41 -0600 |
commit | 0cf7d4373afc1bbc0b9a42954d6dbd162aa361a4 (patch) | |
tree | 307f858411925cd08f8edf6fd848d3986d4aab43 | |
parent | a037ad401e4a78ce22a9ec2dada8ff3593aa8fa4 (diff) | |
download | frameworks_base-0cf7d4373afc1bbc0b9a42954d6dbd162aa361a4.zip frameworks_base-0cf7d4373afc1bbc0b9a42954d6dbd162aa361a4.tar.gz frameworks_base-0cf7d4373afc1bbc0b9a42954d6dbd162aa361a4.tar.bz2 |
Forward port CM Screen Security settings (1/2)
* Variable size pattern lockscreen
* Toggle dots/error pattern visibility
Change-Id: Ie109e82c1fb2fd96b07e977e1cd76ae3acb865ff
8 files changed, 271 insertions, 72 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a3de3d1..e107fd1 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4004,6 +4004,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); @@ -4774,6 +4777,24 @@ public final class Settings { 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. * @hide diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 00e41bd..cc951a5 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -33,6 +33,7 @@ interface ILockSettings { void setLockPassword(in String password, in String savedPassword, int userId); VerifyCredentialResponse checkPassword(in String password, int userId); VerifyCredentialResponse verifyPassword(in String password, long challenge, int userId); + byte getLockPatternSize(int userId); boolean checkVoldPassword(int userId); boolean havePattern(int userId); boolean havePassword(int userId); diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 345b99f..5e5f039 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -91,6 +91,11 @@ public class LockPatternUtils { */ public static final int MIN_LOCK_PASSWORD_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 @@ -847,17 +852,18 @@ public class LockPatternUtils { * @param string The pattern serialized with {@link #patternToString} * @return The pattern. */ - public static List<LockPatternView.Cell> stringToPattern(String string) { + public static List<LockPatternView.Cell> stringToPattern(String string, byte gridSize) { if (string == null) { return null; } - List<LockPatternView.Cell> result = Lists.newArrayList(); + LockPatternView.Cell.updateSize(gridSize); + final byte[] bytes = string.getBytes(); for (int i = 0; i < bytes.length; i++) { byte b = (byte) (bytes[i] - '1'); - result.add(LockPatternView.Cell.of(b / 3, b % 3)); + result.add(LockPatternView.Cell.of(b / gridSize, b % gridSize, gridSize)); } return result; } @@ -867,16 +873,26 @@ 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) { + return patternToString(pattern, getLockPatternSize()); + } + + /** + * Serialize a pattern. + * @param pattern The pattern. + * @return The pattern in string form. + */ + public static String patternToString(List<LockPatternView.Cell> pattern, byte gridSize) { if (pattern == null) { return ""; } final int patternSize = pattern.size(); + LockPatternView.Cell.updateSize(gridSize); 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() + '1'); + res[i] = (byte) (cell.getRow() * gridSize + cell.getColumn() + '1'); } return new String(res); } @@ -886,7 +902,6 @@ public class LockPatternUtils { return ""; } final int patternSize = pattern.length(); - byte[] res = new byte[patternSize]; final byte[] bytes = pattern.getBytes(); for (int i = 0; i < patternSize; i++) { @@ -902,7 +917,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 static byte[] patternToHash(List<LockPatternView.Cell> pattern, byte gridSize) { if (pattern == null) { return null; } @@ -911,7 +926,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() * gridSize + cell.getColumn()); } try { MessageDigest md = MessageDigest.getInstance("SHA-1"); @@ -1065,6 +1080,40 @@ public class LockPatternUtils { } /** + * @return the pattern lockscreen size + */ + public byte getLockPatternSize() { + long size = getLong(Settings.Secure.LOCK_PATTERN_SIZE, -1, UserHandle.USER_CURRENT); + if (size > 0 && size < 128) { + return (byte) size; + } + return LockPatternUtils.PATTERN_SIZE_DEFAULT; + } + + /** + * Set the pattern lockscreen size + */ + public void setLockPatternSize(long size) { + setLong(Settings.Secure.LOCK_PATTERN_SIZE, size, UserHandle.USER_CURRENT); + } + + public void setVisibleDotsEnabled(boolean enabled) { + setBoolean(Settings.Secure.LOCK_DOTS_VISIBLE, enabled, UserHandle.USER_CURRENT); + } + + public boolean isVisibleDotsEnabled() { + return getBoolean(Settings.Secure.LOCK_DOTS_VISIBLE, true, UserHandle.USER_CURRENT); + } + + public void setShowErrorPath(boolean enabled) { + setBoolean(Settings.Secure.LOCK_SHOW_ERROR_PATH, enabled, UserHandle.USER_CURRENT); + } + + public boolean isShowErrorPath() { + return getBoolean(Settings.Secure.LOCK_SHOW_ERROR_PATH, true, UserHandle.USER_CURRENT); + } + + /** * Set and store the lockout deadline, meaning the user can't attempt his/her unlock * pattern until the deadline has passed. * @return the chosen deadline. diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 9211eaa..a3cd8ad 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -51,6 +51,7 @@ import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import com.android.internal.R; +import com.android.internal.widget.LockPatternUtils; import java.util.ArrayList; import java.util.HashMap; @@ -58,7 +59,7 @@ 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. @@ -70,7 +71,7 @@ public class LockPatternView extends View { private static final int ASPECT_LOCK_HEIGHT = 2; // Fixed height; width will be minimum of (w,h) private static final boolean PROFILE_DRAWING = false; - private final CellState[][] mCellStates; + private CellState[][] mCellStates; private final int mDotSize; private final int mDotSizeActivated; @@ -88,6 +89,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. @@ -98,7 +101,7 @@ public class LockPatternView extends View { private static final String TAG = "LockPatternView"; private OnPatternListener mOnPatternListener; - private final 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. @@ -106,7 +109,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 final boolean[][] mPatternDrawLookup = new boolean[3][3]; + private boolean[][] mPatternDrawLookup = new boolean[mPatternSize][mPatternSize]; /** * the in progress point: @@ -123,6 +126,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 mHitFactor = 0.6f; @@ -143,32 +148,26 @@ public class LockPatternView extends View { private PatternExploreByTouchHelper mExploreByTouchHelper; private AudioManager mAudioManager; + 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 final class Cell { final int row; final int column; - // keep # objects limited to 9 - private static final Cell[][] sCells = createCells(); - - private static Cell[][] createCells() { - Cell[][] res = new Cell[3][3]; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - res[i][j] = new Cell(i, j); - } - } - return res; + static Cell[][] sCells; + static { + 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; } @@ -181,17 +180,30 @@ public class LockPatternView extends View { return column; } - public static Cell of(int row, int column) { - checkRange(row, column); + /** + * @param row The row of the cell. + * @param column The column of the cell. + */ + 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); + } + } + } + + 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 > 2) { - throw new IllegalArgumentException("column must be in range 0-2"); + if (column < 0 || column > size - 1) { + throw new IllegalArgumentException("column must be in range 0-" + (size - 1)); } } @@ -317,9 +329,9 @@ public class LockPatternView extends View { mPaint.setAntiAlias(true); mPaint.setDither(true); - mCellStates = new CellState[3][3]; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { + mCellStates = new CellState[mPatternSize][mPatternSize]; + for (int i = 0; i < mPatternSize; i++) { + for (int j = 0; j < mPatternSize; j++) { mCellStates[i][j] = new CellState(); mCellStates[i][j].radius = mDotSize/2; mCellStates[i][j].row = i; @@ -355,6 +367,13 @@ public class LockPatternView extends View { } /** + * @return the current pattern lockscreen size. + */ + public byte 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. * @@ -364,6 +383,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. @@ -375,6 +410,35 @@ public class LockPatternView extends View { } /** + * Set the pattern size of the lockscreen + * + * @param size The pattern size. + */ + public void setLockPatternSize(byte size) { + mPatternSize = size; + Cell.updateSize(size); + mCellStates = new CellState[mPatternSize][mPatternSize]; + for (int i = 0; i < mPatternSize; i++) { + for (int j = 0; j < mPatternSize; j++) { + mCellStates[i][j] = new CellState(); + mCellStates[i][j].radius = mDotSize / 2; + mCellStates[i][j].row = i; + mCellStates[i][j].col = j; + } + } + 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. */ @@ -589,8 +653,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; } } @@ -614,11 +678,11 @@ 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; if (DEBUG_A11Y) Log.v(TAG, "onSizeChanged(" + w + "," + h + ")"); final int height = h - mPaddingTop - mPaddingBottom; - mSquareHeight = height / 3.0f; + mSquareHeight = height / (float) mPatternSize; mExploreByTouchHelper.invalidateRoot(); } @@ -674,7 +738,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); @@ -684,21 +747,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 (Math.abs(dColumn) == 2 && Math.abs(dRow) != 1) { - fillInColumn = lastCell.column + ((dColumn > 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); + } + } } - - fillInGapCell = Cell.of(fillInRow, fillInColumn); } - if (fillInGapCell != null && - !mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) { - addCellToPattern(fillInGapCell); - } addCellToPattern(cell); if (mEnableHapticFeedback) { performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, @@ -796,7 +857,7 @@ public class LockPatternView extends View { if (mPatternDrawLookup[rowHit][columnHit]) { return null; } - return Cell.of(rowHit, columnHit); + return Cell.of(rowHit, columnHit, mPatternSize); } /** @@ -810,7 +871,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) { @@ -830,7 +891,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) { @@ -984,8 +1045,8 @@ public class LockPatternView extends View { } private void cancelLineAnimations() { - 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++) { CellState state = mCellStates[i][j]; if (state.lineAnimator != null) { state.lineAnimator.cancel(); @@ -1088,9 +1149,9 @@ public class LockPatternView extends View { currentPath.rewind(); // draw the circles - for (int i = 0; i < 3; i++) { + for (int i = 0; i < mPatternSize; i++) { float centerY = getCenterYForRow(i); - for (int j = 0; j < 3; j++) { + for (int j = 0; j < mPatternSize; j++) { CellState cellState = mCellStates[i][j]; float centerX = getCenterXForColumn(j); float translationY = cellState.translationY; @@ -1109,8 +1170,10 @@ public class LockPatternView extends View { // TODO: the path should be created and cached every time we hit-detect a cell // only the last segment of the path should be computed here // draw the path of the pattern (unless we are in stealth mode) - final boolean drawPath = !mInStealthMode; - + // 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) + || (mPatternDisplayMode == DisplayMode.Wrong && mShowErrorPath)); if (drawPath) { mPathPaint.setColor(getCurrentColor(true /* partOfPattern */)); @@ -1196,9 +1259,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); + LockPatternUtils.patternToString(mPattern, mPatternSize), + mPatternDisplayMode.ordinal(), mPatternSize, + mInputEnabled, mInStealthMode, mEnableHapticFeedback, mVisibleDots, mShowErrorPath); } @Override @@ -1207,11 +1270,14 @@ public class LockPatternView extends View { super.onRestoreInstanceState(ss.getSuperState()); setPattern( DisplayMode.Correct, - LockPatternUtils.stringToPattern(ss.getSerializedPattern())); + LockPatternUtils.stringToPattern(ss.getSerializedPattern(), ss.getPatternSize())); mPatternDisplayMode = DisplayMode.values()[ss.getDisplayMode()]; + mPatternSize = ss.getPatternSize(); mInputEnabled = ss.isInputEnabled(); mInStealthMode = ss.isInStealthMode(); mEnableHapticFeedback = ss.isTactileFeedbackEnabled(); + mVisibleDots = ss.isVisibleDots(); + mShowErrorPath = ss.isShowErrorPath(); } /** @@ -1221,21 +1287,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; } /** @@ -1245,9 +1318,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() { @@ -1258,6 +1334,10 @@ public class LockPatternView extends View { return mDisplayMode; } + public byte getPatternSize() { + return mPatternSize; + } + public boolean isInputEnabled() { return mInputEnabled; } @@ -1270,14 +1350,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); } @SuppressWarnings({ "unused", "hiding" }) // Found using reflection diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java index 9a91ca4..9fc253b 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java @@ -132,10 +132,16 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit mLockPatternView = (LockPatternView) findViewById(R.id.lockPatternView); mLockPatternView.setSaveEnabled(false); mLockPatternView.setOnPatternListener(new UnlockPatternListener()); + mLockPatternView.setLockPatternUtils(mLockPatternUtils); + mLockPatternView.setLockPatternSize(mLockPatternUtils.getLockPatternSize()); + + mLockPatternView.setVisibleDots(mLockPatternUtils.isVisibleDotsEnabled()); + mLockPatternView.setShowErrorPath(mLockPatternUtils.isShowErrorPath()); // stealth mode will be the same for the life of this screen mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled( KeyguardUpdateMonitor.getCurrentUser())); + setFocusableInTouchMode(true); // vibrate mode will be the same for the life of this screen mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled()); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index 3af1d36..b3ec295 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -721,6 +721,9 @@ class DatabaseHelper extends SQLiteOpenHelper { Secure.LOCK_PATTERN_ENABLED, Secure.LOCK_PATTERN_VISIBLE, Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, + Secure.LOCK_PATTERN_SIZE, + Secure.LOCK_DOTS_VISIBLE, + Secure.LOCK_SHOW_ERROR_PATH, "lockscreen.password_type", "lockscreen.lockoutattemptdeadline", "lockscreen.patterneverchosen", @@ -2241,7 +2244,7 @@ class DatabaseHelper extends SQLiteOpenHelper { try { LockPatternUtils lpu = new LockPatternUtils(mContext); List<LockPatternView.Cell> cellPattern = - LockPatternUtils.stringToPattern(lockPattern); + LockPatternUtils.stringToPattern(lockPattern, lpu.getLockPatternSize()); lpu.saveLockPattern(cellPattern, null, UserHandle.USER_OWNER); } catch (IllegalArgumentException e) { // Don't want corrupted lock pattern to hang the reboot process diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 1dbb054..bb0615d 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -446,6 +446,10 @@ public class LockSettingsService extends ILockSettings.Stub { } + public byte getLockPatternSize(int userId) { + return mStorage.getLockPatternSize(userId); + } + @Override public void setLockPattern(String pattern, String savedCredential, int userId) throws RemoteException { @@ -563,8 +567,10 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public byte[] toHash(String pattern, int userId) { + final byte lockPatternSize = getLockPatternSize(userId); return LockPatternUtils.patternToHash( - LockPatternUtils.stringToPattern(pattern)); + LockPatternUtils.stringToPattern(pattern, lockPatternSize), + lockPatternSize); } @Override @@ -803,7 +809,10 @@ public class LockSettingsService extends ILockSettings.Stub { Secure.LOCK_PATTERN_ENABLED, Secure.LOCK_BIOMETRIC_WEAK_FLAGS, Secure.LOCK_PATTERN_VISIBLE, - Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED + Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, + Secure.LOCK_PATTERN_SIZE, + Secure.LOCK_DOTS_VISIBLE, + Secure.LOCK_SHOW_ERROR_PATH, }; // Reading these settings needs the contacts permission diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java index de48e71..72e05c1 100644 --- a/services/core/java/com/android/server/LockSettingsStorage.java +++ b/services/core/java/com/android/server/LockSettingsStorage.java @@ -16,6 +16,8 @@ package com.android.server; +import android.os.RemoteException; +import android.provider.Settings; import com.android.internal.annotations.VisibleForTesting; import android.content.ContentValues; @@ -29,6 +31,7 @@ import android.os.UserManager; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; +import com.android.internal.widget.LockPatternUtils; import java.io.File; import java.io.IOException; @@ -328,7 +331,10 @@ class LockSettingsStorage { mStoredCredentialType = hash == null ? CredentialHash.TYPE_NONE : CredentialHash.TYPE_PATTERN; - writeFile(getLockPatternFilename(userId), hash); + + boolean defaultSize = isDefaultSize(userId); + writeFile(getLockPatternFilename(userId, defaultSize), hash); + clearPasswordHash(userId); } @@ -348,9 +354,22 @@ class LockSettingsStorage { writeFile(getLockPasswordFilename(userId), null); } + public byte getLockPatternSize(int userId) { + long size = Long.valueOf(readKeyValue(Settings.Secure.LOCK_PATTERN_SIZE, "-1", userId)); + if (size > 0 && size < 128) { + return (byte) size; + } + return LockPatternUtils.PATTERN_SIZE_DEFAULT; + } + + public boolean isDefaultSize(int userId) { + return getLockPatternSize(userId) == LockPatternUtils.PATTERN_SIZE_DEFAULT; + } + @VisibleForTesting String getLockPatternFilename(int userId) { - return getLockCredentialFilePathForUser(userId, LOCK_PATTERN_FILE); + String baseFileName = LOCK_PATTERN_FILE; + return getLockCredentialFilePathForUser(userId, baseFileName); } @VisibleForTesting |