From 8311a33bc66a456466ddf98e0aef8a58801c371d Mon Sep 17 00:00:00 2001 From: yungtravla Date: Wed, 5 Jun 2019 20:29:26 +1000 Subject: [PATCH 1/6] fix: use int[] instead of string to allow dots with double digit indexes (stringToPattern becomes intArrayToPattern) --- .../patternlockview/utils/PatternLockUtils.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java b/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java index 545785b..b292f3c 100755 --- a/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java +++ b/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java @@ -65,14 +65,13 @@ public static String patternToString(PatternLockView patternLockView, * @param string The pattern serialized with {@link #patternToString} * @return The actual pattern */ - public static List stringToPattern(PatternLockView patternLockView, - String string) { + public static List intArrayToPattern(PatternLockView patternLockView, + int[] combination) { List result = new ArrayList<>(); - for (int i = 0; i < string.length(); i++) { - int number = Character.getNumericValue(string.charAt(i)); - result.add(PatternLockView.Dot.of(number / patternLockView.getDotCount(), - number % patternLockView.getDotCount())); + for (int i = 0; i < combination.length; i++) { + result.add(PatternLockView.Dot.of(combination[i] / patternLockView.getDotCount(), + combination[i] % patternLockView.getDotCount())); } return result; } From d5b1eebe81bca189f7a628c233b3909b3954ca0f Mon Sep 17 00:00:00 2001 From: yungtravla Date: Fri, 7 Jun 2019 02:15:36 +1000 Subject: [PATCH 2/6] remove unsafe pattern conversion methods + add patternToIntArray method --- .../utils/PatternLockUtils.java | 64 +++---------------- 1 file changed, 8 insertions(+), 56 deletions(-) diff --git a/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java b/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java index b292f3c..3322611 100755 --- a/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java +++ b/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java @@ -44,19 +44,19 @@ private PatternLockUtils() { * @param pattern The actual pattern * @return The pattern in its string form */ - public static String patternToString(PatternLockView patternLockView, - List pattern) { + + public static int[] patternToIntArray(PatternLockView patternLockView, + List pattern) { if (pattern == null) { - return ""; + return new int[0]; } int patternSize = pattern.size(); - StringBuilder stringBuilder = new StringBuilder(); - + int[] patternIntArray = new int[patternSize]; for (int i = 0; i < patternSize; i++) { PatternLockView.Dot dot = pattern.get(i); - stringBuilder.append((dot.getRow() * patternLockView.getDotCount() + dot.getColumn())); + patternIntArray[i] = (dot.getRow() * patternLockView.getDotCount() + dot.getColumn()); } - return stringBuilder.toString(); + return patternIntArray; } /** @@ -66,7 +66,7 @@ public static String patternToString(PatternLockView patternLockView, * @return The actual pattern */ public static List intArrayToPattern(PatternLockView patternLockView, - int[] combination) { + int[] combination) { List result = new ArrayList<>(); for (int i = 0; i < combination.length; i++) { @@ -76,54 +76,6 @@ public static List intArrayToPattern(PatternLockView patter return result; } - /** - * Serializes a given pattern to its equivalent SHA-1 representation. You can store this string - * in any persistence storage or send it to the server for verification - * - * @param pattern The actual pattern - * @return The SHA-1 string of the pattern - */ - public static String patternToSha1(PatternLockView patternLockView, - List pattern) { - try { - MessageDigest messageDigest = MessageDigest.getInstance(SHA1); - messageDigest.update(patternToString(patternLockView, pattern).getBytes(UTF8)); - - byte[] digest = messageDigest.digest(); - BigInteger bigInteger = new BigInteger(1, digest); - return String.format((Locale) null, - "%0" + (digest.length * 2) + "x", bigInteger).toLowerCase(); - } catch (NoSuchAlgorithmException e) { - return null; - } catch (UnsupportedEncodingException e) { - return null; - } - } - - /** - * Serializes a given pattern to its equivalent MD5 representation. You can store this string - * in any persistence storage or send it to the server for verification - * - * @param pattern The actual pattern - * @return The MD5 string of the pattern - */ - public static String patternToMD5(PatternLockView patternLockView, - List pattern) { - try { - MessageDigest messageDigest = MessageDigest.getInstance(MD5); - messageDigest.update(patternToString(patternLockView, pattern).getBytes(UTF8)); - - byte[] digest = messageDigest.digest(); - BigInteger bigInteger = new BigInteger(1, digest); - return String.format((Locale) null, - "%0" + (digest.length * 2) + "x", bigInteger).toLowerCase(); - } catch (NoSuchAlgorithmException e) { - return null; - } catch (UnsupportedEncodingException e) { - return null; - } - } - /** * Generates a random "CAPTCHA" pattern. The generated pattern is easy for the user to re-draw. *

From 136057e81a76b004e2bb9b817bb8fe61eaa424e5 Mon Sep 17 00:00:00 2001 From: yungtravla Date: Fri, 7 Jun 2019 02:28:57 +1000 Subject: [PATCH 3/6] replace pattern value strings to int arrays --- .../java/com/andrognito/patternlockview/PatternLockView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java b/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java index 1624fd0..72dda7b 100755 --- a/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java +++ b/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java @@ -391,7 +391,7 @@ protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); return new SavedState(superState, - PatternLockUtils.patternToString(this, mPattern), + PatternLockUtils.patternToIntArray(this, mPattern), mPatternViewMode, mInputEnabled, mInStealthMode, mEnableHapticFeedback); } @@ -401,7 +401,7 @@ protected void onRestoreInstanceState(Parcelable state) { final SavedState savedState = (SavedState) state; super.onRestoreInstanceState(savedState.getSuperState()); setPattern(CORRECT, - PatternLockUtils.stringToPattern(this, savedState.getSerializedPattern())); + PatternLockUtils.intArrayToPattern(this, savedState.getSerializedPattern())); mPatternViewMode = savedState.getDisplayMode(); mInputEnabled = savedState.isInputEnabled(); mInStealthMode = savedState.isInStealthMode(); From 12a7be5e5b1bee4a889abd13721822779f9630f2 Mon Sep 17 00:00:00 2001 From: yungtravla Date: Fri, 7 Jun 2019 02:57:28 +1000 Subject: [PATCH 4/6] replace unsafe pattern string values with int[] --- README.md | 8 ++++---- .../java/com/andrognito/patternlockdemo/MainActivity.java | 8 ++++---- .../patternlockview/utils/PatternLockUtils.java | 6 +----- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a07896e..9ca7256 100644 --- a/README.md +++ b/README.md @@ -71,13 +71,13 @@ private PatternLockViewListener mPatternLockViewListener = new PatternLockViewLi @Override public void onProgress(List progressPattern) { Log.d(getClass().getName(), "Pattern progress: " + - PatternLockUtils.patternToString(mPatternLockView, progressPattern)); + PatternLockUtils.patternToIntArray(mPatternLockView, progressPattern)); } @Override public void onComplete(List pattern) { Log.d(getClass().getName(), "Pattern complete: " + - PatternLockUtils.patternToString(mPatternLockView, pattern)); + PatternLockUtils.patternToIntArray(mPatternLockView, pattern)); } @Override @@ -103,10 +103,10 @@ RxPatternLockView.patternChanges(mPatternLockView) Log.d(getClass().getName(), "Pattern drawing started"); } else if (event.getEventType() == PatternLockCompoundEvent.EventType.PATTERN_PROGRESS) { Log.d(getClass().getName(), "Pattern progress: " + - PatternLockUtils.patternToString(mPatternLockView, event.getPattern())); + PatternLockUtils.patternToIntArray(mPatternLockView, event.getPattern())); } else if (event.getEventType() == PatternLockCompoundEvent.EventType.PATTERN_COMPLETE) { Log.d(getClass().getName(), "Pattern complete: " + - PatternLockUtils.patternToString(mPatternLockView, event.getPattern())); + PatternLockUtils.patternToIntArray(mPatternLockView, event.getPattern())); } else if (event.getEventType() == PatternLockCompoundEvent.EventType.PATTERN_CLEARED) { Log.d(getClass().getName(), "Pattern has been cleared"); } diff --git a/app/src/main/java/com/andrognito/patternlockdemo/MainActivity.java b/app/src/main/java/com/andrognito/patternlockdemo/MainActivity.java index a1657e1..5a052cd 100644 --- a/app/src/main/java/com/andrognito/patternlockdemo/MainActivity.java +++ b/app/src/main/java/com/andrognito/patternlockdemo/MainActivity.java @@ -31,13 +31,13 @@ public void onStarted() { @Override public void onProgress(List progressPattern) { Log.d(getClass().getName(), "Pattern progress: " + - PatternLockUtils.patternToString(mPatternLockView, progressPattern)); + PatternLockUtils.patternToIntArray(mPatternLockView, progressPattern)); } @Override public void onComplete(List pattern) { Log.d(getClass().getName(), "Pattern complete: " + - PatternLockUtils.patternToString(mPatternLockView, pattern)); + PatternLockUtils.patternToIntArray(mPatternLockView, pattern)); } @Override @@ -86,10 +86,10 @@ public void accept(PatternLockCompoundEvent event) throws Exception { Log.d(getClass().getName(), "Pattern drawing started"); } else if (event.getEventType() == PatternLockCompoundEvent.EventType.PATTERN_PROGRESS) { Log.d(getClass().getName(), "Pattern progress: " + - PatternLockUtils.patternToString(mPatternLockView, event.getPattern())); + PatternLockUtils.patternToIntArray(mPatternLockView, event.getPattern())); } else if (event.getEventType() == PatternLockCompoundEvent.EventType.PATTERN_COMPLETE) { Log.d(getClass().getName(), "Pattern complete: " + - PatternLockUtils.patternToString(mPatternLockView, event.getPattern())); + PatternLockUtils.patternToIntArray(mPatternLockView, event.getPattern())); } else if (event.getEventType() == PatternLockCompoundEvent.EventType.PATTERN_CLEARED) { Log.d(getClass().getName(), "Pattern has been cleared"); } diff --git a/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java b/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java index 3322611..30a4a37 100755 --- a/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java +++ b/patternlockview/src/main/java/com/andrognito/patternlockview/utils/PatternLockUtils.java @@ -28,10 +28,6 @@ public class PatternLockUtils { - private static final String UTF8 = "UTF-8"; - private static final String SHA1 = "SHA-1"; - private static final String MD5 = "MD5"; - private PatternLockUtils() { throw new AssertionError("You can not instantiate this class. Use its static utility " + "methods instead"); @@ -62,7 +58,7 @@ public static int[] patternToIntArray(PatternLockView patternLockView, /** * De-serializes a given string to its equivalent pattern representation * - * @param string The pattern serialized with {@link #patternToString} + * @param int[] The pattern serialized with {@link #patternToIntArray} * @return The actual pattern */ public static List intArrayToPattern(PatternLockView patternLockView, From 2bac40f09176d9fe443e7b11f9d0cfcfd5fccd3c Mon Sep 17 00:00:00 2001 From: yungtravla Date: Fri, 7 Jun 2019 15:29:37 +1000 Subject: [PATCH 5/6] improve library's compatibility with int[] pattern values --- .../com/andrognito/patternlockdemo/MainActivity.java | 9 +++++---- .../andrognito/patternlockview/PatternLockView.java | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/andrognito/patternlockdemo/MainActivity.java b/app/src/main/java/com/andrognito/patternlockdemo/MainActivity.java index 5a052cd..33098c1 100644 --- a/app/src/main/java/com/andrognito/patternlockdemo/MainActivity.java +++ b/app/src/main/java/com/andrognito/patternlockdemo/MainActivity.java @@ -14,6 +14,7 @@ import com.andrognito.rxpatternlockview.events.PatternLockCompleteEvent; import com.andrognito.rxpatternlockview.events.PatternLockCompoundEvent; +import java.util.Arrays; import java.util.List; import io.reactivex.functions.Consumer; @@ -31,13 +32,13 @@ public void onStarted() { @Override public void onProgress(List progressPattern) { Log.d(getClass().getName(), "Pattern progress: " + - PatternLockUtils.patternToIntArray(mPatternLockView, progressPattern)); + Arrays.toString(PatternLockUtils.patternToIntArray(mPatternLockView, progressPattern))); } @Override public void onComplete(List pattern) { Log.d(getClass().getName(), "Pattern complete: " + - PatternLockUtils.patternToIntArray(mPatternLockView, pattern)); + Arrays.toString(PatternLockUtils.patternToIntArray(mPatternLockView, pattern))); } @Override @@ -86,10 +87,10 @@ public void accept(PatternLockCompoundEvent event) throws Exception { Log.d(getClass().getName(), "Pattern drawing started"); } else if (event.getEventType() == PatternLockCompoundEvent.EventType.PATTERN_PROGRESS) { Log.d(getClass().getName(), "Pattern progress: " + - PatternLockUtils.patternToIntArray(mPatternLockView, event.getPattern())); + Arrays.toString(PatternLockUtils.patternToIntArray(mPatternLockView, event.getPattern()))); } else if (event.getEventType() == PatternLockCompoundEvent.EventType.PATTERN_COMPLETE) { Log.d(getClass().getName(), "Pattern complete: " + - PatternLockUtils.patternToIntArray(mPatternLockView, event.getPattern())); + Arrays.toString(PatternLockUtils.patternToIntArray(mPatternLockView, event.getPattern()))); } else if (event.getEventType() == PatternLockCompoundEvent.EventType.PATTERN_CLEARED) { Log.d(getClass().getName(), "Pattern has been cleared"); } diff --git a/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java b/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java index 72dda7b..5ba2891 100755 --- a/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java +++ b/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java @@ -401,7 +401,7 @@ protected void onRestoreInstanceState(Parcelable state) { final SavedState savedState = (SavedState) state; super.onRestoreInstanceState(savedState.getSuperState()); setPattern(CORRECT, - PatternLockUtils.intArrayToPattern(this, savedState.getSerializedPattern())); + PatternLockUtils.intArrayToPattern(this, savedState.getSerializedPattern())); mPatternViewMode = savedState.getDisplayMode(); mInputEnabled = savedState.isInputEnabled(); mInStealthMode = savedState.isInStealthMode(); @@ -1264,7 +1264,7 @@ private Dot(Parcel in) { */ private static class SavedState extends BaseSavedState { - private final String mSerializedPattern; + private final int[] mSerializedPattern; private final int mDisplayMode; private final boolean mInputEnabled; private final boolean mInStealthMode; @@ -1273,7 +1273,7 @@ private static class SavedState extends BaseSavedState { /** * Constructor called from {@link PatternLockView#onSaveInstanceState()} */ - private SavedState(Parcelable superState, String serializedPattern, + private SavedState(Parcelable superState, int[] serializedPattern, int displayMode, boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled) { super(superState); @@ -1291,14 +1291,14 @@ private SavedState(Parcelable superState, String serializedPattern, private SavedState(Parcel in) { super(in); - mSerializedPattern = in.readString(); + mSerializedPattern = in.createIntArray(); mDisplayMode = in.readInt(); mInputEnabled = (Boolean) in.readValue(null); mInStealthMode = (Boolean) in.readValue(null); mTactileFeedbackEnabled = (Boolean) in.readValue(null); } - public String getSerializedPattern() { + public int[] getSerializedPattern() { return mSerializedPattern; } @@ -1321,7 +1321,7 @@ public boolean isTactileFeedbackEnabled() { @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); - dest.writeString(mSerializedPattern); + dest.writeIntArray(mSerializedPattern); dest.writeInt(mDisplayMode); dest.writeValue(mInputEnabled); dest.writeValue(mInStealthMode); From 780fc91d27ac657dbf0cee66c879e77c08044a6b Mon Sep 17 00:00:00 2001 From: yungtravla Date: Sun, 8 Sep 2019 05:20:54 +1000 Subject: [PATCH 6/6] Update PatternLockView.java --- .../com/andrognito/patternlockview/PatternLockView.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java b/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java index 5ba2891..a7632ba 100755 --- a/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java +++ b/patternlockview/src/main/java/com/andrognito/patternlockview/PatternLockView.java @@ -112,6 +112,7 @@ public class PatternLockView extends View { private float mHitFactor = 0.6f; // Made static so that the static inner class can use it + private static Dot[][] sDots; private static int sDotCount; private boolean mAspectRatioEnabled; @@ -578,6 +579,13 @@ public void setViewMode(@PatternViewMode int patternViewMode) { public void setDotCount(int dotCount) { sDotCount = dotCount; + sDots = new Dot[sDotCount][sDotCount]; + for (int i = 0; i < sDotCount; i++) { + for (int j = 0; j < sDotCount; j++) { + sDots[i][j] = new Dot(i, j); + } + } + mPatternSize = sDotCount * sDotCount; mPattern = new ArrayList<>(mPatternSize); mPatternDrawLookup = new boolean[sDotCount][sDotCount]; @@ -1149,7 +1157,6 @@ public static class Dot implements Parcelable { private int mRow; private int mColumn; - private static Dot[][] sDots; static { sDots = new Dot[sDotCount][sDotCount];