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..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.patternToString(mPatternLockView, progressPattern)); + Arrays.toString(PatternLockUtils.patternToIntArray(mPatternLockView, progressPattern))); } @Override public void onComplete(List pattern) { Log.d(getClass().getName(), "Pattern complete: " + - PatternLockUtils.patternToString(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.patternToString(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.patternToString(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 1624fd0..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; @@ -391,7 +392,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 +402,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(); @@ -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]; @@ -1264,7 +1271,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 +1280,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 +1298,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 +1328,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); 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..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"); @@ -44,87 +40,38 @@ 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; } /** * 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 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; } - /** - * 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. *