Add pattern protection

This commit is contained in:
seven332 committed 2016-03-21 17:02:16 +08:00
1 parent 81428446d9
commit 7626c8e89e
18 files changed
+1718 -9

No files matched your search

@@ -680,6 +680,17 @@ public class Settings {
putBoolean(KEY_SAVE_PARSE_ERROR_BODY, value);
}
public static final String KEY_SECURITY = "security";
public static final String DEFAULT_SECURITY = "";
public static String getSecurity() {
return getString(KEY_SECURITY, DEFAULT_SECURITY);
}
public static void putSecurity(String value) {
putString(KEY_SECURITY, value);
}
/********************
****** Guide
********************/
@@ -58,6 +58,7 @@ import com.hippo.ehviewer.ui.scene.GalleryPreviewsScene;
import com.hippo.ehviewer.ui.scene.HistoryScene;
import com.hippo.ehviewer.ui.scene.ProgressScene;
import com.hippo.ehviewer.ui.scene.QuickSearchScene;
import com.hippo.ehviewer.ui.scene.SecurityScene;
import com.hippo.ehviewer.ui.scene.SelectSiteScene;
import com.hippo.ehviewer.ui.scene.SignInScene;
import com.hippo.ehviewer.ui.scene.WarningScene;
@@ -76,15 +77,14 @@ public final class MainActivity extends StageActivity
private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0;
private static final int REQUEST_CODE_UPDATE_PROFILE = 0;
private static final String KEY_NAV_CHECKED_ITEM = "nav_checked_item";
public static final int CHECK_STEP_WARNING = 0;
public static final int CHECK_STEP_ANALYTICS = 1;
public static final int CHECK_STEP_CRASH = 2;
public static final int CHECK_STEP_SIGN_IN = 3;
public static final int CHECK_STEP_SELECT_SITE = 4;
public static final int CHECK_STEP_SECURITY = 0;
public static final int CHECK_STEP_WARNING = 1;
public static final int CHECK_STEP_ANALYTICS = 2;
public static final int CHECK_STEP_CRASH = 3;
public static final int CHECK_STEP_SIGN_IN = 4;
public static final int CHECK_STEP_SELECT_SITE = 5;
public static final String KEY_TARGET_SCENE = "target_scene";
public static final String KEY_TARGET_ARGS = "target_args";
@@ -106,6 +106,7 @@ public final class MainActivity extends StageActivity
private int mNavCheckedItem = 0;
static {
registerLaunchMode(SecurityScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK);
registerLaunchMode(WarningScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK);
registerLaunchMode(AnalyticsScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK);
registerLaunchMode(CrashScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK);
@@ -128,6 +129,11 @@ public final class MainActivity extends StageActivity
public void startSceneForCheckStep(int checkStep, Bundle args) {
switch (checkStep) {
case CHECK_STEP_SECURITY:
if (Settings.getShowWarning()) {
startScene(new Announcer(WarningScene.class).setArgs(args));
break;
}
case CHECK_STEP_WARNING:
if (Settings.getAskAnalytics()) {
startScene(new Announcer(AnalyticsScene.class).setArgs(args));
@@ -184,7 +190,9 @@ public final class MainActivity extends StageActivity
@Nullable
@Override
protected Announcer getLaunchAnnouncer() {
if (Settings.getShowWarning()) {
if (!TextUtils.isEmpty(Settings.getSecurity())) {
return new Announcer(SecurityScene.class);
} else if (Settings.getShowWarning()) {
return new Announcer(WarningScene.class);
} else if (Settings.getAskAnalytics()) {
return new Announcer(AnalyticsScene.class);
@@ -204,7 +212,12 @@ public final class MainActivity extends StageActivity
// Sometimes scene can't show directly
private Announcer processAnnouncer(Announcer announcer) {
if (0 == getSceneCount()) {
if (Settings.getShowWarning()) {
if (!TextUtils.isEmpty(Settings.getSecurity())) {
Bundle newArgs = new Bundle();
newArgs.putString(KEY_TARGET_SCENE, announcer.getClazz().getName());
newArgs.putBundle(KEY_TARGET_ARGS, announcer.getArgs());
return new Announcer(SecurityScene.class).setArgs(newArgs);
} else if (Settings.getShowWarning()) {
Bundle newArgs = new Bundle();
newArgs.putString(KEY_TARGET_SCENE, announcer.getClazz().getName());
newArgs.putBundle(KEY_TARGET_ARGS, announcer.getArgs());
@@ -0,0 +1,82 @@
/*
* Copyright 2016 Hippo Seven
*
* 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.hippo.ehviewer.ui;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.View;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
import com.hippo.widget.lockpattern.LockPatternUtils;
import com.hippo.widget.lockpattern.LockPatternView;
import com.hippo.yorozuya.ViewUtils;
public class SetSecurityActivity extends ToolbarActivity implements View.OnClickListener {
@Nullable
private LockPatternView mPatternView;
@Nullable
private View mCancel;
@Nullable
private View mSet;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_security);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
mPatternView = (LockPatternView) ViewUtils.$$(this, R.id.pattern_view);
mCancel = ViewUtils.$$(this, R.id.cancel);
mSet = ViewUtils.$$(this, R.id.set);
String pattern = Settings.getSecurity();
if (!TextUtils.isEmpty(pattern)) {
mPatternView.setPattern(LockPatternView.DisplayMode.Correct,
LockPatternUtils.stringToPattern(pattern));
}
mCancel.setOnClickListener(this);
mSet.setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
mPatternView = null;
}
@Override
public void onClick(View v) {
if (v == mCancel) {
finish();
} else if (v == mSet) {
if (null != mPatternView) {
String security;
if (mPatternView.getCellSize() <= 1) {
security = "";
} else {
security = mPatternView.getPatternString();
}
Settings.putSecurity(security);
}
finish();
}
}
}
@@ -20,11 +20,13 @@ import android.content.res.Resources;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.text.TextUtils;
import android.widget.Toast;
import com.hippo.ehviewer.AppConfig;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
import com.hippo.util.LogCat;
import com.hippo.util.ReadableTime;
@@ -34,6 +36,7 @@ public class AdvancedFragment extends PreferenceFragment implements Preference.O
private static final String KEY_DUMP_LOGCAT = "dump_logcat";
private static final String KEY_CLEAR_MEMORY_CACHE = "clear_memory_cache";
private static final String KEY_PATTERN_PROTECTION = "pattern_protection";
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -47,6 +50,16 @@ public class AdvancedFragment extends PreferenceFragment implements Preference.O
clearMemoryCache.setOnPreferenceClickListener(this);
}
@Override
public void onResume() {
super.onResume();
Preference patternProtection = findPreference(KEY_PATTERN_PROTECTION);
patternProtection.setSummary(TextUtils.isEmpty(Settings.getSecurity()) ?
R.string.settings_advanced_pattern_protection_not_set :
R.string.settings_advanced_pattern_protection_set);
}
@Override
public boolean onPreferenceClick(Preference preference) {
String key = preference.getKey();
@@ -0,0 +1,111 @@
/*
* Copyright 2016 Hippo Seven
*
* 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.hippo.ehviewer.ui.scene;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
import com.hippo.ehviewer.ui.MainActivity;
import com.hippo.widget.lockpattern.LockPatternUtils;
import com.hippo.widget.lockpattern.LockPatternView;
import com.hippo.yorozuya.ObjectUtils;
import com.hippo.yorozuya.ViewUtils;
import java.util.List;
public class SecurityScene extends BaseScene implements LockPatternView.OnPatternListener {
private static final int MAX_RETRY_TIMES = 5;
private static final String KEY_RETRY_TIMES = "retry_times";
@Nullable
private LockPatternView mPatternView;
private int mRetryTimes;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (null == savedInstanceState) {
mRetryTimes = MAX_RETRY_TIMES;
} else {
mRetryTimes = savedInstanceState.getInt(KEY_RETRY_TIMES);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(KEY_RETRY_TIMES, mRetryTimes);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_security, container, false);
mPatternView = (LockPatternView) ViewUtils.$$(view, R.id.pattern_view);
mPatternView.setOnPatternListener(this);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
mPatternView = null;
}
@Override
public void onPatternStart() {}
@Override
public void onPatternCleared() {}
@Override
public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {}
@Override
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
MainActivity activity = getActivity2();
if (null == activity || null == mPatternView) {
return;
}
String enteredPatter = LockPatternUtils.patternToString(pattern);
String targetPatter = Settings.getSecurity();
if (ObjectUtils.equal(enteredPatter, targetPatter)) {
activity.startSceneForCheckStep(MainActivity.CHECK_STEP_SECURITY, getArguments());
finish();
} else {
mPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
mRetryTimes--;
if (mRetryTimes <= 0) {
finish();
}
}
}
}
@@ -0,0 +1,75 @@
/*
* 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.hippo.widget.lockpattern;
import java.util.ArrayList;
import java.util.List;
/**
* 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<LockPatternView.Cell> stringToPattern(String string) {
List<LockPatternView.Cell> result = new ArrayList<>();
final byte[] bytes = string.getBytes();
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
result.add(LockPatternView.Cell.of(b / 3, b % 3));
}
return result;
}
/**
* Serialize a pattern.
* @param pattern The pattern.
* @return The pattern in string form.
*/
public static String patternToString(List<LockPatternView.Cell> pattern) {
if (pattern == null) {
return "";
}
final int patternSize = pattern.size();
byte[] res = new byte[patternSize];
for (int i = 0; i < patternSize; i++) {
LockPatternView.Cell cell = pattern.get(i);
res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
}
return new String(res);
}
public static boolean isPatternVaild(String pattern) {
byte[] bytes = pattern.getBytes();
if (bytes.length <= 9 && bytes.length >= 2) {
for (byte b : bytes) {
if (b >= 9 || b < 0) {
return false;
}
}
return true;
} else {
return false;
}
}
}
File diff suppressed because it is too large. Load diff