diff --git a/About.md b/About.md new file mode 100644 index 0000000..c5cb874 --- /dev/null +++ b/About.md @@ -0,0 +1,3 @@ +The author -- Hai Bison -- is available for work at [oDesk](https://www.odesk.com/users/~012e482afb87d7637c) or [Elance](https://www.elance.com/s/haibison/). + +He's a little funny and hard working :-) \ No newline at end of file diff --git a/AdvancedOptions.md b/AdvancedOptions.md new file mode 100644 index 0000000..b2784ba --- /dev/null +++ b/AdvancedOptions.md @@ -0,0 +1,24 @@ +## Minimum Wired Dots ## + +By default, minimum wired dots required are `4`. You can configure that limit with helper class [Settings.Display](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/util/Settings.Display.html), the valid value is in range `1`-`9`. For example, to change it to `3`: + +``` +import com.haibison.android.lockpattern.util.Settings; + +... + +Settings.Display.setMinWiredDots(your-context, 3); +``` + + +## Maximum Retries ## + +By default, in comparing pattern mode, maximum retries allowed are `5`. For example, to change it to `3`: + +``` +Settings.Display.setMaxRetries(your-context, 3); +``` + +## Delivering result to a [PendingIntent](http://developer.android.com/reference/android/app/PendingIntent.html) or [ResultReceiver](http://developer.android.com/reference/android/os/ResultReceiver.html) ## + +You can put a `PendingIntent` to [EXTRA\_PENDING\_INTENT\_OK](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#EXTRA_PENDING_INTENT_OK) or [EXTRA\_PENDING\_INTENT\_CANCELLED](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#EXTRA_PENDING_INTENT_CANCELLED). The library will call that intent according to the result. Also, to deliver the result to a `ResultReceiver`, you can use key [EXTRA\_RESULT\_RECEIVER](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#EXTRA_RESULT_RECEIVER). \ No newline at end of file diff --git a/AndroidManifest.md b/AndroidManifest.md new file mode 100644 index 0000000..e16bcce --- /dev/null +++ b/AndroidManifest.md @@ -0,0 +1,25 @@ +All configurations with helper class [Settings](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/util/Settings.html) (and all of its nested classes) must be called before you start [LockPatternActivity](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html). But you _can_ configure settings in an activity and call `LockPatternActivity` in another activity. + +However that could make the usage more complicated. So there's an option: You can also configure settings directly via your app's `AndroidManifest.xml`. For details, refer to class `Settings`. Note that the values in the manifest get higher priority than the ones from this class. + +For example, this is used in the demo app: + +``` + + + + +``` + +If you use ProGuard _and_ set your encrypter class via manifest like above, remember to ignore your encrypter class: +``` +-keep class group.pals.android.lib.ui.lockpattern.demo.LPEncrypter { *; } +``` \ No newline at end of file diff --git a/AppsOnGooglePlay.md b/AppsOnGooglePlay.md new file mode 100644 index 0000000..76b148d --- /dev/null +++ b/AppsOnGooglePlay.md @@ -0,0 +1,12 @@ + + +<hr> + + + +If you have apps on Google Play which use this library, and you would like to show your apps here, please send us an email. + +### Notes ### + + * The apps are listed in order of notification to us. + * Please include the link to its home on Google Play. \ No newline at end of file diff --git a/Credits.md b/Credits.md new file mode 100644 index 0000000..5596770 --- /dev/null +++ b/Credits.md @@ -0,0 +1,7 @@ +We sincerely thank all of our friends — who have been contributing to this project. We hope this project will be always useful for everyone. + + * C + * [Steven Byle](http://stackoverflow.com/users/1507439/steven-byle) + * Thomas Breitbach + * Yan Cheng Cheok (Project Admin of [JStock](http://jstock.sourceforge.net/)) + * And others. \ No newline at end of file diff --git a/Encryption.md b/Encryption.md new file mode 100644 index 0000000..938f8fd --- /dev/null +++ b/Encryption.md @@ -0,0 +1,72 @@ +It will be more secure if for each app, you have a unique encrypter — to encrypt the pattern on your own way. + +# Details # + +For example, here is a simple encrypter (which is used in the demo app), we name it `LPEncrypter`: +``` +package ... + +import com.haibison.android.lockpattern.collect.Lists; +import com.haibison.android.lockpattern.util.IEncrypter; +import com.haibison.android.lockpattern.widget.LockPatternView.Cell; + +import java.util.List; + +import android.content.Context; + +public class LPEncrypter implements IEncrypter { + + @Override + public char[] encrypt(Context context, List pattern) { + /* + * This is a simple example. And it's also worth mentioning that this is + * a very weak encrypter, just for fun :-) + */ + + StringBuilder result = new StringBuilder(); + for (Cell cell : pattern) + result.append(Integer.toString(cell.getId() + 1)).append('-'); + + return result.substring(0, result.length() - 1).toCharArray(); + }// encrypt() + + @Override + public List decrypt(Context context, char[] encryptedPattern) { + List result = Lists.newArrayList(); + String[] ids = new String(encryptedPattern).split("[^0-9]"); + for (String id : ids) + result.add(Cell.of(Integer.parseInt(id) - 1)); + + return result; + }// decrypt() + +} +``` + +Usage: +``` +import com.haibison.android.lockpattern.util.Settings; + +... + +Settings.Security.setEncrypterClass(your-context, LPEncrypter.class); +``` + +Or via [AndroidManifest.xml](AndroidManifest.md): +``` + + + +``` + +You might want to take a look at built-in class [SimpleWeakEncryption](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/util/SimpleWeakEncryption.html). However, like its name suggests, it is just a _simple and weak_ encryption utility. Use it on your own risk :-) + +# Notes # + + * Classes implementing [IEncrypter](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/util/IEncrypter.html) must have one zero-argument constructor. Otherwise, an [InvalidEncrypterException](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/util/InvalidEncrypterException.html) will be thrown. \ No newline at end of file diff --git a/FAQs.md b/FAQs.md new file mode 100644 index 0000000..f66da91 --- /dev/null +++ b/FAQs.md @@ -0,0 +1,13 @@ +### I'm new, where should I start? ### + +Please, have a look at [Quick Use](QuickUse.md). + +### Why resources are named with prefix `alp_42447968_`? ### + +To avoid of collisions of resources with other libraries, or with the host project. At first we've tried `alp_`, but to make it safer, we've added a CRC-32 string `42447968_`. A CRC-32 string is shorter than an MD-5 string, and we think that would be safe enough. + +### Where are preferences/settings saved? ### + +On app's internal storage. Preferences files are named with suffix `a6eedbe5-1cf9-4684-8134-ad4ec9f6a131` (constant [Sys.UID](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/util/Sys.html#UID)). And for your information, `42447968` is CRC-32 of above suffix. + +And of course, the library's preferences don't mess with your app's own preferences, or other libraries' preferences. \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 2a1bef4..0000000 --- a/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/LockPatternViewTest/.classpath b/LockPatternViewTest/.classpath deleted file mode 100644 index 7bc01d9..0000000 --- a/LockPatternViewTest/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/LockPatternViewTest/.project b/LockPatternViewTest/.project deleted file mode 100644 index 80f24df..0000000 --- a/LockPatternViewTest/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - LockPatternViewTest - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/LockPatternViewTest/AndroidManifest.xml b/LockPatternViewTest/AndroidManifest.xml deleted file mode 100644 index 6385e72..0000000 --- a/LockPatternViewTest/AndroidManifest.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/LockPatternViewTest/build.xml b/LockPatternViewTest/build.xml deleted file mode 100644 index c8cb426..0000000 --- a/LockPatternViewTest/build.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/LockPatternViewTest/proguard-project.txt b/LockPatternViewTest/proguard-project.txt deleted file mode 100644 index f2fe155..0000000 --- a/LockPatternViewTest/proguard-project.txt +++ /dev/null @@ -1,20 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/LockPatternViewTest/project.properties b/LockPatternViewTest/project.properties deleted file mode 100644 index 6e18427..0000000 --- a/LockPatternViewTest/project.properties +++ /dev/null @@ -1,14 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Project target. -target=android-21 diff --git a/LockPatternViewTest/res/drawable-hdpi/ic_launcher.png b/LockPatternViewTest/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index 96a442e..0000000 Binary files a/LockPatternViewTest/res/drawable-hdpi/ic_launcher.png and /dev/null differ diff --git a/LockPatternViewTest/res/drawable-mdpi/ic_launcher.png b/LockPatternViewTest/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 359047d..0000000 Binary files a/LockPatternViewTest/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/LockPatternViewTest/res/drawable-xhdpi/ic_launcher.png b/LockPatternViewTest/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 71c6d76..0000000 Binary files a/LockPatternViewTest/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/LockPatternViewTest/res/values-v11/styles.xml b/LockPatternViewTest/res/values-v11/styles.xml deleted file mode 100644 index b1d0383..0000000 --- a/LockPatternViewTest/res/values-v11/styles.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/LockPatternViewTest/res/values-v21/styles.xml b/LockPatternViewTest/res/values-v21/styles.xml deleted file mode 100644 index b471c82..0000000 --- a/LockPatternViewTest/res/values-v21/styles.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/LockPatternViewTest/res/values/colors.xml b/LockPatternViewTest/res/values/colors.xml deleted file mode 100644 index 8f1e4ff..0000000 --- a/LockPatternViewTest/res/values/colors.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - #ffffffff - #ffffffff - #fff4511e - #ff37474f - #ff009688 - #fff4511e - - \ No newline at end of file diff --git a/LockPatternViewTest/res/values/dimens.xml b/LockPatternViewTest/res/values/dimens.xml deleted file mode 100644 index 3bba14a..0000000 --- a/LockPatternViewTest/res/values/dimens.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - 3dp - 12dp - 28dp - - \ No newline at end of file diff --git a/LockPatternViewTest/res/values/strings.xml b/LockPatternViewTest/res/values/strings.xml deleted file mode 100644 index 4425e25..0000000 --- a/LockPatternViewTest/res/values/strings.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - LockPatternView Test - - - Pattern started - - Pattern cleared - - Cell added - - Pattern completed - - \ No newline at end of file diff --git a/LockPatternViewTest/res/values/styles.xml b/LockPatternViewTest/res/values/styles.xml deleted file mode 100644 index f1699ff..0000000 --- a/LockPatternViewTest/res/values/styles.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/LockPatternViewTest/src/app/MainActivity.java b/LockPatternViewTest/src/app/MainActivity.java deleted file mode 100644 index 7319c1b..0000000 --- a/LockPatternViewTest/src/app/MainActivity.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012 Hai Bison - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package app; - -import android.app.Activity; -import android.os.Bundle; - -import com.android.internal.widget.LockPatternViewEx; - -/** - * Main activity. - * - * @author Hai Bison - * - */ -public class MainActivity extends Activity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(new LockPatternViewEx(this)); - }// onCreate() - -} diff --git a/LockPatternViewTest/src/app/utils/Resources.java b/LockPatternViewTest/src/app/utils/Resources.java deleted file mode 100644 index c4fbd6c..0000000 --- a/LockPatternViewTest/src/app/utils/Resources.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2012 Hai Bison - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package app.utils; - -import android.content.Context; -import android.util.TypedValue; - -/** - * Resources' utilities. - * - * @author Hai Bison - * - */ -public class Resources { - - /** - * This is singleton class. - */ - private Resources() { - }// Resources() - - /** - * Convenient method for {@link Context#getTheme()} and - * {@link Resources.Theme#resolveAttribute(int, TypedValue, boolean)}. - * - * @param context - * the context. - * @param resId - * The resource identifier of the desired theme attribute. - * @return the resource ID that {@link TypedValue#resourceId} points to, or - * {@code 0} if not found. - */ - public static int resolveAttribute(Context context, int resId) { - return resolveAttribute(context, resId, 0); - }// resolveAttribute() - - /** - * Convenient method for {@link Context#getTheme()} and - * {@link Resources.Theme#resolveAttribute(int, TypedValue, boolean)}. - * - * @param context - * the context. - * @param resId - * The resource identifier of the desired theme attribute. - * @param defaultValue - * the default value if cannot resolve {@code resId}. - * @return the resource ID that {@link TypedValue#resourceId} points to, or - * {@code defaultValue} if not found. - */ - public static int resolveAttribute(Context context, int resId, - int defaultValue) { - TypedValue typedValue = new TypedValue(); - if (context.getTheme().resolveAttribute(resId, typedValue, true)) - return typedValue.resourceId; - return defaultValue; - }// resolveAttribute() - -} diff --git a/LockPatternViewTest/src/com/android/internal/widget/LockPatternUtils.java b/LockPatternViewTest/src/com/android/internal/widget/LockPatternUtils.java deleted file mode 100644 index f131981..0000000 --- a/LockPatternViewTest/src/com/android/internal/widget/LockPatternUtils.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.widget; - -import java.util.List; - -import com.google.android.collect.Lists; - -/** - * Utilities for the lock pattern and its settings. - */ -public class LockPatternUtils { - - /** - * Deserialize a pattern. - * - * @param string - * The pattern serialized with {@link #patternToString} - * @return The pattern. - */ - public static List stringToPattern(String string) { - List result = Lists.newArrayList(); - - final byte[] bytes = string.getBytes(); - for (int i = 0; i < bytes.length; i++) { - byte b = bytes[i]; - result.add(LockPatternViewEx.Cell.of(b / 3, b % 3)); - } - return result; - } - - /** - * Serialize a pattern. - * - * @param pattern - * The pattern. - * @return The pattern in string form. - */ - public static String patternToString(List pattern) { - if (pattern == null) { - return ""; - } - final int patternSize = pattern.size(); - - byte[] res = new byte[patternSize]; - for (int i = 0; i < patternSize; i++) { - LockPatternViewEx.Cell cell = pattern.get(i); - res[i] = (byte) (cell.getRow() * 3 + cell.getColumn()); - } - return new String(res); - } - -} diff --git a/LockPatternViewTest/src/com/android/internal/widget/LockPatternViewEx.java b/LockPatternViewTest/src/com/android/internal/widget/LockPatternViewEx.java deleted file mode 100644 index 0b5c67f..0000000 --- a/LockPatternViewTest/src/com/android/internal/widget/LockPatternViewEx.java +++ /dev/null @@ -1,1204 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.widget; - -import haibison.test.lockpatternview.R; - -import java.util.ArrayList; -import java.util.List; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.Rect; -import android.os.Build; -import android.os.Debug; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; -import android.util.AttributeSet; -import android.view.HapticFeedbackConstants; -import android.view.MotionEvent; -import android.view.View; -import android.view.accessibility.AccessibilityManager; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; -import app.utils.Resources; - -/** - * Displays and detects the user's unlock attempt, which is a drag of a finger - * across 9 regions of the screen. - * - * Is also capable of displaying a static pattern in "in progress", "wrong" or - * "correct" states. - */ -public class LockPatternViewEx extends View { - - // Aspect to use when rendering this view - private static final int ASPECT_SQUARE = 0; // View will be the minimum of - // width/height - private static final int ASPECT_LOCK_WIDTH = 1; // Fixed width; height will - // be minimum of (w,h) - 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 final int mDotSize; - private final int mDotSizeActivated; - private final int mPathWidth; - - private boolean mDrawingProfilingStarted = false; - - private Paint mPaint = new Paint(); - private Paint mPathPaint = new Paint(); - - /** - * How many milliseconds we spend animating each circle of a lock pattern if - * the animating mode is set. The entire animation should take this constant - * * the length of the pattern to complete. - */ - private static final int MILLIS_PER_CIRCLE_ANIMATING = 700; - - /** - * 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. - */ - private static final float DRAG_THRESHHOLD = 0.0f; - - private OnPatternListener mOnPatternListener; - private ArrayList mPattern = new ArrayList(9); - - /** - * Lookup table for the circles of the pattern we are currently drawing. - * This will be the cells of the complete pattern unless we are animating, - * 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]; - - /** - * the in progress point: - during interaction: where the user's finger is - - * during animation: the current tip of the animating line - */ - private float mInProgressX = -1; - private float mInProgressY = -1; - - private long mAnimatingPeriodStart; - - private DisplayMode mPatternDisplayMode = DisplayMode.Correct; - private boolean mInputEnabled = true; - private boolean mInStealthMode = false; - private boolean mEnableHapticFeedback = true; - private boolean mPatternInProgress = false; - - private float mHitFactor = 0.6f; - - private float mSquareWidth; - private float mSquareHeight; - - private final Path mCurrentPath = new Path(); - private final Rect mInvalidate = new Rect(); - private final Rect mTmpInvalidateRect = new Rect(); - - private int mAspect; - private int mRegularColor; - private int mErrorColor; - private int mSuccessColor; - - private Interpolator mFastOutSlowInInterpolator; - private Interpolator mLinearOutSlowInInterpolator; - - /** - * Represents a cell in the 3 X 3 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]; - static { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - sCells[i][j] = new Cell(i, j); - } - } - } - - /** - * @param row - * The row of the cell. - * @param column - * The column of the cell. - */ - private Cell(int row, int column) { - checkRange(row, column); - this.row = row; - this.column = column; - } - - public int getRow() { - return row; - } - - public int getColumn() { - return column; - } - - /** - * @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); - 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"); - } - if (column < 0 || column > 2) { - throw new IllegalArgumentException( - "column must be in range 0-2"); - } - } - - public String toString() { - return "(row=" + row + ",clmn=" + column + ")"; - } - } - - public static class CellState { - - public float scale = 1.0f; - public float translateY = 0.0f; - public float alpha = 1.0f; - public float size; - public float lineEndX = Float.MIN_VALUE; - public float lineEndY = Float.MIN_VALUE; - public ValueAnimator lineAnimator; - } - - /** - * How to display the current pattern. - */ - public enum DisplayMode { - - /** - * The pattern drawn is correct (i.e draw it in a friendly color) - */ - Correct, - - /** - * Animate the pattern (for demo, and help). - */ - Animate, - - /** - * The pattern is wrong (i.e draw a foreboding color) - */ - Wrong - } - - /** - * The call back interface for detecting patterns entered by the user. - */ - public static interface OnPatternListener { - - /** - * A new pattern has begun. - */ - void onPatternStart(); - - /** - * The pattern was cleared. - */ - void onPatternCleared(); - - /** - * The user extended the pattern currently being drawn by one cell. - * - * @param pattern - * The pattern with newly added cell. - */ - void onPatternCellAdded(List pattern); - - /** - * A pattern was detected from the user. - * - * @param pattern - * The pattern. - */ - void onPatternDetected(List pattern); - } - - public LockPatternViewEx(Context context) { - this(context, null); - } - - public LockPatternViewEx(Context context, AttributeSet attrs) { - super(context, attrs); - - TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.LockPatternViewEx); - - final String aspect = a.getString(R.styleable.LockPatternViewEx_aspect); - - if ("square".equals(aspect)) { - mAspect = ASPECT_SQUARE; - } else if ("lock_width".equals(aspect)) { - mAspect = ASPECT_LOCK_WIDTH; - } else if ("lock_height".equals(aspect)) { - mAspect = ASPECT_LOCK_HEIGHT; - } else { - mAspect = ASPECT_SQUARE; - } - - setClickable(true); - - mPathPaint.setAntiAlias(true); - mPathPaint.setDither(true); - - mRegularColor = getResources().getColor( - Resources.resolveAttribute(getContext(), - R.attr.color_lock_pattern_view_regular)); - mErrorColor = getResources().getColor( - Resources.resolveAttribute(getContext(), - R.attr.color_lock_pattern_view_error)); - mSuccessColor = getResources().getColor( - Resources.resolveAttribute(getContext(), - R.attr.color_lock_pattern_view_success)); - - mRegularColor = a.getColor(R.styleable.LockPatternViewEx_regularColor, - mRegularColor); - mErrorColor = a.getColor(R.styleable.LockPatternViewEx_errorColor, - mErrorColor); - mSuccessColor = a.getColor(R.styleable.LockPatternViewEx_successColor, - mSuccessColor); - - int pathColor = a.getColor(R.styleable.LockPatternViewEx_pathColor, - mRegularColor); - mPathPaint.setColor(pathColor); - - mPathPaint.setStyle(Paint.Style.STROKE); - mPathPaint.setStrokeJoin(Paint.Join.ROUND); - mPathPaint.setStrokeCap(Paint.Cap.ROUND); - - mPathWidth = getResources().getDimensionPixelSize( - R.dimen.lock_pattern_dot_line_width); - mPathPaint.setStrokeWidth(mPathWidth); - - mDotSize = getResources().getDimensionPixelSize( - R.dimen.lock_pattern_dot_size); - mDotSizeActivated = getResources().getDimensionPixelSize( - R.dimen.lock_pattern_dot_size_activated); - - 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[i][j] = new CellState(); - mCellStates[i][j].size = mDotSize; - } - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator( - context, android.R.interpolator.fast_out_slow_in); - mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator( - context, android.R.interpolator.linear_out_slow_in); - }// if - } - - public CellState[][] getCellStates() { - return mCellStates; - } - - /** - * @return Whether the view is in stealth mode. - */ - public boolean isInStealthMode() { - return mInStealthMode; - } - - /** - * @return Whether the view has tactile feedback enabled. - */ - public boolean isTactileFeedbackEnabled() { - return mEnableHapticFeedback; - } - - /** - * Set whether the view is in stealth mode. If true, there will be no - * visible feedback as the user enters the pattern. - * - * @param inStealthMode - * Whether in stealth mode. - */ - public void setInStealthMode(boolean inStealthMode) { - mInStealthMode = inStealthMode; - } - - /** - * Set whether the view will use tactile feedback. If true, there will be - * tactile feedback as the user enters the pattern. - * - * @param tactileFeedbackEnabled - * Whether tactile feedback is enabled - */ - public void setTactileFeedbackEnabled(boolean tactileFeedbackEnabled) { - mEnableHapticFeedback = tactileFeedbackEnabled; - } - - /** - * Set the call back for pattern detection. - * - * @param onPatternListener - * The call back. - */ - public void setOnPatternListener(OnPatternListener onPatternListener) { - mOnPatternListener = onPatternListener; - } - - /** - * Set the pattern explicitely (rather than waiting for the user to input a - * pattern). - * - * @param displayMode - * How to display the pattern. - * @param pattern - * The pattern. - */ - public void setPattern(DisplayMode displayMode, List pattern) { - mPattern.clear(); - mPattern.addAll(pattern); - clearPatternDrawLookup(); - for (Cell cell : pattern) { - mPatternDrawLookup[cell.getRow()][cell.getColumn()] = true; - } - - setDisplayMode(displayMode); - } - - /** - * Set the display mode of the current pattern. This can be useful, for - * instance, after detecting a pattern to tell this view whether change the - * in progress result to correct or wrong. - * - * @param displayMode - * The display mode. - */ - public void setDisplayMode(DisplayMode displayMode) { - mPatternDisplayMode = displayMode; - if (displayMode == DisplayMode.Animate) { - if (mPattern.size() == 0) { - throw new IllegalStateException( - "you must have a pattern to " - + "animate if you want to set the display mode to animate"); - } - mAnimatingPeriodStart = SystemClock.elapsedRealtime(); - final Cell first = mPattern.get(0); - mInProgressX = getCenterXForColumn(first.getColumn()); - mInProgressY = getCenterYForRow(first.getRow()); - clearPatternDrawLookup(); - } - invalidate(); - } - - private void notifyCellAdded() { - sendAccessEvent(R.string.lockscreen_access_pattern_cell_added); - if (mOnPatternListener != null) { - mOnPatternListener.onPatternCellAdded(mPattern); - } - } - - private void notifyPatternStarted() { - sendAccessEvent(R.string.lockscreen_access_pattern_start); - if (mOnPatternListener != null) { - mOnPatternListener.onPatternStart(); - } - } - - private void notifyPatternDetected() { - sendAccessEvent(R.string.lockscreen_access_pattern_detected); - if (mOnPatternListener != null) { - mOnPatternListener.onPatternDetected(mPattern); - } - } - - private void notifyPatternCleared() { - sendAccessEvent(R.string.lockscreen_access_pattern_cleared); - if (mOnPatternListener != null) { - mOnPatternListener.onPatternCleared(); - } - } - - /** - * Clear the pattern. - */ - public void clearPattern() { - resetPattern(); - } - - /** - * Reset all pattern state. - */ - private void resetPattern() { - mPattern.clear(); - clearPatternDrawLookup(); - mPatternDisplayMode = DisplayMode.Correct; - invalidate(); - } - - /** - * Clear the pattern lookup table. - */ - private void clearPatternDrawLookup() { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - mPatternDrawLookup[i][j] = false; - } - } - } - - /** - * Disable input (for instance when displaying a message that will timeout - * so user doesn't get view into messy state). - */ - public void disableInput() { - mInputEnabled = false; - } - - /** - * Enable input. - */ - public void enableInput() { - mInputEnabled = true; - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - final int width = w - getPaddingLeft() - getPaddingRight(); - mSquareWidth = width / 3.0f; - - final int height = h - getPaddingTop() - getPaddingBottom(); - mSquareHeight = height / 3.0f; - } - - private int resolveMeasured(int measureSpec, int desired) { - int result = 0; - int specSize = MeasureSpec.getSize(measureSpec); - switch (MeasureSpec.getMode(measureSpec)) { - case MeasureSpec.UNSPECIFIED: - result = desired; - break; - case MeasureSpec.AT_MOST: - result = Math.max(specSize, desired); - break; - case MeasureSpec.EXACTLY: - default: - result = specSize; - } - return result; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int minimumWidth = getSuggestedMinimumWidth(); - final int minimumHeight = getSuggestedMinimumHeight(); - int viewWidth = resolveMeasured(widthMeasureSpec, minimumWidth); - int viewHeight = resolveMeasured(heightMeasureSpec, minimumHeight); - - switch (mAspect) { - case ASPECT_SQUARE: - viewWidth = viewHeight = Math.min(viewWidth, viewHeight); - break; - case ASPECT_LOCK_WIDTH: - viewHeight = Math.min(viewWidth, viewHeight); - break; - case ASPECT_LOCK_HEIGHT: - viewWidth = Math.min(viewWidth, viewHeight); - break; - } - // Log.v(TAG, "LockPatternView dimensions: " + viewWidth + "x" + - // viewHeight); - setMeasuredDimension(viewWidth, viewHeight); - } - - /** - * Determines whether the point x, y will add a new point to the current - * pattern (in addition to finding the cell, also makes heuristic choices - * such as filling in gaps based on current pattern). - * - * @param x - * The x coordinate. - * @param y - * The y coordinate. - */ - private Cell detectAndAddHit(float x, float y) { - final Cell cell = checkForNewHit(x, y); - if (cell != null) { - - // check for gaps in existing pattern - Cell fillInGapCell = null; - final ArrayList pattern = mPattern; - if (!pattern.isEmpty()) { - final Cell lastCell = pattern.get(pattern.size() - 1); - int dRow = cell.row - lastCell.row; - int dColumn = cell.column - lastCell.column; - - 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); - } - - fillInGapCell = Cell.of(fillInRow, fillInColumn); - } - - if (fillInGapCell != null - && !mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) { - addCellToPattern(fillInGapCell); - } - addCellToPattern(cell); - if (mEnableHapticFeedback) { - performHapticFeedback( - HapticFeedbackConstants.VIRTUAL_KEY, - HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING - | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - return cell; - } - return null; - } - - private void addCellToPattern(Cell newCell) { - mPatternDrawLookup[newCell.getRow()][newCell.getColumn()] = true; - mPattern.add(newCell); - if (!mInStealthMode) { - startCellActivatedAnimation(newCell); - } - notifyCellAdded(); - } - - private void startCellActivatedAnimation(Cell cell) { - final CellState cellState = mCellStates[cell.row][cell.column]; - startSizeAnimation(mDotSize, mDotSizeActivated, 96, - mLinearOutSlowInInterpolator, cellState, new Runnable() { - - @Override - public void run() { - startSizeAnimation(mDotSizeActivated, mDotSize, 192, - mFastOutSlowInInterpolator, cellState, null); - } - }); - startLineEndAnimation(cellState, mInProgressX, mInProgressY, - getCenterXForColumn(cell.column), getCenterYForRow(cell.row)); - } - - private void startLineEndAnimation(final CellState state, - final float startX, final float startY, final float targetX, - final float targetY) { - ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); - valueAnimator - .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float t = (Float) animation.getAnimatedValue(); - state.lineEndX = (1 - t) * startX + t * targetX; - state.lineEndY = (1 - t) * startY + t * targetY; - invalidate(); - } - }); - valueAnimator.addListener(new AnimatorListenerAdapter() { - - @Override - public void onAnimationEnd(Animator animation) { - state.lineAnimator = null; - } - }); - valueAnimator.setInterpolator(mFastOutSlowInInterpolator); - valueAnimator.setDuration(100); - valueAnimator.start(); - state.lineAnimator = valueAnimator; - } - - private void startSizeAnimation(float start, float end, long duration, - Interpolator interpolator, final CellState state, - final Runnable endRunnable) { - ValueAnimator valueAnimator = ValueAnimator.ofFloat(start, end); - valueAnimator - .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - state.size = (Float) animation.getAnimatedValue(); - invalidate(); - } - }); - if (endRunnable != null) { - valueAnimator.addListener(new AnimatorListenerAdapter() { - - @Override - public void onAnimationEnd(Animator animation) { - endRunnable.run(); - } - }); - } - valueAnimator.setInterpolator(interpolator); - valueAnimator.setDuration(duration); - valueAnimator.start(); - } - - // helper method to find which cell a point maps to - private Cell checkForNewHit(float x, float y) { - - final int rowHit = getRowHit(y); - if (rowHit < 0) { - return null; - } - final int columnHit = getColumnHit(x); - if (columnHit < 0) { - return null; - } - - if (mPatternDrawLookup[rowHit][columnHit]) { - return null; - } - return Cell.of(rowHit, columnHit); - } - - /** - * Helper method to find the row that y falls into. - * - * @param y - * The y coordinate - * @return The row that y falls in, or -1 if it falls in no row. - */ - private int getRowHit(float y) { - - final float squareHeight = mSquareHeight; - float hitSize = squareHeight * mHitFactor; - - float offset = getPaddingTop() + (squareHeight - hitSize) / 2f; - for (int i = 0; i < 3; i++) { - - final float hitTop = offset + squareHeight * i; - if (y >= hitTop && y <= hitTop + hitSize) { - return i; - } - } - return -1; - } - - /** - * Helper method to find the column x fallis into. - * - * @param x - * The x coordinate. - * @return The column that x falls in, or -1 if it falls in no column. - */ - private int getColumnHit(float x) { - final float squareWidth = mSquareWidth; - float hitSize = squareWidth * mHitFactor; - - float offset = getPaddingLeft() + (squareWidth - hitSize) / 2f; - for (int i = 0; i < 3; i++) { - - final float hitLeft = offset + squareWidth * i; - if (x >= hitLeft && x <= hitLeft + hitSize) { - return i; - } - } - return -1; - } - - @Override - public boolean onHoverEvent(MotionEvent event) { - if (((AccessibilityManager) getContext().getSystemService( - Context.ACCESSIBILITY_SERVICE)).isTouchExplorationEnabled()) { - final int action = event.getAction(); - switch (action) { - case MotionEvent.ACTION_HOVER_ENTER: - event.setAction(MotionEvent.ACTION_DOWN); - break; - case MotionEvent.ACTION_HOVER_MOVE: - event.setAction(MotionEvent.ACTION_MOVE); - break; - case MotionEvent.ACTION_HOVER_EXIT: - event.setAction(MotionEvent.ACTION_UP); - break; - } - onTouchEvent(event); - event.setAction(action); - } - return super.onHoverEvent(event); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - if (!mInputEnabled || !isEnabled()) { - return false; - } - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - handleActionDown(event); - return true; - case MotionEvent.ACTION_UP: - handleActionUp(event); - return true; - case MotionEvent.ACTION_MOVE: - handleActionMove(event); - return true; - case MotionEvent.ACTION_CANCEL: - if (mPatternInProgress) { - mPatternInProgress = false; - resetPattern(); - notifyPatternCleared(); - } - if (PROFILE_DRAWING) { - if (mDrawingProfilingStarted) { - Debug.stopMethodTracing(); - mDrawingProfilingStarted = false; - } - } - return true; - } - return false; - } - - private void handleActionMove(MotionEvent event) { - // Handle all recent motion events so we don't skip any cells even when - // the device - // is busy... - final float radius = mPathWidth; - final int historySize = event.getHistorySize(); - mTmpInvalidateRect.setEmpty(); - boolean invalidateNow = false; - for (int i = 0; i < historySize + 1; i++) { - final float x = i < historySize ? event.getHistoricalX(i) : event - .getX(); - final float y = i < historySize ? event.getHistoricalY(i) : event - .getY(); - Cell hitCell = detectAndAddHit(x, y); - final int patternSize = mPattern.size(); - if (hitCell != null && patternSize == 1) { - mPatternInProgress = true; - notifyPatternStarted(); - } - // note current x and y for rubber banding of in progress patterns - final float dx = Math.abs(x - mInProgressX); - final float dy = Math.abs(y - mInProgressY); - if (dx > DRAG_THRESHHOLD || dy > DRAG_THRESHHOLD) { - invalidateNow = true; - } - - if (mPatternInProgress && patternSize > 0) { - final ArrayList pattern = mPattern; - final Cell lastCell = pattern.get(patternSize - 1); - float lastCellCenterX = getCenterXForColumn(lastCell.column); - float lastCellCenterY = getCenterYForRow(lastCell.row); - - // Adjust for drawn segment from last cell to (x,y). Radius - // accounts for line width. - float left = Math.min(lastCellCenterX, x) - radius; - float right = Math.max(lastCellCenterX, x) + radius; - float top = Math.min(lastCellCenterY, y) - radius; - float bottom = Math.max(lastCellCenterY, y) + radius; - - // Invalidate between the pattern's new cell and the pattern's - // previous cell - if (hitCell != null) { - final float width = mSquareWidth * 0.5f; - final float height = mSquareHeight * 0.5f; - final float hitCellCenterX = getCenterXForColumn(hitCell.column); - final float hitCellCenterY = getCenterYForRow(hitCell.row); - - left = Math.min(hitCellCenterX - width, left); - right = Math.max(hitCellCenterX + width, right); - top = Math.min(hitCellCenterY - height, top); - bottom = Math.max(hitCellCenterY + height, bottom); - } - - // Invalidate between the pattern's last cell and the previous - // location - mTmpInvalidateRect.union(Math.round(left), Math.round(top), - Math.round(right), Math.round(bottom)); - } - } - mInProgressX = event.getX(); - mInProgressY = event.getY(); - - // To save updates, we only invalidate if the user moved beyond a - // certain amount. - if (invalidateNow) { - mInvalidate.union(mTmpInvalidateRect); - invalidate(mInvalidate); - mInvalidate.set(mTmpInvalidateRect); - } - } - - private void sendAccessEvent(int resId) { - announceForAccessibility(getContext().getString(resId)); - } - - private void handleActionUp(MotionEvent event) { - // report pattern detected - if (!mPattern.isEmpty()) { - mPatternInProgress = false; - cancelLineAnimations(); - notifyPatternDetected(); - invalidate(); - } - if (PROFILE_DRAWING) { - if (mDrawingProfilingStarted) { - Debug.stopMethodTracing(); - mDrawingProfilingStarted = false; - } - } - } - - private void cancelLineAnimations() { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - CellState state = mCellStates[i][j]; - if (state.lineAnimator != null) { - state.lineAnimator.cancel(); - state.lineEndX = Float.MIN_VALUE; - state.lineEndY = Float.MIN_VALUE; - } - } - } - } - - private void handleActionDown(MotionEvent event) { - resetPattern(); - final float x = event.getX(); - final float y = event.getY(); - final Cell hitCell = detectAndAddHit(x, y); - if (hitCell != null) { - mPatternInProgress = true; - mPatternDisplayMode = DisplayMode.Correct; - notifyPatternStarted(); - } else if (mPatternInProgress) { - mPatternInProgress = false; - notifyPatternCleared(); - } - if (hitCell != null) { - final float startX = getCenterXForColumn(hitCell.column); - final float startY = getCenterYForRow(hitCell.row); - - final float widthOffset = mSquareWidth / 2f; - final float heightOffset = mSquareHeight / 2f; - - invalidate((int) (startX - widthOffset), - (int) (startY - heightOffset), - (int) (startX + widthOffset), (int) (startY + heightOffset)); - } - mInProgressX = x; - mInProgressY = y; - if (PROFILE_DRAWING) { - if (!mDrawingProfilingStarted) { - Debug.startMethodTracing("LockPatternDrawing"); - mDrawingProfilingStarted = true; - } - } - } - - private float getCenterXForColumn(int column) { - return getPaddingLeft() + column * mSquareWidth + mSquareWidth / 2f; - } - - private float getCenterYForRow(int row) { - return getPaddingTop() + row * mSquareHeight + mSquareHeight / 2f; - } - - @Override - protected void onDraw(Canvas canvas) { - final ArrayList pattern = mPattern; - final int count = pattern.size(); - final boolean[][] drawLookup = mPatternDrawLookup; - - if (mPatternDisplayMode == DisplayMode.Animate) { - - // figure out which circles to draw - - // + 1 so we pause on complete pattern - final int oneCycle = (count + 1) * MILLIS_PER_CIRCLE_ANIMATING; - final int spotInCycle = (int) (SystemClock.elapsedRealtime() - mAnimatingPeriodStart) - % oneCycle; - final int numCircles = spotInCycle / MILLIS_PER_CIRCLE_ANIMATING; - - clearPatternDrawLookup(); - for (int i = 0; i < numCircles; i++) { - final Cell cell = pattern.get(i); - drawLookup[cell.getRow()][cell.getColumn()] = true; - } - - // figure out in progress portion of ghosting line - - final boolean needToUpdateInProgressPoint = numCircles > 0 - && numCircles < count; - - if (needToUpdateInProgressPoint) { - final float percentageOfNextCircle = ((float) (spotInCycle % MILLIS_PER_CIRCLE_ANIMATING)) - / MILLIS_PER_CIRCLE_ANIMATING; - - final Cell currentCell = pattern.get(numCircles - 1); - final float centerX = getCenterXForColumn(currentCell.column); - final float centerY = getCenterYForRow(currentCell.row); - - final Cell nextCell = pattern.get(numCircles); - final float dx = percentageOfNextCircle - * (getCenterXForColumn(nextCell.column) - centerX); - final float dy = percentageOfNextCircle - * (getCenterYForRow(nextCell.row) - centerY); - mInProgressX = centerX + dx; - mInProgressY = centerY + dy; - } - // TODO: Infinite loop here... - invalidate(); - } - - final Path currentPath = mCurrentPath; - currentPath.rewind(); - - // draw the circles - for (int i = 0; i < 3; i++) { - float centerY = getCenterYForRow(i); - for (int j = 0; j < 3; j++) { - CellState cellState = mCellStates[i][j]; - float centerX = getCenterXForColumn(j); - float size = cellState.size * cellState.scale; - float translationY = cellState.translateY; - drawCircle(canvas, (int) centerX, (int) centerY + translationY, - size, drawLookup[i][j], cellState.alpha); - } - } - - // 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; - - if (drawPath) { - mPathPaint.setColor(getCurrentColor(true /* partOfPattern */)); - - boolean anyCircles = false; - float lastX = 0f; - float lastY = 0f; - for (int i = 0; i < count; i++) { - Cell cell = pattern.get(i); - - // only draw the part of the pattern stored in - // the lookup table (this is only different in the case - // of animation). - if (!drawLookup[cell.row][cell.column]) { - break; - } - anyCircles = true; - - float centerX = getCenterXForColumn(cell.column); - float centerY = getCenterYForRow(cell.row); - if (i != 0) { - CellState state = mCellStates[cell.row][cell.column]; - currentPath.rewind(); - currentPath.moveTo(lastX, lastY); - if (state.lineEndX != Float.MIN_VALUE - && state.lineEndY != Float.MIN_VALUE) { - currentPath.lineTo(state.lineEndX, state.lineEndY); - } else { - currentPath.lineTo(centerX, centerY); - } - canvas.drawPath(currentPath, mPathPaint); - } - lastX = centerX; - lastY = centerY; - } - - // draw last in progress section - if ((mPatternInProgress || mPatternDisplayMode == DisplayMode.Animate) - && anyCircles) { - currentPath.rewind(); - currentPath.moveTo(lastX, lastY); - currentPath.lineTo(mInProgressX, mInProgressY); - - mPathPaint.setAlpha((int) (calculateLastSegmentAlpha( - mInProgressX, mInProgressY, lastX, lastY) * 255f)); - canvas.drawPath(currentPath, mPathPaint); - } - } - } - - private float calculateLastSegmentAlpha(float x, float y, float lastX, - float lastY) { - float diffX = x - lastX; - float diffY = y - lastY; - float dist = (float) Math.sqrt(diffX * diffX + diffY * diffY); - float frac = dist / mSquareWidth; - return Math.min(1f, Math.max(0f, (frac - 0.3f) * 4f)); - } - - private int getCurrentColor(boolean partOfPattern) { - if (!partOfPattern || mInStealthMode || mPatternInProgress) { - // unselected circle - return mRegularColor; - } else if (mPatternDisplayMode == DisplayMode.Wrong) { - // the pattern is wrong - return mErrorColor; - } else if (mPatternDisplayMode == DisplayMode.Correct - || mPatternDisplayMode == DisplayMode.Animate) { - return mSuccessColor; - } else { - throw new IllegalStateException("unknown display mode " - + mPatternDisplayMode); - } - } - - /** - * @param partOfPattern - * Whether this circle is part of the pattern. - */ - private void drawCircle(Canvas canvas, float centerX, float centerY, - float size, boolean partOfPattern, float alpha) { - mPaint.setColor(getCurrentColor(partOfPattern)); - mPaint.setAlpha((int) (alpha * 255)); - canvas.drawCircle(centerX, centerY, size / 2, mPaint); - } - - @Override - protected Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - return new SavedState(superState, - LockPatternUtils.patternToString(mPattern), - mPatternDisplayMode.ordinal(), mInputEnabled, mInStealthMode, - mEnableHapticFeedback); - } - - @Override - protected void onRestoreInstanceState(Parcelable state) { - final SavedState ss = (SavedState) state; - super.onRestoreInstanceState(ss.getSuperState()); - setPattern(DisplayMode.Correct, - LockPatternUtils.stringToPattern(ss.getSerializedPattern())); - mPatternDisplayMode = DisplayMode.values()[ss.getDisplayMode()]; - mInputEnabled = ss.isInputEnabled(); - mInStealthMode = ss.isInStealthMode(); - mEnableHapticFeedback = ss.isTactileFeedbackEnabled(); - } - - /** - * The parecelable for saving and restoring a lock pattern view. - */ - private static class SavedState extends BaseSavedState { - - private final String mSerializedPattern; - private final int mDisplayMode; - private final boolean mInputEnabled; - private final boolean mInStealthMode; - private final boolean mTactileFeedbackEnabled; - - /** - * Constructor called from {@link LockPatternViewEx#onSaveInstanceState()} - */ - private SavedState(Parcelable superState, String serializedPattern, - int displayMode, boolean inputEnabled, boolean inStealthMode, - boolean tactileFeedbackEnabled) { - super(superState); - mSerializedPattern = serializedPattern; - mDisplayMode = displayMode; - mInputEnabled = inputEnabled; - mInStealthMode = inStealthMode; - mTactileFeedbackEnabled = tactileFeedbackEnabled; - } - - /** - * Constructor called from {@link #CREATOR} - */ - private SavedState(Parcel in) { - super(in); - mSerializedPattern = in.readString(); - mDisplayMode = in.readInt(); - mInputEnabled = (Boolean) in.readValue(null); - mInStealthMode = (Boolean) in.readValue(null); - mTactileFeedbackEnabled = (Boolean) in.readValue(null); - } - - public String getSerializedPattern() { - return mSerializedPattern; - } - - public int getDisplayMode() { - return mDisplayMode; - } - - public boolean isInputEnabled() { - return mInputEnabled; - } - - public boolean isInStealthMode() { - return mInStealthMode; - } - - public boolean isTactileFeedbackEnabled() { - return mTactileFeedbackEnabled; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeString(mSerializedPattern); - dest.writeInt(mDisplayMode); - dest.writeValue(mInputEnabled); - dest.writeValue(mInStealthMode); - dest.writeValue(mTactileFeedbackEnabled); - } - - public static final Parcelable.Creator CREATOR = new Creator() { - - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } -} diff --git a/LockPatternViewTest/src/com/google/android/collect/Lists.java b/LockPatternViewTest/src/com/google/android/collect/Lists.java deleted file mode 100644 index b7ffe34..0000000 --- a/LockPatternViewTest/src/com/google/android/collect/Lists.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.collect; - -import java.util.ArrayList; -import java.util.Collections; - -/** - * Provides static methods for creating {@code List} instances easily, and other - * utility methods for working with lists. - */ -public class Lists { - - /** - * Creates an empty {@code ArrayList} instance. - * - *

- * Note: if you only need an immutable empty List, use - * {@link Collections#emptyList} instead. - * - * @return a newly-created, initially-empty {@code ArrayList} - */ - public static ArrayList newArrayList() { - return new ArrayList(); - } - - /** - * Creates a resizable {@code ArrayList} instance containing the given - * elements. - * - *

- * Note: due to a bug in javac 1.5.0_06, we cannot support the - * following: - * - *

- * {@code List list = Lists.newArrayList(sub1, sub2);} - * - *

- * where {@code sub1} and {@code sub2} are references to subtypes of - * {@code Base}, not of {@code Base} itself. To get around this, you must - * use: - * - *

- * {@code List list = Lists.newArrayList(sub1, sub2);} - * - * @param elements - * the elements that the list should contain, in order - * @return a newly-created {@code ArrayList} containing those elements - */ - public static ArrayList newArrayList(E... elements) { - int capacity = (elements.length * 110) / 100 + 5; - ArrayList list = new ArrayList(capacity); - Collections.addAll(list, elements); - return list; - } - -} diff --git a/MigrationNotes.md b/MigrationNotes.md new file mode 100644 index 0000000..ff867c3 --- /dev/null +++ b/MigrationNotes.md @@ -0,0 +1,147 @@ +# …to v3.2 # + +Please update your code (Java, XML…) due to these changes: + + * We drop support for APIs < 7. + * Rename `EXTRA_INTENT_ACTIVITY_FORGOT_PATTERN` to `EXTRA_PENDING_INTENT_FORGOT_PATTERN`. Note that its value type is also changed from `Intent` to `PendingIntent`. + +# …to v3.1 # + +Please update your code (Java, XML…) due to these changes: + + * Change package name to `com.haibison.android.lockpattern`. + * Change prefixes for resources from: + * `alp_` to `alp_42447968_` + * `Alp.` to `Alp.42447968.` + +You might want to go through the [Quick Use](QuickUse.md) again :-) + +# …to v3.0.7 # + +There's nothing changed. + +# …to v3.0.6 # + +There's nothing changed. However we add new support for configuring settings directly via your app's [AndroidManifest.xml](AndroidManifest.md). + +# …to v3.0.5 # + +Class `Settings.Display`: rename methods `setMaxRetry()` to `setMaxRetries()`, `getMaxRetry()` to `getMaxRetries()`. + +# …to v3.0.4 # + +Refactor package `prefs` to a single class `util.Settings`: + + * `prefs.Prefs` -> `util.Settings` + * `prefs.DisplayPrefs` -> `util.Settings.Display` + * `prefs.SecurityPrefs` -> `util.Settings.Security` + +# …to v3.0.3 # + +There's nothing changed :-) + +# …to v3.0 # + +Add one more method to interface `IEncrypter`: +``` + /** + * Decrypts an encrypted pattern. + * + * @param context + * the context. + * @param encryptedPattern + * the encrypted pattern. + * @return the original pattern. + */ + List decrypt(Context context, char[] encryptedPattern); +``` + +Please update your code for above change. Basically, it decrypts the encrypted pattern from `encrypt(Context, List)`. + +# …to v2.9 # + +There's nothing changed :-) + +# …to v2.8 # + + * Change method `IEncrypter.encrypt()` from: +``` +char[] encrypt(Context context, char[] pattern); +``` +> to: +``` +char[] encrypt(Context context, List pattern); +``` +> To keep your last encrypter safe, use helper class `LockPatternUtils`: +``` +import group.pals.android.lib.ui.lockpattern.widget.LockPatternUtils; + +... + + @Override + public char[] encrypt(Context context, List pattern) { + /* + * This is the value that last version passed to your encrypter. + */ + char[] patternAsChars = LockPatternUtils.patternToSha1(pattern) + .toCharArray(); + + return ... + }// encrypt() +``` + * Rename `EXTRA_OK_PENDING_INTENT`, `EXTRA_CANCELLED_PENDING_INTENT` to `EXTRA_PENDING_INTENT_OK` and `EXTRA_PENDING_INTENT_CANCELLED`. + * Add new extra `EXTRA_INTENT_ACTIVITY_FORGOT_PATTERN` to help the user recover the pattern if he/ she forgot it. Check [QuickUse](QuickUse#%22Forgot_pattern%3F%22.md) for details. This leads to some changes below: + * `ACTION_COMPARE_PATTERN`: there are _**4 possible result codes**_: `RESULT_OK`, `RESULT_CANCELED`, `LockPatternActivity.RESULT_FAILED` and `LockPatternActivity.RESULT_FORGOT_PATTERN`. + * `ACTION_VERIFY_CAPTCHA`: there are _**3 possible result codes**_ like above _excluding_ `RESULT_FORGOT_PATTERN`. + +# …to v2.7 # + +There's nothing changed. We've added new action named `ACTION_VERIFY_CAPTCHA`. You simply use it with new `Intent` and the library will do the rest. To change default wired dots (which is `4`), use helper class `DisplayPrefs`: +``` +import group.pals.android.lib.ui.lockpattern.prefs.DisplayPrefs; + +... + +DisplayPrefs.setCaptchaWiredDots(your-context, 9); +``` + +# …to v2.6 # + + * Change coding style: use `UPPER_CASE` for all `static final` fields and enums. + * Move all dynamic settings to `SharedPreferences`. For example all these keys were deleted: ~~`_EncrypterClass`~~, ~~`_StealthMode`~~… Check QuickUse again for details. + * Change interface `IEncrypter`. Please see [Encryption](https://code.google.com/p/android-lockpattern/wiki/Encryption) for further details. + * Please note that the pattern is now hold in key `EXTRA_PATTERN` and it is a `char[]` array (_not_ `String`). + +# …to v2.5 # + +## Important notes ## + + * We've added four built-in themes. In order to let the library work properly, you have to use one of them. Because the themes contain resources that the library needs. They are: `Alp_Theme_Dark`, `Alp_Theme_Light`, `Alp_Theme_Dialog_Dark` and `Alp_Theme_Dialog_Light`. + * In mode comparing pattern, **_if_** the user fails to pass the process, the library will return result code `LockPatternActivity._ResultFailed` (**_not_** `RESULT_CANCELED`). **_Please note_** that there are _**[3 possible result codes](QuickUse#Let_the_user_identify_himself_with_lock_pattern.md)**_. You might want to take a look at the [demo project](https://code.google.com/p/android-lockpattern/source/browse/demo) for further information. + +# …to v2.4 # + +Key ~~`_Mode`~~ and enum ~~`LPMode`~~ were removed. Now you configure handlers via action names: + * Use `_ActionCreatePattern` to create new pattern + * Use `_ActionComparePattern` to compare pattern +(Check [Usage](QuickUse#Usage.md)). + +# …to v2.3 # + +To reduce binary size, we removed all keys/ methods which were deprecated and were notified and kept in at least one older version (for migrating purpose): + * Key `LockPatternActivity.`~~`_PaternSha1`~~ + * Method `IEncrypter.`~~`encrypt(String)`~~ + +# …to v2.1 # + + * [Encryption](https://code.google.com/p/android-lockpattern/wiki/Encryption): Method `IEncrypter.`~~`encrypt(String)`~~ is _deprecated_ and _no longer used_. Please use this new method instead: +``` +String IEncrypter.encrypt(Context, String); +``` + +# …to v2 # + +From version 2, key `LockPatternActivity`.~~`_PaternSha1`~~ is _deprecated_ and _no longer used_. Please use this new key instead: +``` +LockPatternActivity._Pattern +``` \ No newline at end of file diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 08f2bcb..0000000 --- a/NOTICE +++ /dev/null @@ -1,17 +0,0 @@ -android-lockpattern -Copyright 2012 Hai Bison - -This product includes software developed at -https://code.google.com/p/android-lockpattern/ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/ProjectHome.md b/ProjectHome.md new file mode 100644 index 0000000..4109611 --- /dev/null +++ b/ProjectHome.md @@ -0,0 +1,28 @@ +<wiki:gadget url="https://android-lockpattern.googlecode.com/hg/resources/gadgets/main\_header.xml" height="70" width="50%" border="1" /> + +Android has one useful tool in security settings, it is Lock Pattern. Users can define their own lock pattern ‒ which is a combination of 4+ dots. + +We have extracted this piece of code from Android source code, [platform/frameworks/base](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/com/android/internal/widget/). Then modified it a little, to make it easy to use in an application. + + * **Latest stable: v3.2 (#45)** (January 19th, 2015). _From version `3.1.1 beta (#44)`, this project follows [Semantic Versioning](https://en.wikipedia.org/wiki/Semantic_versioning#Semantic_versioning)._ + * The demo can be downloaded on [Google Play](https://play.google.com/store/apps/details?id=group.pals.android.lib.ui.lockpattern.demo). It needs some more permissions to help us monetize it. With this service we are able to create more great apps and libraries for you guys. _Thank you for your understanding._ + * Latest source is available in the demo app. You can export it directly to SD card or to Google Drive, Dropbox... + +### Features ### + + * Requires: Android 2.1+ (API 7+). + * Supports: Eclipse IDE, Android Studio (beta). + * _No dependencies._ + * Designed for both _phones and tablets_. + * Stealth mode (invisible pattern). + * 5 built-in themes: + * Dark/Light + * Light with dark action bar (available from API 7+, but only works from API 14+) + * Dark/Light dialogs + * Ability to generate and let the user verify CAPTCHA pattern. + +### Notes ### + + * If you're upgrading the library, refer to [Migration Notes](MigrationNotes.md) first. + * For more information about usage, see Wiki pages. Or you might want to see [Quick Use](QuickUse.md). + * You're welcome to file new issues on [Issues](https://code.google.com/p/android-lockpattern/issues/list) section. \ No newline at end of file diff --git a/QuickUse.md b/QuickUse.md new file mode 100644 index 0000000..4bd345c --- /dev/null +++ b/QuickUse.md @@ -0,0 +1,273 @@ +# Integrating (Eclipse IDE) # + +**First,** you have to open this project in Eclipse. Assuming you place this library at `/data/projects/android-lockpattern`. + +**If** you use Ant: to re-generate your `local.properties`, open terminal, use `android` tool (in SDK): +``` +# [Android SDK]/tools/android update project -p /data/projects/android-lockpattern/code --target android-19 +``` + +**Then, import** this library into your project: + + * By Eclipse: Right click on your project, select _Properties_, select _Android_ tab, then add this library to _Library_ box. + * Manual: Open your _project.properties_ file, add this line: +``` +android.library.reference.1=/data/projects/android-lockpattern/code +``` +> _Note:_ `1` is the sequence number of the library. Reset it to fit your project. Perhaps it starts from `1`, I don't know :-D + +**Import** [LockPatternActivity](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html) into your application: + * By Eclipse: Open `AndroidManifest.xml` -> tab _Application_ -> box _Application Nodes_, click _Add_, select `Activity`. Go to box _Attributes for Activity_, click _Browse_ (next to field _Name_), then add `LockPatternActivity`. + * Manual: Open `AndroidManifest.xml`, inside tag `application`, add this: +``` + +``` + +**Note** that there are 5 built-in themes: + + * `Alp.42447968.Theme.Dark` + * `Alp.42447968.Theme.Light` + * `Alp.42447968.Theme.Light.DarkActionBar` (available from API 7+, but only works from API 14+) + * `Alp.42447968.Theme.Dialog.Dark` + * `Alp.42447968.Theme.Dialog.Light` + +You _have to_ use one of them in order to let the library work properly. Because the themes contain resources that the library needs. + +**Android** team recommends that you should set your target SDK to the newest one. You can still use the library for Android 1.6+. For example: +``` + + + + ... +``` + + * To avoid the activity from being killed after screen orientation changed, add this: +``` + +``` + +# Usage # + +## Create new pattern ## + +``` +... +// This is your preferred flag +private static final int REQ_CREATE_PATTERN = 1; + +... + +Intent intent = new Intent(LockPatternActivity.ACTION_CREATE_PATTERN, null, + your-context, LockPatternActivity.class); +startActivityForResult(intent, REQ_CREATE_PATTERN); +``` + +For more secure, you might want to use [Encryption](Encryption.md). + +## And to get the result ## + +``` +@Override +protected void onActivityResult(int requestCode, int resultCode, + Intent data) { + switch (requestCode) { + case REQ_CREATE_PATTERN: { + if (resultCode == RESULT_OK) { + char[] pattern = data.getCharArrayExtra( + LockPatternActivity.EXTRA_PATTERN); + ... + } + break; + }// REQ_CREATE_PATTERN + } +} +``` + +## Let the user identify himself with lock pattern ## + +``` +... +// This is your preferred flag +private static final int REQ_ENTER_PATTERN = 2; + +... + +char[] savedPattern = ... + +Intent intent = new Intent(LockPatternActivity.ACTION_COMPARE_PATTERN, null, + your-context, LockPatternActivity.class); +intent.putExtra(LockPatternActivity.EXTRA_PATTERN, savedPattern); +startActivityForResult(intent, REQ_ENTER_PATTERN); +``` +``` +... +@Override +protected void onActivityResult(int requestCode, int resultCode, + Intent data) { + switch (requestCode) { + case REQ_ENTER_PATTERN: { + /* + * NOTE that there are 4 possible result codes!!! + */ + switch (resultCode) { + case RESULT_OK: + // The user passed + break; + case RESULT_CANCELED: + // The user cancelled the task + break; + case LockPatternActivity.RESULT_FAILED: + // The user failed to enter the pattern + break; + case LockPatternActivity.RESULT_FORGOT_PATTERN: + // The user forgot the pattern and invoked your recovery Activity. + break; + } + + /* + * In any case, there's always a key EXTRA_RETRY_COUNT, which holds + * the number of tries that the user did. + */ + int retryCount = data.getIntExtra( + LockPatternActivity.EXTRA_RETRY_COUNT, 0); + + break; + }// REQ_ENTER_PATTERN + } +} +``` + +## Notes ## + + * You can tell the library to store newly created pattern into [SharedPreferences](http://developer.android.com/reference/android/content/SharedPreferences.html). So you might not need to specify pattern for action [ACTION\_COMPARE\_PATTERN](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#ACTION_COMPARE_PATTERN). By default, this flag is off. To turn it on: +``` +import com.haibison.android.lockpattern.util.Settings; + +... + +Settings.Security.setAutoSavePattern(your-context, true); +``` + * [ACTION\_COMPARE\_PATTERN](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#ACTION_COMPARE_PATTERN): there are _**4 possible result codes**_ like the sample above. + * [ACTION\_VERIFY\_CAPTCHA](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#ACTION_VERIFY_CAPTCHA): there are _**3 possible result codes**_ like the sample above _excluding_ [RESULT\_FORGOT\_PATTERN](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#RESULT_FORGOT_PATTERN). + +# Tips # + +## Themes ## + + * To turn `LockPatternActivity` into a dialog, open _**your**_ `AndroidManifest.xml` and add this: +``` + +``` + + * To change theme in runtime, you must set theme in `AndroidManifest.xml` as above. If you don't do that and set theme to dialog via code, the background of `LockPatternActivity` will be _not_ transparent. A correct example: +``` +... +intent.putExtra(LockPatternActivity.EXTRA_THEME, R.style.Alp_42447968_Theme_Dialog_Dark); +``` + +## Stealth Mode ## + +In stealth mode, there will be no visible feedback as the user enters the pattern. To turn it on, use helper class [Settings.Display](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/util/Settings.Display.html). By default this mode if off. +``` +import com.haibison.android.lockpattern.util.Settings; + +... + +Settings.Display.setStealthMode(your-context, true); +``` + +## CAPTCHA ## + +To let the library generate a random [CAPTCHA](http://en.wikipedia.org/wiki/CAPTCHA) pattern and have the user verify it, you can use action [ACTION\_VERIFY\_CAPTCHA](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#ACTION_VERIFY_CAPTCHA). Default wired dots is `4`, you can change it with helper class `Settings.Display`. +``` +... +Settings.Display.setCaptchaWiredDots(your-context, 9); +Intent intent = new Intent(LockPatternActivity.ACTION_VERIFY_CAPTCHA, null, + your-context, LockPatternActivity.class); +startActivityForResult(intent, your-request-code); +``` + +## Forgot pattern? ## + +If you use [ACTION\_COMPARE\_PATTERN](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#ACTION_COMPARE_PATTERN), the user might forget his/ her pattern. So, you can use a `PendingIntent` of your `Activity` to help the user recover the pattern when he/she needs. For example: + +``` +PendingIntent piForgotPattern = ... + +Intent intentActivity = new Intent( + LockPatternActivity.ACTION_COMPARE_PATTERN, null, + your-context, LockPatternActivity.class); +intentActivity.putExtra( + LockPatternActivity.EXTRA_PENDING_INTENT_FORGOT_PATTERN, + piForgotPattern); +... +``` + +When the user taps the button _"Forgot pattern?"_ (on `LockPatternActivity`), the library _makes a call_ to start your pending intent, then finishes itself with [RESULT\_FORGOT\_PATTERN](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/LockPatternActivity.html#RESULT_FORGOT_PATTERN). + +## Action Bar Icons ## + +Version 3+ includes an icon set for action bar, which has dark and light icons. + +| ![https://android-lockpattern.googlecode.com/hg/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_dark.png](https://android-lockpattern.googlecode.com/hg/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_dark.png) | ![https://android-lockpattern.googlecode.com/hg/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_light.png](https://android-lockpattern.googlecode.com/hg/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_light.png) | +|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| + +If you use one of built-in themes (`R.style.Alp_42447968_Theme_*`) for your activity, you can make a reference to the icon like: + +``` + +

+ + + + +``` + +Or if you use your own themes, use the icons directly instead of that reference. For example: + +``` + + + + + + + + +``` + +If you want more, the SVG source file is available [here](https://code.google.com/p/android-lockpattern/source/browse/resources/images/controls/alp_42447968_ic_action_lockpattern.svg). + +# Other Notes # + +## Default language ## + +Default language is English. It is located at `res/values/strings.xml`. Actually it is a copy of `res/values-en/strings.xml`. So you can change it to your preferred language. + +If you'd like to contribute your translation, we thank you :-) + +## `AndroidManifest.xml` ## + +All configurations with helper class [Settings](http://docs.android-lockpattern.googlecode.com/hg/com/haibison/android/lockpattern/util/Settings.html) (and all of its nested classes) must be called before you start `LockPatternActivity`. But you _can_ configure settings in an activity and call `LockPatternActivity` in another activity. + +You can also configure settings directly via your app's [AndroidManifest.xml](AndroidManifest.md). \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 8f39799..0000000 --- a/README.md +++ /dev/null @@ -1,265 +0,0 @@ -# android-lockpattern - -* Version: 3.2.1 beta (#46) - -Feel free to contact us at: - -* E-mails: - + haibison.apps[at]gmail.com - -In short, you can use this library in your closed source/commercial apps with -or without our knowledge. Hope you enjoy it :-) - - -# CREDITS - -We sincerely thank all of our friends -- who have been contributing to this -project. We hope this project will be always useful for everyone. - -* C -* [Steven Byle](http://stackoverflow.com/users/1507439/steven-byle) -* Thomas Breitbach -* Yan Cheng Cheok (Project Admin of [JStock](http://jstock.sourceforge.net/)) -* And others. - - -# HISTORY - -* Version 3.2.1 beta (#46) - + *Initialize: January 23rd, 2015* - -* Version 3.2 (#45) - + *Release:* January 19th, 2015 - + Update based code from AOSP Lollipop. - + Drop support for APIs < 7. - + Add static helper methods for creating new `Intent`'s and calling - `startActivityForResult(Intent, int)` from an `Activity`, framework - `Fragment` or support library `Fragment`. - + Rename `EXTRA_INTENT_ACTIVITY_FORGOT_PATTERN` to - `EXTRA_PENDING_INTENT_FORGOT_PATTERN`. Note that its value type is also - changed from `Intent` to `PendingIntent`. - + Fix small issues. - -* Version 3.1.1 beta (#44) - + *Initialize:* April 04, 2014 - -* Version 3.1 (#43) - + *Release:* March 10, 2014 - + Change package name to `com.haibison.android.lockpattern`. - + Change prefixes: - - From `alp_` to `alp_42447968_`. - - From `Alp.` to `Alp.42447968.`. - + Optimize code and make some other minor changes. - -* Version 3.0.8 beta - + *Initialize:* February 26, 2014 - -* Version 3.0.7 - + *Release:* February 21, 2014 - + Fix `NullPointerException` while loading settings from manifest. - -* Version 3.0.6 - + *Release:* February 19, 2014 - + Add support to directly configure settings via AndroidManifest.xml (tag - ``). - -* Version 3.0.6 beta - + *Initialize:* February 18, 2014 - -* Version 3.0.5 - + *Release:* Feburary 12, 2014 - + Add `SimpleWeakEncryption`. - + Update `LockPatternView` to branch `kitkat-release` (commit: - `c46c4a6765196bcabf3ea89771a1f9067b22baad`). - + Update Javadocs, some minor changes... - -* Version 3.0.5 beta - + *Initialize:* January 12, 2014 - -* Version 3.0.4 - + *Release:* January 12, 2014 - + Refactor package `prefs` to a single class `util.Settings`. - + Add `LoadingDialog` for the case that implementation of `IEncrypter` takes - lots of time to finish. - -* Version 3.0.4 beta - + *Initialize:* January 11, 2014 - -* Version 3.0.3 - + *Release:* December 18, 2013 - + Optimize code. - -* Version 3.0.2 - + *Release:* December 18, 2013 - + Add theme light with dark action bar (for API 14+). - -* Version 3.0.1 - + *Release:* October 10, 2013 - + Use default icon set (from AOSP). - -* Version 3.0 - + *Release:* September 15, 2013 - + Upgrade IEncrypter. - -* Version 2.9 - + *Release:* August 11, 2013 - + Fix dialog themes in API 11. - + Optimize code. - -* Version 2.9 beta - + *Initialize:* July 05, 2013 - -* Version 2.8 - + *Release:* July 02, 2013 - + Add new extra `EXTRA_INTENT_ACTIVITY_FORGOT_PATTERN` to help the user - recover the pattern if he/ she forgot it. - + Change `char[] IEncrypter.encrypt(Context, char[])` to - `char[] IEncrypter.encrypt(Context, List)`. - + Rename `EXTRA_OK_PENDING_INTENT`, `EXTRA_CANCELLED_PENDING_INTENT` to - `EXTRA_PENDING_INTENT_OK` and `EXTRA_PENDING_INTENT_CANCELLED`. - + Optimize code. - + Some minor changes... - -* Version 2.8 beta - + *Initialize:* June 20, 2013 - -* Version 2.7 - + *Release:* June 20, 2013 - + Add new action `ACTION_VERIFY_CAPTCHA`. - -* Version 2.7 beta - + *Initialize:* May 28, 2013 - -* Version 2.6 - + *Release:* May 18, 2013 - + Use `UPPER_CASE` for `static final` fields and enums; - + Move most of dynamic settings to `SharedPreferences`; - + Change `IEncrypter`; - -* Version 2.6 beta - + *Initialize:* May 15, 2013 - -* Version 2.5.1 - + *Release:* April 15, 2013 - + Fix delivering result to `ResultReceiver`. - -* Version 2.5 - + *Release:* April 15, 2013 - + Upgrade UI; - + Add options: - - for setting minimum wired dots in mode creating pattern; - - for setting maximum tries and determining the number of tries that the - user did in mode comparing patterns; - - thanks to David Myers for his feedbacks; - + Use fixed size for `LockPatternActivity` in large screens with dialog - themes; - + Add options for sending result to a `PendingIntent` and/ or - `ResultReceiver`; - + Fix minor bugs; optimize code; - -* Version 2.5 beta - + *Initialize:* March 18, 2013 - -* Version 2.4 - + *Release:* March 16, 2013 - + Merge latest code from AOSP; - + Use action names instead of extra fields for different types of handlers: - - `_ActionCreatePattern` - - `_ActionComparePattern` - + Add built-in themes: default dark and dark dialog; - + Add stealth-mode; - + New icon set; - + Optimize code and UI; special thanks to - [Steven Byle](http://stackoverflow.com/users/1507439/steven-byle): - - - -* Version 2.3 - + Update info: August 28, 2012 - + The - [serious bug](https://code.google.com/p/android-lockpattern/issues/detail?id=1) - was invalid. - -* Version 2.3 - + *Release:* August 28, 2012 - + Fixed serious bug: key `_PaternSha1` is deprecated but is used to return - the pattern; - + Removed all fields/ methods which were deprecated in old versions; - -* Version 2.2 - + *Release:* August 17, 2012 - + added: Spanish language; special thanks to C. - a kind friend who helped - us translate the library into his mother language; - -* Version 2.1 - + *Release:* July 29, 2012 - + turn off `AutoSave` by default; - + add new method `IEncrypter.encrypt(Context, String);` - + set method `IEncrypter.encrypt(String)` as deprecated; - -* Version 2.1 beta - + Initialization: July 21, 2012 - -* Version 2 - + *Release:* July 15, 2012 - + add support for encryption; - -* Version 2 beta - + Initialization: July 12, 2012 - -* Version 1.5.5 - + *Release:* June 22, 2012 - + set max width and height for `LockPatternView` to `400dp` for tablet; - -* Version 1.5.4 - + *Release:* June 09, 2012 - + Fix bug: in mode `CreatePattern`, `LockPatternActivity` recognized wrong - the confirmed pattern; - -* Version 1.5.4 beta - + Initialization: June 07, 2012 - -* Version 1.5.3 - + *Release:* June 07, 2012 - + ability to change theme in runtime; - + save and restore controls' state after screen orientation changed; - -* Version 1.5.3 beta - + Initialization: May 21, 2012 - + make `LockPatternView`'s gravity center; - -* Version 1.5.2 - + *Release:* May 21, 2012 - + in landscape mode, move button `Cancel` to bottom; - -* Version 1.5.1 - + *Release:* May 21, 2012 - + set `LockPatternView`'s gravity center; - -* Version 1.5 - + *Release:* May 21, 2012 - + due to - [this bug](https://code.google.com/p/android/issues/detail?id=30622), so - we prefix all resource names with `alp_`; - + add layout for landscape mode; - + update coding style: - - prefix global fields with `m`; - - prefix static final fields with `_`; - -* Version 1.4 - + *Release:* April 29, 2012 - + change UI; - + determine and use user's haptic feedback; - -* Version 1.2 - + *Release:* March 09, 2012 - + make sure `LockPatternUtils.patternToSha1()` returns lower case string; - -* Version 1.1 - + *Release:* March 08, 2012 - + fix security issue about using `SharedPreferences`; - -* Version 1.0 - + *Release:* March 08, 2012 - + first release; - + create pattern; - + compare to existing pattern; diff --git a/code/.classpath b/code/.classpath deleted file mode 100644 index 7bc01d9..0000000 --- a/code/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/code/.project b/code/.project deleted file mode 100644 index 0c95dde..0000000 --- a/code/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - android-lockpattern - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/code/AndroidManifest.xml b/code/AndroidManifest.xml deleted file mode 100644 index 9a83049..0000000 --- a/code/AndroidManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - diff --git a/code/build.xml b/code/build.xml deleted file mode 100644 index 5327a8d..0000000 --- a/code/build.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/code/proguard.cfg b/code/proguard.cfg deleted file mode 100644 index b1cdf17..0000000 --- a/code/proguard.cfg +++ /dev/null @@ -1,40 +0,0 @@ --optimizationpasses 5 --dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses --dontpreverify --verbose --optimizations !code/simplification/arithmetic,!field/*,!class/merging/* - --keep public class * extends android.app.Activity --keep public class * extends android.app.Application --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class * extends android.app.backup.BackupAgentHelper --keep public class * extends android.preference.Preference --keep public class com.android.vending.licensing.ILicensingService - --keepclasseswithmembernames class * { - native ; -} - --keepclasseswithmembers class * { - public (android.content.Context, android.util.AttributeSet); -} - --keepclasseswithmembers class * { - public (android.content.Context, android.util.AttributeSet, int); -} - --keepclassmembers class * extends android.app.Activity { - public void *(android.view.View); -} - --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} diff --git a/code/project.properties b/code/project.properties deleted file mode 100644 index 62bd840..0000000 --- a/code/project.properties +++ /dev/null @@ -1,13 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-21 -android.library=true -proguard.config=proguard.cfg diff --git a/code/res/drawable-hdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png b/code/res/drawable-hdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png deleted file mode 100644 index 911f3fe..0000000 Binary files a/code/res/drawable-hdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png and /dev/null differ diff --git a/code/res/drawable-hdpi/alp_42447968_aosp_dialog_full_holo_light.9.png b/code/res/drawable-hdpi/alp_42447968_aosp_dialog_full_holo_light.9.png deleted file mode 100644 index 2129567..0000000 Binary files a/code/res/drawable-hdpi/alp_42447968_aosp_dialog_full_holo_light.9.png and /dev/null differ diff --git a/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_dark.png b/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_dark.png deleted file mode 100644 index 9bddca6..0000000 Binary files a/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_dark.png and /dev/null differ diff --git a/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png b/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png deleted file mode 100644 index e160999..0000000 Binary files a/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png and /dev/null differ diff --git a/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_light.png b/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_light.png deleted file mode 100644 index 7f4f109..0000000 Binary files a/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_light.png and /dev/null differ diff --git a/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_light_disabled.png b/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_light_disabled.png deleted file mode 100644 index aec42be..0000000 Binary files a/code/res/drawable-hdpi/alp_42447968_ic_action_lockpattern_light_disabled.png and /dev/null differ diff --git a/code/res/drawable-mdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png b/code/res/drawable-mdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png deleted file mode 100644 index dc37316..0000000 Binary files a/code/res/drawable-mdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png and /dev/null differ diff --git a/code/res/drawable-mdpi/alp_42447968_aosp_dialog_full_holo_light.9.png b/code/res/drawable-mdpi/alp_42447968_aosp_dialog_full_holo_light.9.png deleted file mode 100644 index 0c5770a..0000000 Binary files a/code/res/drawable-mdpi/alp_42447968_aosp_dialog_full_holo_light.9.png and /dev/null differ diff --git a/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_dark.png b/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_dark.png deleted file mode 100644 index c25c114..0000000 Binary files a/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_dark.png and /dev/null differ diff --git a/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png b/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png deleted file mode 100644 index 756c8a0..0000000 Binary files a/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png and /dev/null differ diff --git a/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_light.png b/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_light.png deleted file mode 100644 index 87421bd..0000000 Binary files a/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_light.png and /dev/null differ diff --git a/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_light_disabled.png b/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_light_disabled.png deleted file mode 100644 index 471994a..0000000 Binary files a/code/res/drawable-mdpi/alp_42447968_ic_action_lockpattern_light_disabled.png and /dev/null differ diff --git a/code/res/drawable-xhdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png b/code/res/drawable-xhdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png deleted file mode 100644 index 75d36be..0000000 Binary files a/code/res/drawable-xhdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png and /dev/null differ diff --git a/code/res/drawable-xhdpi/alp_42447968_aosp_dialog_full_holo_light.9.png b/code/res/drawable-xhdpi/alp_42447968_aosp_dialog_full_holo_light.9.png deleted file mode 100644 index d9bd337..0000000 Binary files a/code/res/drawable-xhdpi/alp_42447968_aosp_dialog_full_holo_light.9.png and /dev/null differ diff --git a/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_dark.png b/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_dark.png deleted file mode 100644 index 7fc60b6..0000000 Binary files a/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_dark.png and /dev/null differ diff --git a/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png b/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png deleted file mode 100644 index 29b927b..0000000 Binary files a/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png and /dev/null differ diff --git a/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_light.png b/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_light.png deleted file mode 100644 index 772c7d5..0000000 Binary files a/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_light.png and /dev/null differ diff --git a/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_light_disabled.png b/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_light_disabled.png deleted file mode 100644 index 710d699..0000000 Binary files a/code/res/drawable-xhdpi/alp_42447968_ic_action_lockpattern_light_disabled.png and /dev/null differ diff --git a/code/res/drawable-xxhdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png b/code/res/drawable-xxhdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png deleted file mode 100644 index b029809..0000000 Binary files a/code/res/drawable-xxhdpi/alp_42447968_aosp_dialog_full_holo_dark.9.png and /dev/null differ diff --git a/code/res/drawable-xxhdpi/alp_42447968_aosp_dialog_full_holo_light.9.png b/code/res/drawable-xxhdpi/alp_42447968_aosp_dialog_full_holo_light.9.png deleted file mode 100644 index 63dd192..0000000 Binary files a/code/res/drawable-xxhdpi/alp_42447968_aosp_dialog_full_holo_light.9.png and /dev/null differ diff --git a/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_dark.png b/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_dark.png deleted file mode 100644 index 2fa1222..0000000 Binary files a/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_dark.png and /dev/null differ diff --git a/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png b/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png deleted file mode 100644 index 777aa72..0000000 Binary files a/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png and /dev/null differ diff --git a/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_light.png b/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_light.png deleted file mode 100644 index 27e01ea..0000000 Binary files a/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_light.png and /dev/null differ diff --git a/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_light_disabled.png b/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_light_disabled.png deleted file mode 100644 index 7602045..0000000 Binary files a/code/res/drawable-xxhdpi/alp_42447968_ic_action_lockpattern_light_disabled.png and /dev/null differ diff --git a/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_dark.png b/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_dark.png deleted file mode 100644 index 0bd4615..0000000 Binary files a/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_dark.png and /dev/null differ diff --git a/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png b/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png deleted file mode 100644 index 0688d45..0000000 Binary files a/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_dark_disabled.png and /dev/null differ diff --git a/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_light.png b/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_light.png deleted file mode 100644 index 3269aec..0000000 Binary files a/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_light.png and /dev/null differ diff --git a/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_light_disabled.png b/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_light_disabled.png deleted file mode 100644 index 6d5cacc..0000000 Binary files a/code/res/drawable-xxxhdpi/alp_42447968_ic_action_lockpattern_light_disabled.png and /dev/null differ diff --git a/code/res/drawable/alp_42447968_selector_ic_action_lockpattern_dark.xml b/code/res/drawable/alp_42447968_selector_ic_action_lockpattern_dark.xml deleted file mode 100644 index cbc14dc..0000000 --- a/code/res/drawable/alp_42447968_selector_ic_action_lockpattern_dark.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/code/res/drawable/alp_42447968_selector_ic_action_lockpattern_light.xml b/code/res/drawable/alp_42447968_selector_ic_action_lockpattern_light.xml deleted file mode 100644 index 288316f..0000000 --- a/code/res/drawable/alp_42447968_selector_ic_action_lockpattern_light.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/code/res/layout/alp_42447968_lock_pattern_activity.xml b/code/res/layout/alp_42447968_lock_pattern_activity.xml deleted file mode 100644 index 8ea63bb..0000000 --- a/code/res/layout/alp_42447968_lock_pattern_activity.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - -