5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 10 15:27:10 PDT 2013
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
7 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/README:
--------------------------------------------------------------------------------
1 | Some tests require Mockito and DexMaker to compile and run.
2 | The two libraries need to be included into the APK.
3 |
4 | * Mockito: http://code.google.com/p/mockito/
5 | * DexMaker: http://code.google.com/p/dexmaker/
6 |
7 | When importing this project into Eclipse, add mockito.jar
8 | ("all" JAR rather than the "core" JAR) and dexmaker.jar
9 | to the "libs" directory of this test project.
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 | /*/build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Project Files
30 | *.iml
31 | .idea/
32 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
7 |
8 | 350dp
9 | 1dp
10 |
11 |
12 |
13 | 3dp
14 | 12dp
15 | 28dp
16 |
17 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/import_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
13 |
18 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-v11/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 | #ff5478c2
19 |
20 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values/enroll2sv_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-land/layouts.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | @layout/lock_pattern_activity_land
21 |
22 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-v14/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 | @android:color/holo_blue_light
19 |
20 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/aidl/com/google/android/apps/authenticator/dataexport/IExportServiceV2.aidl:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.dataexport;
18 |
19 | import android.os.Bundle;
20 |
21 | interface IExportServiceV2 {
22 | Bundle getData();
23 | void onImportSucceeded();
24 | }
25 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/openSourceDev/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 |
21 | com.google.android.apps.authenticator2.osdev
22 |
23 |
24 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/drawable/refresh_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
21 |
24 |
26 |
27 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/rename.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
20 |
21 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/openSource/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 |
21 | org.xdty.authenticator
22 | com.google.android.apps.authenticator2.os
23 |
24 |
25 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/remove_account_prompt.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
22 |
24 |
25 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/OtpGenerationNotPermittedException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | /**
20 | * Indicates that {@link OtpSource} failed to generate an OTP because OTP generation is not
21 | * permitted for the specified account.
22 | *
23 | * @author klyubin@google.com (Alex Klyubin)
24 | */
25 | public class OtpGenerationNotPermittedException extends OtpSourceException {
26 | public OtpGenerationNotPermittedException(String message) {
27 | super(message);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | alp.pkey.sys.pattern
4 | alp.pkey.sys.auto_save_pattern
5 | alp.pkey.sys.encrypter_class
6 | alp.pkey.display.stealth_mode
7 | alp.pkey.display.min_wired_dots
8 | alp.pkey.display.max_retries
9 | alp.pkey.display.captcha_wired_dots
10 |
11 | false
12 | false
13 |
14 | 4
15 | 5
16 | 4
17 |
18 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/OtpSourceException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | /**
20 | * Indicates that {@link OtpSource} failed to performed the requested operation.
21 | *
22 | * @author klyubin@google.com (Alex Klyubin)
23 | */
24 | public class OtpSourceException extends Exception {
25 | public OtpSourceException(String message) {
26 | super(message);
27 | }
28 |
29 | public OtpSourceException(String message, Throwable cause) {
30 | super(message, cause);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/org/xdty/authenticator/androidlockpattern/util/InvalidEncrypterException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Hai Bison
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xdty.authenticator.androidlockpattern.util;
18 |
19 | /**
20 | * Used to throw exception if given class is not implemented from
21 | * {@link IEncrypter}.
22 | *
23 | * @author Hai Bison
24 | * @since v2 beta
25 | */
26 | public class InvalidEncrypterException extends RuntimeException {
27 |
28 | /**
29 | * Auto-generated by Eclipse.
30 | */
31 | private static final long serialVersionUID = -1709666714042537187L;
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/AuthenticatorApp/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 22
5 | buildToolsVersion "22.0.1"
6 |
7 | defaultConfig {
8 | applicationId "org.xdty.authenticator"
9 | minSdkVersion 8
10 | targetSdkVersion 22
11 |
12 | versionCode 2
13 | versionName "1.0.1"
14 |
15 | testApplicationId "com.google.android.apps.authenticator2.tests"
16 | testInstrumentationRunner "android.test.InstrumentationTestRunner"
17 | }
18 |
19 | productFlavors {
20 | playStore {
21 | }
22 |
23 | openSourceNeo {
24 | applicationId "org.xdty.authenticator"
25 | testApplicationId "org.xdty.authenticator.tests"
26 | }
27 | }
28 |
29 | buildTypes {
30 | release {
31 | minifyEnabled false
32 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
33 | }
34 | }
35 |
36 | repositories {
37 | jcenter()
38 | }
39 |
40 | dependencies {
41 | androidTestCompile "org.mockito:mockito-core:1.9.5"
42 | androidTestCompile "com.google.dexmaker:dexmaker:1.2"
43 | androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/RunImmediatelyOnCallingThreadExecutor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import java.util.concurrent.Executor;
20 |
21 | /**
22 | * {@link Executor} that invokes the provided {@link Runnable} instances immediately on the thread
23 | * invoking its {@code execute} method.
24 | *
25 | * @author klyubin@google.com (Alex Klyubin)
26 | */
27 | public class RunImmediatelyOnCallingThreadExecutor implements Executor {
28 |
29 | @Override
30 | public void execute(Runnable command) {
31 | command.run();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/dataimport/ImportController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.dataimport;
18 |
19 | import android.content.Context;
20 | import android.content.Intent;
21 |
22 | /**
23 | * Controller for importing data from the "old" app.
24 | *
25 | * @author klyubin@google.com (Alex Klyubin)
26 | */
27 | public interface ImportController {
28 | public interface Listener {
29 | void onDataImported();
30 | void onOldAppUninstallSuggested(Intent uninstallIntent);
31 | void onFinished();
32 | }
33 |
34 | void start(Context context, Listener listener);
35 | }
36 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/view_group_progress_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
21 |
22 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/drawable/btn_dir_next_holo_dark.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/drawable/btn_dir_prev_holo_dark.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/SettingsActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.os.Bundle;
20 | import com.google.android.apps.authenticator.testability.TestablePreferenceActivity;
21 |
22 | import org.xdty.authenticator.R;
23 |
24 | /**
25 | * Top-level preferences Activity.
26 | *
27 | * @author klyubin@google.com (Alex Klyubin)
28 | */
29 | public class SettingsActivity extends TestablePreferenceActivity {
30 |
31 | @Override
32 | protected void onCreate(Bundle savedInstanceState) {
33 | super.onCreate(savedInstanceState);
34 |
35 | addPreferencesFromResource(R.xml.preferences);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/org/xdty/authenticator/security/LPEncrypter.java:
--------------------------------------------------------------------------------
1 | package org.xdty.authenticator.security;
2 |
3 | import android.content.Context;
4 |
5 | import org.xdty.authenticator.androidlockpattern.collect.Lists;
6 | import org.xdty.authenticator.androidlockpattern.util.IEncrypter;
7 | import org.xdty.authenticator.androidlockpattern.widget.LockPatternView.Cell;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * Created by ty on 15-5-21.
13 | */
14 | public class LPEncrypter implements IEncrypter {
15 |
16 | @Override
17 | public char[] encrypt(Context context, List pattern) {
18 | /*
19 | * This is a simple example. And it's also worth mentioning that this is
20 | * a very weak encrypter, just for fun :-)
21 | */
22 |
23 | StringBuilder result = new StringBuilder();
24 | for (Cell cell : pattern)
25 | result.append(Integer.toString(cell.getId() + 1)).append('-');
26 |
27 | return result.substring(0, result.length() - 1).toCharArray();
28 | }// encrypt()
29 |
30 | @Override
31 | public List decrypt(Context context, char[] encryptedPattern) {
32 | List result = Lists.newArrayList();
33 | String[] ids = new String(encryptedPattern).split("[^0-9]");
34 | for (String id : ids)
35 | result.add(Cell.of(Integer.parseInt(id) - 1));
36 |
37 | return result;
38 | }// decrypt()
39 | }
40 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/timesync/SettingsTimeCorrectionActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.timesync;
18 |
19 | import android.os.Bundle;
20 |
21 | import com.google.android.apps.authenticator.testability.TestablePreferenceActivity;
22 |
23 | import org.xdty.authenticator.R;
24 |
25 | /**
26 | * Activity that displays the "Time correction" preferences.
27 | *
28 | * @author klyubin@google.com (Alex Klyubin)
29 | */
30 | public class SettingsTimeCorrectionActivity extends TestablePreferenceActivity {
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 |
36 | addPreferencesFromResource(R.xml.preferences_time_correction);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
33 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/testability/StartActivityListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.testability;
18 |
19 | import android.content.Context;
20 | import android.content.Intent;
21 |
22 | /**
23 | * Listener which is invoked when an attempt is made to launch an {@link android.app.Activity} via
24 | * {@link Context#startActivity(Intent)} or
25 | * {@link android.app.Activity#startActivityForResult(Intent, int)}.
26 | * The listener can decide whether to proceed with the launch.
27 | *
28 | * @author klyubin@google.com (Alex Klyubin)
29 | */
30 | public interface StartActivityListener {
31 |
32 | /**
33 | * Invoked when a launch of an {@link android.app.Activity} is requested.
34 | *
35 | * @return {@code true} to consume/ignore the request, {@code false} to proceed with the launching
36 | * of the {@code Activity}.
37 | */
38 | boolean onStartActivityInvoked(Context sourceContext, Intent intent);
39 | }
40 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/UtilitiesTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import junit.framework.TestCase;
20 |
21 | /**
22 | * Unit tests for {@link Utilities}.
23 | *
24 | * @author klyubin@google.com (Alex Klyubin)
25 | */
26 | public class UtilitiesTest extends TestCase {
27 |
28 | public void testMillisToSeconds() {
29 | // Test rounding
30 | assertEquals(1234, Utilities.millisToSeconds(1234567));
31 | assertEquals(1234, Utilities.millisToSeconds(1234000));
32 | assertEquals(1234, Utilities.millisToSeconds(1234999));
33 |
34 | // Test that it works fine for longs
35 | assertEquals(12345678901L, Utilities.millisToSeconds(12345678901234L));
36 | }
37 |
38 | public void testSecondsToMillis() {
39 | assertEquals(1234000, Utilities.secondsToMillis(1234));
40 |
41 | // Test that it works fine for longs
42 | assertEquals(12345678901000L, Utilities.secondsToMillis(12345678901L));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/testability/SharedPreferencesRenamingDelegatingContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.testability;
18 |
19 | import android.content.Context;
20 | import android.content.ContextWrapper;
21 | import android.content.SharedPreferences;
22 |
23 | /**
24 | * {@link ContextWrapper} that prefixes shared preference file names with the provided prefix and
25 | * passes all other invocations through unmodified to the delegate {@link Context}.
26 | *
27 | * @author klyubin@google.com (Alex Klyubin)
28 | */
29 | public class SharedPreferencesRenamingDelegatingContext extends ContextWrapper {
30 |
31 | private final String mPrefix;
32 |
33 | public SharedPreferencesRenamingDelegatingContext(Context delegate, String prefix) {
34 | super(delegate);
35 | mPrefix = prefix;
36 | }
37 |
38 | @Override
39 | public SharedPreferences getSharedPreferences(String name, int mode) {
40 | return super.getSharedPreferences(mPrefix + name, mode);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/timesync_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
22 |
23 |
31 |
32 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/SettingsAboutActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.content.pm.PackageManager.NameNotFoundException;
20 | import android.os.Bundle;
21 |
22 | import com.google.android.apps.authenticator.testability.TestablePreferenceActivity;
23 |
24 | import org.xdty.authenticator.R;
25 |
26 | /**
27 | * Activity that displays the "About" preferences.
28 | *
29 | * @author klyubin@google.com (Alex Klyubin)
30 | */
31 | public class SettingsAboutActivity extends TestablePreferenceActivity {
32 |
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 |
37 | addPreferencesFromResource(R.xml.preferences_about);
38 |
39 | String packageVersion = "";
40 | try {
41 | packageVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
42 | } catch (NameNotFoundException e) {}
43 | findPreference("version").setSummary(packageVersion);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/PreconditionsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import junit.framework.TestCase;
20 |
21 | /**
22 | * Unit tests for {@link Preconditions}.
23 | *
24 | * @author klyubin@google.com (Alex Klyubin)
25 | */
26 | public class PreconditionsTest extends TestCase {
27 |
28 | public void testCheckNotNullSingleArg() {
29 | Object reference = "test";
30 | assertSame(reference, Preconditions.checkNotNull(reference));
31 |
32 | try {
33 | Preconditions.checkNotNull(null);
34 | fail("NullPointerException should have been thrown");
35 | } catch (NullPointerException e) {
36 | // Expected
37 | }
38 | }
39 |
40 | public void testCheckArgumentSingleArg() {
41 | Preconditions.checkArgument(true);
42 |
43 | try {
44 | Preconditions.checkArgument(false);
45 | fail("IllegalArgumentException should have been thrown");
46 | } catch (IllegalArgumentException e) {
47 | // Expected
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/timesync/AboutActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.timesync;
18 |
19 | import android.os.Bundle;
20 |
21 | import com.google.android.apps.authenticator.wizard.WizardPageActivity;
22 |
23 | import org.xdty.authenticator.R;
24 |
25 | import java.io.Serializable;
26 |
27 | /**
28 | * Activity that displays more information about the Time Correction/Sync feature.
29 | *
30 | * @author klyubin@google.com (Alex Klyubin)
31 | */
32 | public class AboutActivity extends WizardPageActivity {
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 |
38 | setPageContentView(R.layout.timesync_about);
39 | setTextViewHtmlFromResource(R.id.details, R.string.timesync_about_feature_screen_details);
40 |
41 | setButtonBarModeMiddleButtonOnly();
42 | mMiddleButton.setText(R.string.ok);
43 | }
44 |
45 | @Override
46 | protected void onMiddleButtonPressed() {
47 | onBackPressed();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/add_other_account.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
22 |
23 |
30 |
34 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/org/xdty/authenticator/androidlockpattern/util/Sys.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Hai Bison
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xdty.authenticator.androidlockpattern.util;
18 |
19 | /**
20 | * System utilities.
21 | *
22 | * @author Hai Bison
23 | */
24 | public class Sys {
25 |
26 | /**
27 | * The library name.
28 | */
29 | public static final String LIB_NAME = "android-lockpattern";
30 | /**
31 | * The library version code.
32 | */
33 | public static final int LIB_VERSION_CODE = 45;
34 | /**
35 | * The library version name.
36 | */
37 | public static final String LIB_VERSION_NAME = "3.2";
38 | /**
39 | * The library package name.
40 | */
41 | public static final String LIB_PACKAGE_NAME = "com.haibison.android.lockpattern";
42 | /**
43 | * This unique ID is used for some stuffs such as preferences' file name.
44 | *
45 | * @since v2.6 beta
46 | */
47 | public static final String UID = "a6eedbe5-1cf9-4684-8134-ad4ec9f6a131";
48 |
49 | /**
50 | * This is singleton class.
51 | */
52 | private Sys() {
53 | }// Sys
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 | #ff71ca00
19 | #ffff4444
20 |
21 |
22 |
23 |
24 |
25 | #ffffffff
26 | #ffffffff
27 | #fff4511e
28 | #ff37474f
29 | #ff009688
30 | #fff4511e
31 | #cc515151
32 |
33 |
34 |
35 | #ff303030
36 | #ffeeeeee
37 |
38 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/testability/TestableActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.testability;
18 |
19 | import android.app.Activity;
20 | import android.content.Intent;
21 |
22 | /**
23 | * Base class for {@link Activity} instances to make them more testable.
24 | *
25 | * @author klyubin@google.com (Alex Klyubin)
26 | */
27 | public class TestableActivity extends Activity {
28 |
29 | @Override
30 | public void startActivity(Intent intent) {
31 | StartActivityListener listener = DependencyInjector.getStartActivityListener();
32 | if ((listener != null) && (listener.onStartActivityInvoked(this, intent))) {
33 | return;
34 | }
35 |
36 | super.startActivity(intent);
37 | }
38 |
39 | @Override
40 | public void startActivityForResult(Intent intent, int requestCode) {
41 | StartActivityListener listener = DependencyInjector.getStartActivityListener();
42 | if ((listener != null) && (listener.onStartActivityInvoked(this, intent))) {
43 | return;
44 | }
45 |
46 | super.startActivityForResult(intent, requestCode);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/org/xdty/authenticator/androidlockpattern/util/IEncrypter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Hai Bison
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xdty.authenticator.androidlockpattern.util;
18 |
19 | import android.content.Context;
20 |
21 | import org.xdty.authenticator.androidlockpattern.widget.LockPatternView;
22 |
23 | import java.util.List;
24 |
25 | /**
26 | * Interface for encrypter.
27 | *
28 | * @author Hai Bison
29 | * @since v2 beta
30 | */
31 | public interface IEncrypter {
32 |
33 | /**
34 | * Encrypts {@code pattern}.
35 | *
36 | * @param context the context.
37 | * @param pattern the pattern in the form of a list of {@link LockPatternView.Cell}.
38 | * @return the encrypted char array of the pattern.
39 | * @since v2.1 beta
40 | */
41 | char[] encrypt(Context context, List pattern);
42 |
43 | /**
44 | * Decrypts an encrypted pattern.
45 | *
46 | * @param context the context.
47 | * @param encryptedPattern the encrypted pattern.
48 | * @return the original pattern.
49 | */
50 | List decrypt(Context context, char[] encryptedPattern);
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/RunOnThisLooperThreadExecutor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.os.Handler;
20 |
21 | import java.util.concurrent.Executor;
22 |
23 | /**
24 | * {@link Executor} that invokes {@link Runnable} instances on the thread on which it was created.
25 | * The assumption is that the thread has a {@link android.os.Looper} associated with it.
26 | *
27 | * @author klyubin@google.com (Alex Klyubin)
28 | */
29 | public class RunOnThisLooperThreadExecutor implements Executor {
30 |
31 | private final Handler mHandler = new Handler();
32 |
33 | @Override
34 | public void execute(Runnable command) {
35 | if (Thread.currentThread() == mHandler.getLooper().getThread()) {
36 | // The calling thread is the target thread of the Handler -- invoke immediately, blocking
37 | // the calling thread.
38 | command.run();
39 | } else {
40 | // The calling thread is not the same as the thread with which the Handler is associated --
41 | // post to the Handler for later execution.
42 | mHandler.post(command);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/xml/preferences_time_correction.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 |
23 |
26 |
27 |
28 |
33 |
37 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/howitworks/IntroEnterCodeActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.howitworks;
18 |
19 | import android.os.Bundle;
20 |
21 | import com.google.android.apps.authenticator.wizard.WizardPageActivity;
22 |
23 | import org.xdty.authenticator.R;
24 |
25 | import java.io.Serializable;
26 |
27 | /**
28 | * The page of the "How it works" that explains that occasionally the user might need to enter a
29 | * verification code generated by this application. The user simply needs to click the Next button
30 | * to go to the next page.
31 | *
32 | * @author klyubin@google.com (Alex Klyubin)
33 | */
34 | public class IntroEnterCodeActivity extends WizardPageActivity {
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 |
40 | setPageContentView(R.layout.howitworks_enter_code);
41 | setTextViewHtmlFromResource(R.id.details, R.string.howitworks_page_enter_code_details);
42 | }
43 |
44 | @Override
45 | protected void onRightButtonPressed() {
46 | startPageActivity(IntroVerifyDeviceActivity.class);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/testability/TestablePreferenceActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.testability;
18 |
19 | import android.content.Intent;
20 | import android.preference.PreferenceActivity;
21 |
22 | /**
23 | * Base class for {@link PreferenceActivity} instances to make them more testable.
24 | *
25 | * @author klyubin@google.com (Alex Klyubin)
26 | */
27 | public class TestablePreferenceActivity extends PreferenceActivity {
28 |
29 | @Override
30 | public void startActivity(Intent intent) {
31 | StartActivityListener listener = DependencyInjector.getStartActivityListener();
32 | if ((listener != null) && (listener.onStartActivityInvoked(this, intent))) {
33 | return;
34 | }
35 |
36 | super.startActivity(intent);
37 | }
38 |
39 | @Override
40 | public void startActivityForResult(Intent intent, int requestCode) {
41 | StartActivityListener listener = DependencyInjector.getStartActivityListener();
42 | if ((listener != null) && (listener.onStartActivityInvoked(this, intent))) {
43 | return;
44 | }
45 |
46 | super.startActivityForResult(intent, requestCode);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/howitworks/IntroEnterPasswordActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.howitworks;
18 |
19 | import android.os.Bundle;
20 |
21 | import com.google.android.apps.authenticator.wizard.WizardPageActivity;
22 |
23 | import org.xdty.authenticator.R;
24 |
25 | import java.io.Serializable;
26 |
27 | /**
28 | * The start page of the "How it works" flow that explains that in addition to entering the password
29 | * during sign in a verification code may be required. The user simply needs to click the Next
30 | * button to go to the next page.
31 | *
32 | * @author klyubin@google.com (Alex Klyubin)
33 | */
34 | public class IntroEnterPasswordActivity extends WizardPageActivity {
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 |
40 | setPageContentView(R.layout.howitworks_enter_password);
41 | setTextViewHtmlFromResource(R.id.details, R.string.howitworks_page_enter_password_details);
42 | }
43 |
44 | @Override
45 | protected void onRightButtonPressed() {
46 | startPageActivity(IntroEnterCodeActivity.class);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/howitworks/IntroEnterCodeActivityTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.howitworks;
18 |
19 | import com.google.android.apps.authenticator.wizard.WizardPageActivityTestBase;
20 |
21 | import android.content.Intent;
22 |
23 | import java.io.Serializable;
24 |
25 | /**
26 | * Unit tests for {@link IntroEnterCodeActivity}.
27 | *
28 | * @author klyubin@google.com (Alex Klyubin)
29 | */
30 | public class IntroEnterCodeActivityTest
31 | extends WizardPageActivityTestBase {
32 |
33 | public IntroEnterCodeActivityTest() {
34 | super(IntroEnterCodeActivity.class);
35 | }
36 |
37 | public void testBackKeyFinishesActivity() throws Exception {
38 | assertBackKeyFinishesActivity();
39 | }
40 |
41 | public void testLeftButtonFinishesActivity() throws Exception {
42 | assertLeftButtonPressFinishesActivity();
43 | }
44 |
45 | public void testRightButtonStartsNextPage() throws Exception {
46 | Intent intent = pressRightButtonAndCaptureActivityStartIntent();
47 | assertIntentForClassInTargetPackage(IntroVerifyDeviceActivity.class, intent);
48 | assertFalse(getActivity().isFinishing());
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/howitworks/IntroVerifyDeviceActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.howitworks;
18 |
19 | import android.os.Bundle;
20 |
21 | import com.google.android.apps.authenticator.wizard.WizardPageActivity;
22 |
23 | import org.xdty.authenticator.R;
24 |
25 | import java.io.Serializable;
26 |
27 | /**
28 | * The page of the "How it works" flow that explains that the user can ask Google not to
29 | * ask for verification codes every time the user signs in from a verified computer or device.
30 | * The user needs to click the Exit button to exit the flow.
31 | *
32 | * @author klyubin@google.com (Alex Klyubin)
33 | */
34 | public class IntroVerifyDeviceActivity extends WizardPageActivity {
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 |
40 | setPageContentView(R.layout.howitworks_verify_device);
41 | setTextViewHtmlFromResource(R.id.details, R.string.howitworks_page_verify_device_details);
42 |
43 | mRightButton.setText(R.string.button_exit_howitworks_flow);
44 | }
45 |
46 | @Override
47 | protected void onRightButtonPressed() {
48 | exitWizard();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/howitworks/IntroEnterPasswordActivityTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.howitworks;
18 |
19 | import com.google.android.apps.authenticator.wizard.WizardPageActivityTestBase;
20 |
21 | import android.content.Intent;
22 |
23 | import java.io.Serializable;
24 |
25 | /**
26 | * Unit tests for {@link IntroEnterPasswordActivity}.
27 | *
28 | * @author klyubin@google.com (Alex Klyubin)
29 | */
30 | public class IntroEnterPasswordActivityTest
31 | extends WizardPageActivityTestBase {
32 |
33 | public IntroEnterPasswordActivityTest() {
34 | super(IntroEnterPasswordActivity.class);
35 | }
36 |
37 | public void testBackKeyFinishesActivity() throws Exception {
38 | assertBackKeyFinishesActivity();
39 | }
40 |
41 | public void testLeftButtonFinishesActivity() throws Exception {
42 | assertLeftButtonPressFinishesActivity();
43 | }
44 |
45 | public void testRightButtonStartsNextPage() throws Exception {
46 | Intent intent = pressRightButtonAndCaptureActivityStartIntent();
47 | assertIntentForClassInTargetPackage(IntroEnterCodeActivity.class, intent);
48 | assertFalse(getActivity().isFinishing());
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/howitworks_enter_code.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
22 |
23 |
30 |
31 |
39 |
40 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/howitworks/IntroVerifyDeviceActivityTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.howitworks;
18 |
19 | import com.google.android.apps.authenticator.AuthenticatorActivity;
20 | import com.google.android.apps.authenticator.wizard.WizardPageActivityTestBase;
21 |
22 | import android.content.Intent;
23 |
24 | import java.io.Serializable;
25 |
26 | /**
27 | * Unit tests for {@link IntroVerifyDeviceActivity}.
28 | *
29 | * @author klyubin@google.com (Alex Klyubin)
30 | */
31 | public class IntroVerifyDeviceActivityTest
32 | extends WizardPageActivityTestBase {
33 |
34 | public IntroVerifyDeviceActivityTest() {
35 | super(IntroVerifyDeviceActivity.class);
36 | }
37 |
38 | public void testBackKeyFinishesActivity() throws Exception {
39 | assertBackKeyFinishesActivity();
40 | }
41 |
42 | public void testLeftButtonFinishesActivity() throws Exception {
43 | assertLeftButtonPressFinishesActivity();
44 | }
45 |
46 | public void testRightButtonExitsWizard() throws Exception {
47 | Intent intent = pressRightButtonAndCaptureActivityStartIntent();
48 | assertIntentForClassInTargetPackage(AuthenticatorActivity.class, intent);
49 | assertTrue(getActivity().isFinishing());
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/howitworks_verify_device.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
22 |
23 |
30 |
31 |
39 |
40 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/howitworks_enter_password.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
22 |
23 |
30 |
31 |
39 |
40 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/enter_key.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
20 |
23 |
27 |
30 |
34 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/activity_export.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
14 |
21 |
27 |
28 |
29 |
33 |
40 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | NeoAuthenticator
2 | ======================================================
3 |
4 | NeoAuthenticator is an enhancement to google Authenticator. Add export/import, lock pattern features.
5 |
6 | Added Features
7 | --------------
8 | 1\. Export and import
9 |
10 | You can export and import your keys with password to external storage, the file is encrypted via PBKDF2/AES.
11 |
12 | More details: [ExportActivity.java](https://github.com/xdtianyu/NeoAuthenticator/blob/master/AuthenticatorApp/src/main/java/org/xdty/authenticator/ExportActivity.java)
13 |
14 | 2\. Lock pattern
15 |
16 | You can setup a lock pattern to prevent others accessing your authenticator's keys.
17 |
18 | More details: [LockPatternSettingActivity.java](https://github.com/xdtianyu/NeoAuthenticator/blob/master/AuthenticatorApp/src/main/java/org/xdty/authenticator/LockPatternSettingActivity.java)
19 |
20 | Google Authenticator for Android (open source version)
21 | ======================================================
22 | Copyright 2010 Google Inc.
23 |
24 | https://github.com/google/google-authenticator-android
25 |
26 | This project is an older fork of the one on the Play store. It's an older
27 | version that doesn't get changes synced to it from the Play store version.
28 |
29 | Description
30 | -----------
31 | The Google Authenticator project includes implementations of one-time passcode
32 | generators for several mobile platforms, as well as a pluggable authentication
33 | module (PAM). One-time passcodes are generated using open standards developed by
34 | the [Initiative for Open Authentication (OATH)](http://www.openauthentication.org/)
35 | (which is unrelated to [OAuth](http://oauth.net/ OAuth)).
36 |
37 | This project contains the Android app. All other apps, and the PAM module, are in
38 | [a separate project](https://github.com/google/google-authenticator).
39 |
40 | This implementation supports the HMAC-Based One-time Password (HOTP) algorithm
41 | specified in [RFC 4226](https://tools.ietf.org/html/rfc4226) and the Time-based
42 | One-time Password (TOTP) algorithm specified in [RFC 6238](https://tools.ietf.org/html/rfc6238).
43 |
44 | Further documentation is available in the [Wiki](https://github.com/google/google-authenticator/wiki).
45 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/export_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
19 |
20 |
26 |
31 |
38 |
42 |
48 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/xml/preferences_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 |
25 |
29 |
32 |
33 |
34 |
38 |
41 |
42 |
45 |
48 |
49 |
52 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/activity_lock_pattern.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
16 |
22 |
29 |
30 |
31 |
37 |
43 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/Utilities.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.webkit.WebView;
20 |
21 | /**
22 | * A class for handling a variety of utility things. This was mostly made
23 | * because I needed to centralize dialog related constants. I foresee this class
24 | * being used for other code sharing across Activities in the future, however.
25 | *
26 | * @author alexei@czeskis.com (Alexei Czeskis)
27 | *
28 | */
29 | public class Utilities {
30 | // Links
31 | public static final String ZXING_MARKET =
32 | "market://search?q=pname:com.google.zxing.client.android";
33 | public static final String ZXING_DIRECT =
34 | "https://zxing.googlecode.com/files/BarcodeScanner3.1.apk";
35 |
36 | // Dialog IDs
37 | public static final int DOWNLOAD_DIALOG = 0;
38 | public static final int MULTIPLE_ACCOUNTS_DIALOG = 1;
39 | static final int INVALID_QR_CODE = 3;
40 | static final int INVALID_SECRET_IN_QR_CODE = 7;
41 |
42 | public static final long SECOND_IN_MILLIS = 1000;
43 | public static final long MINUTE_IN_MILLIS = 60 * SECOND_IN_MILLIS;
44 |
45 | // Constructor -- Does nothing yet
46 | private Utilities() { }
47 |
48 | public static final long millisToSeconds(long timeMillis) {
49 | return timeMillis / 1000;
50 | }
51 |
52 | public static final long secondsToMillis(long timeSeconds) {
53 | return timeSeconds * 1000;
54 | }
55 |
56 | /**
57 | * Sets the provided HTML as the contents of the provided {@link WebView}.
58 | */
59 | public static void setWebViewHtml(WebView view, String html) {
60 | view.loadDataWithBaseURL(null, html, "text/html", "utf-8", null);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/AddOtherAccountActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.content.Intent;
20 | import android.os.Bundle;
21 | import android.view.View;
22 |
23 | import com.google.android.apps.authenticator.wizard.WizardPageActivity;
24 |
25 | import org.xdty.authenticator.R;
26 |
27 | import java.io.Serializable;
28 |
29 | /**
30 | * The page of the "Add account" flow that offers the user to add an account.
31 | * The page offers the user to scan a barcode or manually enter the account details.
32 | *
33 | * @author klyubin@google.com (Alex Klyubin)
34 | */
35 | public class AddOtherAccountActivity extends WizardPageActivity {
36 |
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 |
41 | setPageContentView(R.layout.add_other_account);
42 |
43 | findViewById(R.id.scan_barcode).setOnClickListener(new View.OnClickListener() {
44 | @Override
45 | public void onClick(View v) {
46 | scanBarcode();
47 | }
48 | });
49 | findViewById(R.id.manually_add_account).setOnClickListener(new View.OnClickListener() {
50 | @Override
51 | public void onClick(View v) {
52 | manuallyEnterAccountDetails();
53 | }
54 | });
55 |
56 | mRightButton.setVisibility(View.INVISIBLE);
57 | }
58 |
59 | private void manuallyEnterAccountDetails() {
60 | Intent intent = new Intent(Intent.ACTION_VIEW);
61 | intent.setClass(this, EnterKeyActivity.class);
62 | startActivity(intent);
63 | }
64 |
65 | private void scanBarcode() {
66 | startActivity(AuthenticatorActivity.getLaunchIntentActionScanBarcode(this));
67 | finish();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/xml/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 |
24 |
27 |
28 |
29 |
30 |
34 |
37 |
38 |
39 |
40 |
44 |
47 |
48 |
49 |
50 |
54 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/UserRowView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.content.Context;
20 | import android.util.AttributeSet;
21 | import android.view.accessibility.AccessibilityEvent;
22 | import android.widget.LinearLayout;
23 | import android.widget.TextView;
24 |
25 | import org.xdty.authenticator.R;
26 |
27 | /**
28 | * Custom view that shows the user, pin, and "Get New Code" button (if enabled).
29 | * The layout for this is under res/layout/user_row.xml
30 | * For better accessibility, we have created this custom class to generate
31 | * accessibility events that are better suited for this widget.
32 | *
33 | * @author clchen@google.com (Charles L. Chen)
34 | */
35 | public class UserRowView extends LinearLayout {
36 |
37 | public UserRowView(Context context) {
38 | super(context);
39 | }
40 |
41 | public UserRowView(Context context, AttributeSet attrset) {
42 | super(context, attrset);
43 | }
44 |
45 | @Override
46 | public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent accessEvent) {
47 | Context ctx = this.getContext();
48 |
49 | String message = "";
50 | CharSequence pinText = ((TextView) findViewById(R.id.pin_value)).getText();
51 | if (ctx.getString(R.string.empty_pin).equals(pinText)){
52 | message = ctx.getString(R.string.counter_pin);
53 | } else {
54 | for (int i = 0; i < pinText.length(); i++) {
55 | message = message + pinText.charAt(i) + " ";
56 | }
57 | }
58 | CharSequence userText = ((TextView) findViewById(R.id.current_user)).getText();
59 | message = message + " " + userText;
60 | accessEvent.setClassName(getClass().getName());
61 | accessEvent.setPackageName(ctx.getPackageName());
62 | accessEvent.getText().add(message);
63 |
64 | return true;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
36 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
50 |
54 |
55 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/org/xdty/authenticator/androidlockpattern/collect/Lists.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xdty.authenticator.androidlockpattern.collect;
18 |
19 | import java.util.ArrayList;
20 | import java.util.Collections;
21 |
22 | /**
23 | * Provides static methods for creating {@code List} instances easily, and other
24 | * utility methods for working with lists.
25 | */
26 | public class Lists {
27 |
28 | /**
29 | * Creates an empty {@code ArrayList} instance.
30 | *
31 | *
32 | * Note: if you only need an immutable empty List, use
33 | * {@link Collections#emptyList} instead.
34 | *
35 | * @return a newly-created, initially-empty {@code ArrayList}
36 | */
37 | public static ArrayList newArrayList() {
38 | return new ArrayList();
39 | }
40 |
41 | /**
42 | * Creates a resizable {@code ArrayList} instance containing the given
43 | * elements.
44 | *
45 | *
46 | * Note: due to a bug in javac 1.5.0_06, we cannot support the
47 | * following:
48 | *
49 | *
50 | * {@code List list = Lists.newArrayList(sub1, sub2);}
51 | *
52 | *
53 | * where {@code sub1} and {@code sub2} are references to subtypes of
54 | * {@code Base}, not of {@code Base} itself. To get around this, you must
55 | * use:
56 | *
57 | *
58 | * {@code List list = Lists.newArrayList(sub1, sub2);}
59 | *
60 | * @param elements
61 | * the elements that the list should contain, in order
62 | * @return a newly-created {@code ArrayList} containing those elements
63 | */
64 | public static ArrayList newArrayList(E... elements) {
65 | int capacity = (elements.length * 110) / 100 + 5;
66 | ArrayList list = new ArrayList(capacity);
67 | Collections.addAll(list, elements);
68 | return list;
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/OtpSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import java.util.Collection;
20 |
21 | /**
22 | * Abstraction for collection of OTP tokens.
23 | *
24 | * @author cemp@google.com (Cem Paya)
25 | */
26 | public interface OtpSource {
27 |
28 | /**
29 | * Enumerate list of accounts that this OTP token supports.
30 | *
31 | * @param result Collection to append usernames. This object is NOT cleared on
32 | * entry; if there are existing items, they will not be removed.
33 | * @return Number of accounts added to the collection.
34 | */
35 | int enumerateAccounts(Collection result);
36 |
37 | /**
38 | * Return the next OTP code for specified username.
39 | * Invoking this function may change internal state of the OTP generator,
40 | * for example advancing the counter.
41 | *
42 | * @param accountName Username, email address or other unique identifier for the account.
43 | * @return OTP as string code.
44 | */
45 | String getNextCode(String accountName) throws OtpSourceException;
46 |
47 | /**
48 | * Generate response to a given challenge based on next OTP code.
49 | * Subclasses are not required to implement this method.
50 | *
51 | * @param accountName Username, email address or other unique identifier for the account.
52 | * @param challenge Server specified challenge as UTF8 string.
53 | * @return Response to the challenge.
54 | * @throws UnsupportedOperationException if the token does not support
55 | * challenge-response extension for this account.
56 | */
57 | String respondToChallenge(String accountName, String challenge) throws OtpSourceException;
58 |
59 | /**
60 | * Gets the counter for generating or verifying TOTP codes.
61 | */
62 | TotpCounter getTotpCounter();
63 |
64 | /**
65 | * Gets the clock for generating or verifying TOTP codes.
66 | */
67 | TotpClock getTotpClock();
68 | }
69 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/org/xdty/authenticator/androidlockpattern/util/ResourceUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Hai Bison
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xdty.authenticator.androidlockpattern.util;
18 |
19 | import android.content.Context;
20 | import android.content.res.Resources;
21 | import android.util.TypedValue;
22 |
23 | /**
24 | * Resources' utilities.
25 | *
26 | * @author Hai Bison
27 | */
28 | public class ResourceUtils {
29 |
30 | /**
31 | * This is singleton class.
32 | */
33 | private ResourceUtils() {
34 | }// ResourceUtils()
35 |
36 | /**
37 | * Convenient method for {@link Context#getTheme()} and
38 | * {@link Resources.Theme#resolveAttribute(int, TypedValue, boolean)}.
39 | *
40 | * @param context the context.
41 | * @param resId The resource identifier of the desired theme attribute.
42 | * @return the resource ID that {@link TypedValue#resourceId} points to, or
43 | * {@code 0} if not found.
44 | */
45 | public static int resolveAttribute(Context context, int resId) {
46 | return resolveAttribute(context, resId, 0);
47 | }// resolveAttribute()
48 |
49 | /**
50 | * Convenient method for {@link Context#getTheme()} and
51 | * {@link Resources.Theme#resolveAttribute(int, TypedValue, boolean)}.
52 | *
53 | * @param context the context.
54 | * @param resId The resource identifier of the desired theme attribute.
55 | * @param defaultValue the default value if cannot resolve {@code resId}.
56 | * @return the resource ID that {@link TypedValue#resourceId} points to, or
57 | * {@code defaultValue} if not found.
58 | */
59 | public static int resolveAttribute(Context context, int resId,
60 | int defaultValue) {
61 | TypedValue typedValue = new TypedValue();
62 | if (context.getTheme().resolveAttribute(resId, typedValue, true))
63 | return typedValue.resourceId;
64 | return defaultValue;
65 | }// resolveAttribute()
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/AuthenticatorApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import com.google.android.apps.authenticator.testability.DependencyInjector;
20 |
21 | import android.app.Application;
22 |
23 | /**
24 | * Authenticator application which is one of the first things instantiated when our process starts.
25 | * At the moment the only reason for the existence of this class is to initialize
26 | * {@link DependencyInjector} with the application context so that the class can (later) instantiate
27 | * the various objects it owns.
28 | *
29 | * Also restrict UNIX file permissions on application's persistent data directory to owner
30 | * (this app's UID) only.
31 | *
32 | * @author klyubin@google.com (Alex Klyubin)
33 | */
34 | public class AuthenticatorApplication extends Application {
35 |
36 | @Override
37 | public void onCreate() {
38 | super.onCreate();
39 |
40 | // Try to restrict data dir file permissions to owner (this app's UID) only. This mitigates the
41 | // security vulnerability where SQLite database transaction journals are world-readable.
42 | // NOTE: This also prevents all files in the data dir from being world-accessible, which is fine
43 | // because this application does not need world-accessible files.
44 | try {
45 | FileUtilities.restrictAccessToOwnerOnly(
46 | getApplicationContext().getApplicationInfo().dataDir);
47 | } catch (Throwable e) {
48 | // Ignore this exception and don't log anything to avoid attracting attention to this fix
49 | }
50 |
51 | // During test runs the injector may have been configured already. Thus we take care to avoid
52 | // overwriting any existing configuration here.
53 | DependencyInjector.configureForProductionIfNotConfigured(getApplicationContext());
54 | }
55 |
56 | @Override
57 | public void onTerminate() {
58 | DependencyInjector.close();
59 |
60 | super.onTerminate();
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/MarketBuildOptionalFeatures.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.app.Dialog;
20 | import android.content.Context;
21 | import android.content.Intent;
22 | import android.content.SharedPreferences;
23 | import android.net.Uri;
24 |
25 | /**
26 | * {@link OptionalFeatures} implementation used in Market builds.
27 | *
28 | * @author klyubin@google.com (Alex Klyubin)
29 | */
30 | public class MarketBuildOptionalFeatures implements OptionalFeatures {
31 |
32 | @Override
33 | public void onAuthenticatorActivityCreated(AuthenticatorActivity activity) {}
34 |
35 | @Override
36 | public void onAuthenticatorActivityAccountSaved(Context context, String account) {}
37 |
38 | @Override
39 | public boolean interpretScanResult(Context context, Uri scanResult) {
40 | return false;
41 | }
42 |
43 | @Override
44 | public void onDataImportedFromOldApp(Context context) {}
45 |
46 | @Override
47 | public SharedPreferences getSharedPreferencesForDataImportFromOldApp(Context context) {
48 | return null;
49 | }
50 |
51 | @Override
52 | public String appendDataImportLearnMoreLink(Context context, String text) {
53 | return text;
54 | }
55 |
56 | @Override
57 | public OtpSource createOtpSource(AccountDb accountDb, TotpClock totpClock) {
58 | return new OtpProvider(accountDb, totpClock);
59 | }
60 |
61 | @Override
62 | public void onAuthenticatorActivityGetNextOtpFailed(
63 | AuthenticatorActivity activity, String accountName, OtpSourceException exception) {
64 | throw new RuntimeException("Failed to generate OTP for account", exception);
65 | }
66 |
67 | @Override
68 | public Dialog onAuthenticatorActivityCreateDialog(AuthenticatorActivity activity, int id) {
69 | return null;
70 | }
71 |
72 | @Override
73 | public void onAuthenticatorActivityAddAccount(AuthenticatorActivity activity) {
74 | activity.startActivity(new Intent(activity, AddOtherAccountActivity.class));
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/HexEncodingTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.test.MoreAsserts;
20 |
21 | import junit.framework.TestCase;
22 |
23 | /**
24 | * Unit tests for {@link HexEncoding}.
25 | *
26 | * @author klyubin@google.com (Alex Klyubin)
27 | */
28 | public class HexEncodingTest extends TestCase {
29 |
30 | public void testEncodeNull() {
31 | try {
32 | HexEncoding.encode(null);
33 | fail();
34 | } catch (NullPointerException expected) {}
35 | }
36 |
37 | public void testEncodeEmpty() {
38 | assertEquals("", HexEncoding.encode(new byte[0]));
39 | }
40 |
41 | public void testEncodeAllDigits() {
42 | assertEquals("0123456789abcdef", HexEncoding.encode(
43 | new byte[] {0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef}));
44 | }
45 |
46 | public void testDecodeNull() {
47 | try {
48 | HexEncoding.decode(null);
49 | fail();
50 | } catch (NullPointerException expected) {}
51 | }
52 |
53 | public void testDecodeEmpty() {
54 | MoreAsserts.assertEquals(new byte[0], HexEncoding.decode(""));
55 | }
56 |
57 | public void testDecodeAllDigits() {
58 | MoreAsserts.assertEquals(
59 | new byte[] {0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef},
60 | HexEncoding.decode("0123456789abcdef"));
61 | }
62 |
63 | public void testDecodeOddNumberOfDigits() {
64 | MoreAsserts.assertEquals(
65 | new byte[] {0x0f, 0x23, 0x45},
66 | HexEncoding.decode("f2345"));
67 | }
68 |
69 | public void testDecodeOneDigit() {
70 | MoreAsserts.assertEquals(
71 | new byte[] {0x03},
72 | HexEncoding.decode("3"));
73 | }
74 |
75 | public void testDecode_withSpaces() {
76 | try {
77 | HexEncoding.decode("01 23");
78 | fail();
79 | } catch (IllegalArgumentException expected) {}
80 | }
81 |
82 | public void testDecode_withUpperCaseDigits() {
83 | MoreAsserts.assertEquals(
84 | new byte[] {(byte) 0xab, (byte) 0xcd, (byte) 0xef},
85 | HexEncoding.decode("ABCDEF"));
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/user_row.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 |
23 |
24 |
30 |
31 |
36 |
39 |
40 |
44 |
49 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/AddOtherAccountActivityTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import com.google.android.apps.authenticator.testability.DependencyInjector;
20 | import com.google.android.apps.authenticator2.R;
21 |
22 | import android.content.ComponentName;
23 | import android.content.Intent;
24 | import android.test.ActivityInstrumentationTestCase2;
25 |
26 | /**
27 | * Unit tests for {@link AddOtherAccountActivity}.
28 | *
29 | * @author klyubin@google.com (Alex Klyubin)
30 | */
31 | public class AddOtherAccountActivityTest
32 | extends ActivityInstrumentationTestCase2 {
33 |
34 | public AddOtherAccountActivityTest() {
35 | super(TestUtilities.APP_PACKAGE_NAME, AddOtherAccountActivity.class);
36 | }
37 |
38 | @Override
39 | protected void setUp() throws Exception {
40 | super.setUp();
41 |
42 | DependencyInjector.resetForIntegrationTesting(getInstrumentation().getTargetContext());
43 | TestUtilities.withLaunchPreventingStartActivityListenerInDependencyResolver();
44 | }
45 |
46 | @Override
47 | protected void tearDown() throws Exception {
48 | DependencyInjector.close();
49 |
50 | super.tearDown();
51 | }
52 |
53 | public void testScanBarcode() throws Exception {
54 | TestUtilities.clickView(getInstrumentation(), getActivity().findViewById(R.id.scan_barcode));
55 |
56 | Intent actualIntent = TestUtilities.verifyWithTimeoutThatStartActivityAttemptedExactlyOnce();
57 | Intent expectedIntent = AuthenticatorActivity.getLaunchIntentActionScanBarcode(getActivity());
58 | assertEquals(expectedIntent.getAction(), actualIntent.getAction());
59 | assertEquals(expectedIntent.getComponent(), actualIntent.getComponent());
60 | }
61 |
62 | public void testManuallyAddAccount() throws Exception {
63 | TestUtilities.clickView(
64 | getInstrumentation(), getActivity().findViewById(R.id.manually_add_account));
65 |
66 | Intent actualIntent = TestUtilities.verifyWithTimeoutThatStartActivityAttemptedExactlyOnce();
67 | assertEquals(
68 | new ComponentName(getActivity(), EnterKeyActivity.class),
69 | actualIntent.getComponent());
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/lock_pattern_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
15 |
16 |
21 |
22 |
27 |
28 |
29 |
37 |
38 |
39 |
40 |
43 |
44 |
49 |
50 |
58 |
59 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/Preconditions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | /**
20 | * Simple static methods to be called at the start of your own methods to verify correct arguments
21 | * and state. Inspired by Guava.
22 | *
23 | * @author klyubin@google.com (Alex Klyubin)
24 | */
25 | public final class Preconditions {
26 |
27 | /** Hidden to avoid instantiation. */
28 | private Preconditions() {}
29 |
30 | /**
31 | * Ensures that an object reference passed as a parameter to the calling method is not
32 | * {@code null}.
33 | *
34 | * @return non-{@code null} reference that was validated.
35 | *
36 | * @throws NullPointerException if {@code reference} is {@code null}.
37 | */
38 | public static T checkNotNull(T reference) {
39 | if (reference == null) {
40 | throw new NullPointerException();
41 | }
42 | return reference;
43 | }
44 |
45 | /**
46 | * Ensures the truth of an expression involving one or more parameters to the calling method.
47 | *
48 | * @throws IllegalArgumentException if {@code expression} is {@code false}.
49 | */
50 | public static void checkArgument(boolean expression) {
51 | if (!expression) {
52 | throw new IllegalArgumentException();
53 | }
54 | }
55 |
56 | /**
57 | * Ensures the truth of an expression involving the state of the calling
58 | * instance, but not involving any parameters to the calling method.
59 | *
60 | * @throws IllegalStateException if {@code expression} is false
61 | */
62 | public static void checkState(boolean expression) {
63 | if (!expression) {
64 | throw new IllegalStateException();
65 | }
66 | }
67 |
68 | /**
69 | * Ensures the truth of an expression involving the state of the calling
70 | * instance, but not involving any parameters to the calling method.
71 | *
72 | * @param errorMessage the exception message to use if the check fails; will
73 | * be converted to a string using {@link String#valueOf(Object)}
74 | * @throws IllegalStateException if {@code expression} is false
75 | */
76 | public static void checkState(
77 | boolean expression, Object errorMessage) {
78 | if (!expression) {
79 | throw new IllegalStateException(String.valueOf(errorMessage));
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-zh-rCN/timesync_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 | "校正用来生成验证码的时间"
20 | "将身份验证器的内部时钟与 Google 服务器进行同步"
21 | "立即同步"
22 | "关于此功能"
23 | "关于此功能"
24 | "如果您按下“立即同步”,身份验证器就会尝试将其内部时钟与 Google 服务器同步一次。设备的日期和时间设置不会更改。<p>与 Google 服务器同步内部时钟时,身份验证器不会传输任何个人数据或帐户信息。<p> <b>这有什么作用</b> <p>身份验证器需要根据以下信息生成两步验证码:1) 当前时间,2) 该应用与服务器联络时使用的暗号。<p>如果身份验证器和服务器上的时间不一致,那么当您尝试登录时,系统可能不会接受该应用生成的验证码。<p>默认情况下,身份验证器会使用设备的日期和时间设置,因此在大多数情况下,只要您确保您的时间、日期和时区设置配置正确,即可生成有效的验证码。但是,如果确实出现时间不匹配的情况,就很难排查出问题(尤其是当您使用网络提供的时间或时区时)。"
25 | "立即同步"
26 | "立即同步"
27 | "正在连接服务器…"
28 | "时间已校正"
29 | "身份验证器的内部时钟已按照 Google 服务器提供的时间进行调整。"\n\n"此设备上的日期和时间设置未更改。"
30 | "时间已正确"
31 | "身份验证器的内部时钟未作调整,因为该时钟已经与 Google 服务器同步。"
32 | "立即同步"
33 | "与 Google 服务器联系时出现问题。请检查您的网络设置,然后重试。"
34 |
35 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/HexEncoding.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | /**
20 | * Hexadecimal encoding where each byte is represented by two hexadecimal digits.
21 | *
22 | * @author klyubin@google.com (Alex Klyubin)
23 | */
24 | public class HexEncoding {
25 |
26 | /** Hidden constructor to prevent instantiation. */
27 | private HexEncoding() {}
28 |
29 | private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
30 |
31 | /**
32 | * Encodes the provided data as a hexadecimal string.
33 | */
34 | public static String encode(byte[] data) {
35 | StringBuilder result = new StringBuilder(data.length * 2);
36 | for (byte b : data) {
37 | result.append(HEX_DIGITS[(b >>> 4) & 0x0f]);
38 | result.append(HEX_DIGITS[b & 0x0f]);
39 | }
40 | return result.toString();
41 | }
42 |
43 | /**
44 | * Decodes the provided hexadecimal string into an array of bytes.
45 | */
46 | public static byte[] decode(String encoded) {
47 | // IMPLEMENTATION NOTE: Special care is taken to permit odd number of hexadecimal digits.
48 | int resultLengthBytes = (encoded.length() + 1) / 2;
49 | byte[] result = new byte[resultLengthBytes];
50 | int resultOffset = 0;
51 | int encodedCharOffset = 0;
52 | if ((encoded.length() % 2) != 0) {
53 | // Odd number of digits -- the first digit is the lower 4 bits of the first result byte.
54 | result[resultOffset++] = (byte) getHexadecimalDigitValue(encoded.charAt(encodedCharOffset));
55 | encodedCharOffset++;
56 | }
57 | for (int len = encoded.length(); encodedCharOffset < len; encodedCharOffset += 2) {
58 | result[resultOffset++] = (byte)
59 | ((getHexadecimalDigitValue(encoded.charAt(encodedCharOffset)) << 4)
60 | | getHexadecimalDigitValue(encoded.charAt(encodedCharOffset + 1)));
61 | }
62 | return result;
63 | }
64 |
65 | private static int getHexadecimalDigitValue(char c) {
66 | if ((c >= 'a') && (c <= 'f')) {
67 | return (c - 'a') + 0x0a;
68 | } else if ((c >= 'A') && (c <= 'F')) {
69 | return (c - 'A') + 0x0a;
70 | } else if ((c >= '0') && (c <= '9')) {
71 | return c - '0';
72 | } else {
73 | throw new IllegalArgumentException(
74 | "Invalid hexadecimal digit at position : '" + c + "' (0x" + Integer.toHexString(c) + ")");
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-zh-rTW/timesync_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 | "驗證碼時間修正"
20 | "將 Authenticator 的內部時鐘與 Google 伺服器同步"
21 | "立即同步處理"
22 | "關於這項功能"
23 | "關於這項功能"
24 | "如果按下 [立即同步處理],Authenticator 會立刻將內部時鐘與 Google 伺服器同步化;裝置的日期和時間設定不會變更。<p>Authenticator 將內部時鐘與 Google 伺服器同步化時,不會傳送任何個人資料或帳戶資訊。<p><b>這樣做有什麼幫助</b><p>Authenticator 會根據下列條件產生兩步驟驗證碼:1) 目前的時間,以及 2) 應用程式和伺服器才知道的機密數字。<p>如果 Authenticator 和伺服器的時間不一致,當您登入時,系統不會接受應用程式產生的驗證碼。<p>根據預設,Authenticator 會使用裝置的日期和時間設定,而且在大部分情況下,只要您確定時間、日期和時區已正確設定,即可產生有效的驗證碼。不過,一旦發生時間不一致的問題,這可能會比較難以排解 (尤其是當您使用網路提供的時間或時區)。"
25 | "立即同步處理"
26 | "立即同步處理"
27 | "正在連線到伺服器…"
28 | "時間已修正"
29 | "Authenticator 的內部時鐘已調整以符合 Google 伺服器的時間。"\n\n"此裝置的日期與時間設定並未變更。"
30 | "時間正確"
31 | "Authenticator 已和 Google 伺服器同步,因此內部時鐘未調整。"
32 | "立即同步處理"
33 | "連線到 Google 伺服器時發生問題,請檢查您的網路設定,然後再試一次。"
34 |
35 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
29 |
30 |
33 |
34 |
37 |
38 |
42 |
43 |
46 |
47 |
50 |
51 |
54 |
55 |
60 |
61 |
64 |
65 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-v11/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
29 |
30 |
34 |
35 |
38 |
39 |
43 |
44 |
48 |
49 |
53 |
54 |
59 |
60 |
63 |
64 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/testability/HttpClientFactoryTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.testability;
18 |
19 | import android.os.Build;
20 | import android.test.AndroidTestCase;
21 |
22 | import org.apache.http.client.HttpClient;
23 | import org.apache.http.client.params.HttpClientParams;
24 | import org.apache.http.conn.ClientConnectionManager;
25 | import org.apache.http.conn.params.ConnManagerParams;
26 | import org.apache.http.impl.client.DefaultHttpClient;
27 | import org.apache.http.params.HttpConnectionParams;
28 | import org.apache.http.params.HttpParams;
29 |
30 | /**
31 | * Unit tests for {@link HttpClientFactory}.
32 | *
33 | * @author klyubin@google.com (Alex Klyubin)
34 | */
35 | public class HttpClientFactoryTest extends AndroidTestCase {
36 |
37 | private HttpClient mClient;
38 |
39 | @Override
40 | protected void setUp() throws Exception {
41 | super.setUp();
42 |
43 | mClient = HttpClientFactory.createHttpClient(getContext());
44 | }
45 |
46 | @Override
47 | protected void tearDown() throws Exception {
48 | if (mClient != null) {
49 | ClientConnectionManager connectionManager = mClient.getConnectionManager();
50 | if (connectionManager != null) {
51 | connectionManager.shutdown();
52 | }
53 | }
54 | super.tearDown();
55 | }
56 |
57 | public void testClientClass() throws Exception {
58 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ECLAIR_MR1) {
59 | assertEquals(
60 | getContext().getClassLoader().loadClass(DefaultHttpClient.class.getName()),
61 | mClient.getClass());
62 | } else {
63 | assertEquals(
64 | getContext().getClassLoader().loadClass("android.net.http.AndroidHttpClient"),
65 | mClient.getClass());
66 | }
67 | }
68 |
69 | public void testClientConfiguration() throws Exception {
70 | HttpParams params = mClient.getParams();
71 | assertFalse(HttpClientParams.isRedirecting(params));
72 | assertFalse(HttpClientParams.isAuthenticating(params));
73 | assertEquals(
74 | HttpClientFactory.DEFAULT_CONNECT_TIMEOUT_MILLIS,
75 | HttpConnectionParams.getConnectionTimeout(params));
76 | assertEquals(
77 | HttpClientFactory.DEFAULT_READ_TIMEOUT_MILLIS,
78 | HttpConnectionParams.getSoTimeout(params));
79 | assertEquals(
80 | HttpClientFactory.DEFAULT_GET_CONNECTION_FROM_POOL_TIMEOUT_MILLIS,
81 | ConnManagerParams.getTimeout(params));
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-ja/timesync_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 | "コードの時刻調整"
20 | "認証システムの内部クロックをGoogleサーバーと同期させます"
21 | "今すぐ同期"
22 | "この機能について"
23 | "この機能について"
24 | "[今すぐ同期]をタップすると、認証システムの内部クロックとGoogleサーバーとの同期が一度行われます。端末の日付/時刻設定は変更されません。<p> 内部クロックとGoogleサーバーの同期中に、認証システムから個人データやアカウント情報が送信されることはありません。<p> <b>同期を行う理由</b> <p> 認証システムでは、1)現在の時刻および2)アプリとサーバーが認識できる秘密の番号に基づいて2段階認証プロセスの確認コードを生成します。<p> 認証システムの時刻とサーバーの時刻が異なると、アプリによって生成されたコードがログイン時に承認されないことがあります。<p> 認証システムはデフォルトでは端末の日付/時刻設定を使用しますが、日付、時刻、タイムゾーンが正しく設定されていればほとんどの場合は有効なコードが生成されます。ただし、時刻の不一致が発生した場合(特にネットワークの時刻やタイムゾーンを使用した場合)は、トラブルシューティングが難しくなる可能性があります。"
25 | "今すぐ同期"
26 | "今すぐ同期"
27 | "サーバーに接続中..."
28 | "時刻を調整しました"
29 | "認証システムの内部クロックがGoogleサーバーの時刻に合わせて調整されました。"\n\n"この端末の日付/時刻設定は変更されていません。"
30 | "時刻は調整済みです"
31 | "認証システムの内部クロックは調整されませんでした。既にGoogleサーバーと同期済みです。"
32 | "今すぐ同期"
33 | "Googleのサーバーとの接続に問題が発生しました。ネットワーク設定を確認してもう一度お試しください。"
34 |
35 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/check_code.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
20 |
21 |
24 |
25 |
29 |
30 |
33 |
34 |
37 |
38 |
41 |
42 |
43 |
46 |
47 |
52 |
53 |
56 |
57 |
58 |
59 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/lock_pattern_activity_land.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
16 |
17 |
26 |
27 |
35 |
36 |
37 |
38 |
41 |
42 |
49 |
50 |
57 |
58 |
59 |
60 |
64 |
65 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-ko/timesync_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 | "코드에 맞게 시간 수정"
20 | "OTP 내부 시계와 Google 서버 동기화"
21 | "지금 동기화"
22 | "기능 정보"
23 | "기능 정보"
24 | ""지금 동기화"를 누르면 OTP가 내부 시계와 Google 서버와의 동기화를 1회 시도합니다. 기기의 날짜 및 시간 설정은 변경되지 않습니다. <p> OTP가 내부 시계를 Google 서버와 동기화하는 동안 개인 정보 또는 계정 정보는 전송되지 않습니다. <p> <b>이러한 방식이 유용한 이유</b> <p> OTP는 1) 현재 시간 및 2) 앱 및 서버에 인식된 비밀번호를 토대로 2단계 인증 코드를 생성합니다. <p> OTP와 서버의 현재 시간이 일치하지 않으면, 사용자가 로그인을 시도할 때 앱이 생성한 코드가 승인되지 않습니다. <p> 기본적으로 OTP는 기기의 현재 날짜 및 시간 설정을 사용하며 대부분의 경우 시간, 날짜 및 시간대를 올바르게 설정하면 유효한 코드를 생성할 수 있습니다. 하지만 시간 불일치가 실제로 발생하는 경우에는 문제를 해결하기 힘들 수 있습니다(특히 네트워크 제공 시간 또는 시간대를 사용하는 경우)."
25 | "지금 동기화"
26 | "지금 동기화"
27 | "서버에 연결 중…"
28 | "시간 수정됨"
29 | "Google 서버에서 제공한 시간과 일치하도록 OTP의 내부 시계가 조정되었습니다. "\n\n"이 기기의 날짜 및 시간 설정이 변경되지 않았습니다."
30 | "시간이 이미 정확함"
31 | "OTP의 내부 시계가 조정되지 않았습니다. Google 서버와 이미 동기화된 것 같습니다."
32 | "지금 동기화"
33 | "Google 서버에 접속하는 중에 문제가 발생했습니다. 네트워크 설정을 확인한 다음 다시 시도하세요."
34 |
35 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/org/xdty/authenticator/LockPatternSettingActivity.java:
--------------------------------------------------------------------------------
1 | package org.xdty.authenticator;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.widget.CheckBox;
7 | import android.widget.CompoundButton;
8 |
9 | import org.xdty.authenticator.androidlockpattern.LockPatternActivity;
10 | import org.xdty.authenticator.androidlockpattern.util.Settings;
11 | import org.xdty.authenticator.security.LPEncrypter;
12 |
13 | public class LockPatternSettingActivity extends Activity {
14 |
15 | private static final int REQ_CREATE_PATTERN = 1;
16 | private static final int REQ_ENTER_PATTERN = 2;
17 | private static final String TAG = "LockPatternSetting";
18 |
19 | private CheckBox enableLockPattern;
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | setContentView(R.layout.activity_lock_pattern);
25 |
26 | enableLockPattern = (CheckBox) findViewById(R.id.enable_lock_pattern);
27 | final CheckBox displayUnlockPattern = (CheckBox) findViewById(R.id.display_unlock_pattern);
28 |
29 | if (Settings.Security.getPattern(this) != null) {
30 | enableLockPattern.setChecked(true);
31 | }
32 |
33 | if (!Settings.Display.isStealthMode(this)) {
34 | displayUnlockPattern.setChecked(true);
35 | }
36 |
37 | enableLockPattern.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
38 | @Override
39 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
40 |
41 | if (isChecked) {
42 | Settings.Security.setEncrypterClass(LockPatternSettingActivity.this, LPEncrypter.class);
43 |
44 | Settings.Security.setAutoSavePattern(LockPatternSettingActivity.this, true);
45 | Intent intent = new Intent(LockPatternActivity.ACTION_CREATE_PATTERN, null,
46 | LockPatternSettingActivity.this, LockPatternActivity.class);
47 | startActivityForResult(intent, REQ_CREATE_PATTERN);
48 | } else {
49 | Settings.Security.setPattern(LockPatternSettingActivity.this, null);
50 | }
51 | }
52 | });
53 |
54 | displayUnlockPattern.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
55 | @Override
56 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
57 | if (isChecked) {
58 | Settings.Display.setStealthMode(LockPatternSettingActivity.this, false);
59 | } else {
60 | Settings.Display.setStealthMode(LockPatternSettingActivity.this, true);
61 | }
62 | }
63 | });
64 | }
65 |
66 | @Override
67 | protected void onActivityResult(int requestCode, int resultCode,
68 | Intent data) {
69 | switch (requestCode) {
70 | case REQ_CREATE_PATTERN:
71 | if (resultCode != RESULT_OK) {
72 | enableLockPattern.setChecked(false);
73 | }
74 | break;
75 |
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/org/xdty/authenticator/androidlockpattern/util/Randoms.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Hai Bison
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xdty.authenticator.androidlockpattern.util;
18 |
19 | import org.xdty.authenticator.androidlockpattern.collect.Lists;
20 |
21 | import java.util.List;
22 | import java.util.Random;
23 |
24 | /**
25 | * Random utilities.
26 | *
27 | * @author Hai Bison
28 | */
29 | public class Randoms {
30 |
31 | private static final Random RANDOM = new Random();
32 |
33 | /**
34 | * This is singleton class.
35 | */
36 | private Randoms() {
37 | }// Random()
38 |
39 | /**
40 | * Generates a random integer.
41 | *
42 | * @return the random integer.
43 | */
44 | public static int randInt() {
45 | return RANDOM.nextInt((int) (System.nanoTime() % Integer.MAX_VALUE));
46 | }// randInt()
47 |
48 | /**
49 | * Generates a random integer within {@code [0, n)}.
50 | *
51 | * @param n an arbitrary value.
52 | * @return the random integer.
53 | */
54 | public static int randInt(int n) {
55 | return n > 0 ? randInt() % n : 0;
56 | }// randInt()
57 |
58 | /**
59 | * Generates a random integer array which has length of {@code end - start},
60 | * and is filled by all values from {@code start} to {@code end - 1} in
61 | * randomized orders.
62 | *
63 | * @param start the starting value.
64 | * @param end the ending value.
65 | * @return the random integer array. If {@code end <= start}, an empty array
66 | * returns.
67 | */
68 | public static int[] randIntArray(int start, int end) {
69 | if (end <= start)
70 | return new int[0];
71 |
72 | final List values = Lists.newArrayList();
73 | for (int i = start; i < end; i++)
74 | values.add(i);
75 |
76 | final int[] result = new int[values.size()];
77 | for (int i = 0; i < result.length; i++) {
78 | int k = randInt(values.size());
79 | result[i] = values.get(k);
80 | values.remove(k);
81 | }// for
82 |
83 | return result;
84 | }// randIntArray()
85 |
86 | /**
87 | * Generates a random integer array which has length of {@code end}, and is
88 | * filled by all values from {@code 0} to {@code end - 1} in randomized
89 | * orders.
90 | *
91 | * @param end the ending value.
92 | * @return the random integer array. If {@code end <= start}, an empty array
93 | * returns.
94 | */
95 | public static int[] randIntArray(int end) {
96 | return randIntArray(0, end);
97 | }// randIntArray()
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-am/timesync_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 | "ለኮዶች የሰዓት ማስተካከያ"
20 | "የአረጋጋጭ ውስጣዊ ሰዓት ከGoogle አገልጋዮች ጋር አመሳስል"
21 | "አሁን አመሳስል"
22 | "ስለዚህ ባህርይ"
23 | "ስለዚህ ባህርይ"
24 | ""አሁን አመሳስል"ን አሁን ከጫንከው አረጋጋጭ ውስጣዊ ሰዓቱን ከGoogle የአገልጋዮች ጋር ለማመሳሰል አንድ ጊዜ ሙከራ ያደርጋል። የመሣሪያው ቀን እና ሰዓት ቅንብሮች አይቀየሩም። <p> አረጋጋጭ ውስጣዊ ሰዓቱን ከGoogle አገልጋዮች ጋር በሚያመሳስልበት ጊዜ ምንም አይነት የግል ውሂብ ወይም የመለያ መረጃ አያስተላልፍም። <p> <b>ይሄ ለምንድነው ጠቃሚ የሆነው</b> <p> አረጋጋጭ በ 1) የአሁኑ ጊዜ፣ እና በ 2) በመተግበርያውን እና በአገልጋዩ የሚታወቅ ሚስጥራዊ ቁጥር መሠረት ባለ2-ደረጃ የማረጋገጫ ኮዶችን ያመነጫል። <p> አረጋጋጭ እና አገልጋዩ በሰዓቱ መስማማት ካልቻሉ ለመግባት ስትሞክር መተግበሪያው የሚያመነጫቸው ኮዶች ተቀባይነት ላያገኙ ይችላሉ። <p> አረጋጋጭ የመሣሪያው ቀን እና ሰዓት ቅንብሮች በነባሪነት ይጠቀማል፣ እና ደግሞ በአብዛኛው አጋጣሚዎች የጊዜህ፣ የቀንህ እና የሰዓት ሰቅህ ቅንብሮች በትክክል መዋቀራቸውን በማረጋገጥ ልክ የሆኑ ኮዶችን ማመንጨት ትችላለህ። ይሁንና፣ የሰዓት አለመገጣጠሞች ሲከሰቱ መላ ለመፈለግ አስቸጋሪ ሊሆኑ ይችላል (በተለይ በአውታረ መረብ የተሰጡ ሰዓት ወይም የሰዓት ሰቆችን የምትጠቀም ከሆነ)።"
25 | "አሁን አመሳስል"
26 | "አሁን አመሳስል"
27 | "ከአገልጋይ ጋር በመገናኘት ላይ…"
28 | "ሰዓት ተስተካክሏል"
29 | "የአረጋጋጭ ውስጣዊ ሰዓት የGoogle አገልጋዮች ከሚሰጡት ሰዓት ጋር እንዲገጣጠም ተብሎ ተስተካክሏል። "\n\n"በዚህ መሣሪያ ላይ ያሉት የቀን እና ሰዓት ቅንብሮች አልተቀየሩም።"
30 | "ሰዓት አስቀድሞ ትክክል ነው"
31 | "አረጋጋጭ ከGoogle አገልጋዮች ጋር አስቀድሞ የተመሳሰለ ሆኖ ስለሚታይ ውስጣዊ ሰዓቱ አልተስተካከለም።"
32 | "አሁን አመሳስል"
33 | "የGoogle አገልጋይ ማግኘት ላይ ችግር ነበር። እባክህ የአውታረ መረብህን ግንኙነት አረጋግጥና እንደገና ሞክር።"
34 |
35 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/OptionalFeatures.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.app.Dialog;
20 | import android.content.Context;
21 | import android.content.SharedPreferences;
22 | import android.net.Uri;
23 |
24 | /**
25 | * Interface for providing functionality not available in Market builds without having to modify
26 | * the codebase shared between the Market and non-Market builds.
27 | *
28 | * @author klyubin@google.com (Alex Klyubin)
29 | */
30 | public interface OptionalFeatures {
31 |
32 | /**
33 | * Invoked when the {@link AuthenticatorActivity} {@code onCreate} is almost done.
34 | */
35 | void onAuthenticatorActivityCreated(AuthenticatorActivity activity);
36 |
37 | /**
38 | * Invoked when the {@link AuthenticatorActivity} saves an account/seed.
39 | */
40 | void onAuthenticatorActivityAccountSaved(Context context, String account);
41 |
42 | /**
43 | * Creates the {@link OtpSource} instance used for OTP generation by the app.
44 | */
45 | OtpSource createOtpSource(AccountDb accountDb, TotpClock totpClock);
46 |
47 | /**
48 | * Invoked when a HOTP OTP could not be generated by {@link AuthenticatorActivity}
49 | * for the provided account.
50 | */
51 | void onAuthenticatorActivityGetNextOtpFailed(
52 | AuthenticatorActivity activity, String accountName, OtpSourceException exception);
53 |
54 | /**
55 | * Invoked by {@link AuthenticatorActivity#onCreateDialog(int)} for dialog IDs not directly
56 | * handled by the {@link AuthenticatorActivity} class.
57 | *
58 | * @return dialog or {@code null} for the default behavior.
59 | */
60 | Dialog onAuthenticatorActivityCreateDialog(AuthenticatorActivity activity, int id);
61 |
62 | /**
63 | * Invoked when {@link AuthenticatorActivity} was asked to initiate the Add Account flow.
64 | */
65 | void onAuthenticatorActivityAddAccount(AuthenticatorActivity activity);
66 |
67 | /**
68 | * Invoked when a URI has been scanned.
69 | *
70 | * @return {@code true} if the URI has been consumed by these optional features, {@code false}
71 | * otherwise.
72 | */
73 | boolean interpretScanResult(Context context, Uri scanResult);
74 |
75 | /**
76 | * Invoked when data have been successfully imported from the old Authenticator app.
77 | */
78 | void onDataImportedFromOldApp(Context context);
79 |
80 | /**
81 | * Gets the {@link SharedPreferences} into which to import preferences from the old Authenticator
82 | * app.
83 | *
84 | * @return preferences or {@code null} to skip the importing of preferences.
85 | */
86 | SharedPreferences getSharedPreferencesForDataImportFromOldApp(Context context);
87 |
88 | /**
89 | * Appends the Learn more link to data import dialog text.
90 | *
91 | * @return text with the link.
92 | */
93 | String appendDataImportLearnMoreLink(Context context, String text);
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-iw/timesync_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 | "תיקון שעה לקודים"
20 | "סנכרן את השעון הפנימי של המאמת עם שרתי Google"
21 | "סנכרן עכשיו"
22 | "מידע על תכונה זו"
23 | "מידע על תכונה זו"
24 | "אם תלחץ על "סנכרן עכשיו", המאמת יבצע ניסיון אחד לסנכרן את השעון הפנימי שלו עם שרתי Google. הגדרות התאריך והשעה של המכשיר לא ישונו. <p> המאמת אינו משדר נתונים אישיים או מידע חשבון בעת סנכרון השעון הפנימי שלו עם שרתי Google. <p> <b>מדוע זה מועיל</b> <p> המאמת יוצר קודי אימות דו-שלבי בהתבסס על: 1) השעה הנוכחית ו-2) מספר סודי הידוע ליישום ולשרת. <p> אם קיים חוסר תאימות של השעה בין המאמת והשרת, ייתכן שהקודים שהיישום ייצור לא יתקבלו כאשר תנסה להתחבר. <p> כברירת מחדל, המאמת עושה שימוש בהגדרות התאריך והשעה של המכשיר, וברוב המקרים תוכל ליצור קודים חוקיים על ידי הקפדה על כך שהגדרות השעה, התאריך ואזור הזמן תהיינה תקינות. עם זאת, כאשר מתרחשת אי-התאמה בנוגע לשעה, קשה לפתור זאת (בעיקר אם אתה משתמש בשעה או באזור זמן שמקורם ברשת)."
25 | "סנכרן עכשיו"
26 | "סנכרן עכשיו"
27 | "מתחבר לשרת…"
28 | "השעה תוקנה"
29 | "השעון הפנימי של המאמת הותאם כדי שיהיה תואם לשעה שמספקים שרתי Google. "\n" "\n" הגדרות התאריך והשעה במכשיר זה לא שונו."
30 | "השעה כבר נכונה"
31 | "השעון הפנימי של המאמת לא הותאם מפני שעושה רושם שהוא כבר מסונכרן עם השרתים של Google."
32 | "סנכרן עכשיו"
33 | "אירעה בעיה ביצירת קשר עם השרת של Google. בדוק את הגדרות הרשת שלך ונסה שוב."
34 |
35 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/TotpClock.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import android.content.Context;
20 | import android.content.SharedPreferences;
21 | import android.preference.PreferenceManager;
22 |
23 | /**
24 | * Clock input for the time-based OTPs (TOTP). The input is based on the current system time
25 | * and is adjusted by a persistently stored correction value (offset in minutes).
26 | *
27 | * @author klyubin@google.com (Alex Klyubin)
28 | */
29 | public class TotpClock implements SharedPreferences.OnSharedPreferenceChangeListener {
30 |
31 | // @VisibleForTesting
32 | static final String PREFERENCE_KEY_OFFSET_MINUTES = "timeCorrectionMinutes";
33 |
34 | private final SharedPreferences mPreferences;
35 |
36 | private final Object mLock = new Object();
37 |
38 | /**
39 | * Cached value of time correction (in minutes) or {@code null} if not cached. The value is cached
40 | * because it's read very frequently (once every 100ms) and is modified very infrequently.
41 | *
42 | * @GuardedBy {@link #mLock}
43 | */
44 | private Integer mCachedCorrectionMinutes;
45 |
46 | public TotpClock(Context context) {
47 | mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
48 | mPreferences.registerOnSharedPreferenceChangeListener(this);
49 | }
50 |
51 | /**
52 | * Gets the number of milliseconds since epoch.
53 | */
54 | public long currentTimeMillis() {
55 | return System.currentTimeMillis() + getTimeCorrectionMinutes() * Utilities.MINUTE_IN_MILLIS;
56 | }
57 |
58 | /**
59 | * Gets the currently used time correction value.
60 | *
61 | * @return number of minutes by which this device is behind the correct time.
62 | */
63 | public int getTimeCorrectionMinutes() {
64 | synchronized (mLock) {
65 | if (mCachedCorrectionMinutes == null) {
66 | try {
67 | mCachedCorrectionMinutes = mPreferences.getInt(PREFERENCE_KEY_OFFSET_MINUTES, 0);
68 | } catch(ClassCastException e) {
69 | mCachedCorrectionMinutes = Integer.valueOf(mPreferences.getString(PREFERENCE_KEY_OFFSET_MINUTES, "0"));
70 | }
71 | }
72 | return mCachedCorrectionMinutes;
73 | }
74 | }
75 |
76 | /**
77 | * Sets the currently used time correction value.
78 | *
79 | * @param minutes number of minutes by which this device is behind the correct time.
80 | */
81 | public void setTimeCorrectionMinutes(int minutes) {
82 | synchronized (mLock) {
83 | mPreferences.edit().putInt(PREFERENCE_KEY_OFFSET_MINUTES, minutes).commit();
84 | // Invalidate the cache to force reading actual settings from time to time
85 | mCachedCorrectionMinutes = null;
86 | }
87 | }
88 |
89 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
90 | if (key.equals(PREFERENCE_KEY_OFFSET_MINUTES)) {
91 | // Invalidate the cache
92 | mCachedCorrectionMinutes = null;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
22 |
25 |
29 |
36 |
43 |
51 |
56 |
61 |
62 |
69 |
76 |
77 |
78 |
79 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/SettingsAboutActivityTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import com.google.android.apps.authenticator.testability.DependencyInjector;
20 | import com.google.android.apps.authenticator2.R;
21 |
22 | import android.content.Intent;
23 | import android.preference.Preference;
24 | import android.test.ActivityInstrumentationTestCase2;
25 |
26 | /**
27 | * Unit tests for {@link SettingsAboutActivity}.
28 | *
29 | * @author klyubin@google.com (Alex Klyubin)
30 | */
31 | public class SettingsAboutActivityTest
32 | extends ActivityInstrumentationTestCase2 {
33 |
34 | public SettingsAboutActivityTest() {
35 | super(TestUtilities.APP_PACKAGE_NAME, SettingsAboutActivity.class);
36 | }
37 |
38 | @Override
39 | protected void setUp() throws Exception {
40 | super.setUp();
41 |
42 | DependencyInjector.resetForIntegrationTesting(getInstrumentation().getTargetContext());
43 | TestUtilities.withLaunchPreventingStartActivityListenerInDependencyResolver();
44 | }
45 |
46 | @Override
47 | protected void tearDown() throws Exception {
48 | DependencyInjector.close();
49 |
50 | super.tearDown();
51 | }
52 |
53 | public void testVersionTakenFromPackageVersion() throws Exception {
54 | Preference preference = getActivity().findPreference("version");
55 | String expectedVersion =
56 | getInstrumentation().getTargetContext().getPackageManager().getPackageInfo(
57 | getActivity().getPackageName(), 0).versionName;
58 | assertEquals(expectedVersion, preference.getSummary());
59 | }
60 |
61 | public void testOpenSourcePreferenceOpensUrl() throws Exception {
62 | Intent intent = tapOnPreferenceAndCatchFiredIntent("opensource");
63 | assertDefaultViewActionIntent(
64 | getInstrumentation().getTargetContext().getString(R.string.opensource_page_url),
65 | intent);
66 | }
67 |
68 | public void testTermsOfServicePreferenceOpensUrl() throws Exception {
69 | Intent intent = tapOnPreferenceAndCatchFiredIntent("terms");
70 | assertDefaultViewActionIntent(
71 | getInstrumentation().getTargetContext().getString(R.string.terms_page_url),
72 | intent);
73 | }
74 |
75 | public void testPrivacyPolicyPreferenceOpensUrl() throws Exception {
76 | Intent intent = tapOnPreferenceAndCatchFiredIntent("privacy");
77 | assertDefaultViewActionIntent(
78 | getInstrumentation().getTargetContext().getString(R.string.privacy_page_url),
79 | intent);
80 | }
81 |
82 | private static void assertDefaultViewActionIntent(String expectedData, Intent intent) {
83 | assertEquals("android.intent.action.VIEW", intent.getAction());
84 | assertEquals(expectedData, intent.getDataString());
85 | }
86 |
87 | private Intent tapOnPreferenceAndCatchFiredIntent(String preferenceKey) {
88 | TestUtilities.tapPreference(this, getActivity(), getActivity().findPreference(preferenceKey));
89 | return TestUtilities.verifyWithTimeoutThatStartActivityAttemptedExactlyOnce();
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/java/com/google/android/apps/authenticator/timesync/NetworkTimeProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator.timesync;
18 |
19 | import android.util.Log;
20 |
21 | import org.apache.http.Header;
22 | import org.apache.http.HttpEntity;
23 | import org.apache.http.HttpResponse;
24 | import org.apache.http.client.ClientProtocolException;
25 | import org.apache.http.client.HttpClient;
26 | import org.apache.http.client.methods.HttpHead;
27 | import org.apache.http.impl.cookie.DateParseException;
28 | import org.apache.http.impl.cookie.DateUtils;
29 |
30 | import java.io.IOException;
31 | import java.util.Date;
32 |
33 | /**
34 | * Provider of network time that obtains the time by making a network request to Google.
35 | *
36 | * @author klyubin@google.com (Alex Klyubin)
37 | */
38 | public class NetworkTimeProvider {
39 |
40 | private static final String LOG_TAG = NetworkTimeProvider.class.getSimpleName();
41 | private static final String URL = "https://www.google.com";
42 |
43 | private final HttpClient mHttpClient;
44 |
45 | public NetworkTimeProvider(HttpClient httpClient) {
46 | mHttpClient = httpClient;
47 | }
48 |
49 | /**
50 | * Gets the system time by issuing a request over the network.
51 | *
52 | * @return time (milliseconds since epoch).
53 | *
54 | * @throws IOException if an I/O error occurs.
55 | */
56 | public long getNetworkTime() throws IOException {
57 | HttpHead request = new HttpHead(URL);
58 | Log.i(LOG_TAG, "Sending request to " + request.getURI());
59 | HttpResponse httpResponse;
60 | try {
61 | httpResponse = mHttpClient.execute(request);
62 | } catch (ClientProtocolException e) {
63 | throw new IOException(String.valueOf(e));
64 | } catch (IOException e) {
65 | throw new IOException("Failed due to connectivity issues: " + e);
66 | }
67 |
68 | try {
69 | Header dateHeader = httpResponse.getLastHeader("Date");
70 | Log.i(LOG_TAG, "Received response with Date header: " + dateHeader);
71 | if (dateHeader == null) {
72 | throw new IOException("No Date header in response");
73 | }
74 | String dateHeaderValue = dateHeader.getValue();
75 | try {
76 | Date networkDate = DateUtils.parseDate(dateHeaderValue);
77 | return networkDate.getTime();
78 | } catch (DateParseException e) {
79 | throw new IOException(
80 | "Invalid Date header format in response: \"" + dateHeaderValue + "\"");
81 | }
82 | } finally {
83 | // Consume all of the content of the response to facilitate HTTP 1.1 persistent connection
84 | // reuse and to avoid running out of connections when this methods is scheduled on different
85 | // threads.
86 | try {
87 | HttpEntity responseEntity = httpResponse.getEntity();
88 | if (responseEntity != null) {
89 | responseEntity.consumeContent();
90 | }
91 | } catch (IOException e) {
92 | // Ignored because this is not an error that is relevant to clients of this transport.
93 | }
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/androidTest/java/com/google/android/apps/authenticator/TotpClockTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.google.android.apps.authenticator;
18 |
19 | import com.google.android.apps.authenticator.testability.DependencyInjector;
20 |
21 | import android.content.SharedPreferences;
22 | import android.preference.PreferenceManager;
23 | import android.test.AndroidTestCase;
24 |
25 | /**
26 | * Unit tests for {@link TotpClock}.
27 | *
28 | * @author klyubin@google.com (Alex Klyubin)
29 | */
30 | public class TotpClockTest extends AndroidTestCase {
31 |
32 | private TotpClock mClock;
33 |
34 | @Override
35 | protected void setUp() throws Exception {
36 | super.setUp();
37 | DependencyInjector.resetForIntegrationTesting(getContext());
38 | mClock = new TotpClock(DependencyInjector.getContext());
39 | }
40 |
41 | @Override
42 | protected void tearDown() throws Exception {
43 | DependencyInjector.close();
44 | super.tearDown();
45 | }
46 |
47 | public void testCurrentTimeMillisUsesCurrentTimeAndTimeCorrection() {
48 | assertEquals(0, mClock.getTimeCorrectionMinutes());
49 |
50 | long millisBefore = System.currentTimeMillis();
51 | long actualMillis = mClock.currentTimeMillis();
52 | long millisAfter = System.currentTimeMillis();
53 | assertInRangeInclusive(actualMillis, millisBefore, millisAfter);
54 |
55 | mClock.setTimeCorrectionMinutes(137);
56 | millisBefore = System.currentTimeMillis();
57 | actualMillis = mClock.currentTimeMillis();
58 | millisAfter = System.currentTimeMillis();
59 | assertInRangeInclusive(
60 | actualMillis,
61 | millisBefore + 137 * Utilities.MINUTE_IN_MILLIS,
62 | millisAfter + 137 * Utilities.MINUTE_IN_MILLIS);
63 | }
64 |
65 | public void testTimeCorrectionBackedByPreferences() {
66 | SharedPreferences preferences =
67 | PreferenceManager.getDefaultSharedPreferences(DependencyInjector.getContext());
68 | assertTrue(preferences.edit().putInt(TotpClock.PREFERENCE_KEY_OFFSET_MINUTES, 7).commit());
69 | assertEquals(7, mClock.getTimeCorrectionMinutes());
70 | mClock.setTimeCorrectionMinutes(42);
71 | assertEquals(42, preferences.getInt(TotpClock.PREFERENCE_KEY_OFFSET_MINUTES, 0));
72 | assertEquals(42, mClock.getTimeCorrectionMinutes());
73 | }
74 |
75 | public void testTimeCorrectionCaching() {
76 | // Check that the preference is only read first time the the time correction value is requested
77 | SharedPreferences preferences =
78 | PreferenceManager.getDefaultSharedPreferences(DependencyInjector.getContext());
79 | assertTrue(preferences.edit().putInt(TotpClock.PREFERENCE_KEY_OFFSET_MINUTES, 7).commit());
80 | assertEquals(7, mClock.getTimeCorrectionMinutes());
81 | assertTrue(preferences.edit().putInt(TotpClock.PREFERENCE_KEY_OFFSET_MINUTES, 42).commit());
82 | assertEquals(7, mClock.getTimeCorrectionMinutes());
83 | }
84 |
85 | private static void assertInRangeInclusive(
86 | long actual, long expectedMinValue, long expectedMaxValue) {
87 | if ((actual < expectedMinValue) || (actual > expectedMaxValue)) {
88 | fail(actual + " not in [" + expectedMinValue + ", " + expectedMaxValue + "]");
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/AuthenticatorApp/src/main/res/values-ar/timesync_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
19 | "التصحيح الزمني للرموز"
20 | "مزامنة الساعة الداخلية لأداة المصادقة مع خوادم Google"
21 | "مزامنة الآن"
22 | "حول هذه الميزة"
23 | "حول هذه الميزة"
24 | "في حالة الضغط على "مزامنة الآن"، فستحاول أداة المصادقة مزامنة ساعتها الداخلية مع خوادم Google مرة واحدة. ولن يتم تغيير إعدادات \"التاريخ والوقت\" على الجهاز. <p> لا تنقل أداة المصادقة أية معلومات شخصية أو أي من معلومات الحساب أثناء مزامنة الساعة الداخلية مع خوادم Google. <p> <b>ما اوجه الاستفادة من هذا</b> <p> تنشئ أداة المصادقة رموز التحقق بخطوتين بناءً على 1) الوقت الحالي و2) رقم سري معروف للتطبيق والخادم. <p> وفي حالة عدم توافق أداة المصادقة والخادم على الوقت، فإن الرموز التي ينشئها التطبيق ربما لا يتم قبولها عند محاولة تسجيل الدخول. <p> تستخدم أداة المصادقة افتراضيًا إعدادات \"التاريخ والوقت\" على الجهاز، وفي معظم الحالات ستتمكن من إنشاء رموز صالحة من خلال التأكد من تهيئة إعدادات الوقت والتاريخ والمنطقة الزمنية بشكل صحيح. ومع ذلك، عندما يحدث عدم تطابق الوقت، فربما يكون من الصعب تحرّي الخلل وإصلاحه (خاصة إذا كنت تستخدم الوقت أو المناطق الزمنية التي توفرها الشبكة)."
25 | "مزامنة الآن"
26 | "مزامنة الآن"
27 | "جارٍ الاتصال بالخادم..."
28 | "تم تصحيح الوقت"
29 | "تم ضبط الساعة الداخلية لأداة المزامنة لتطابق الوقت الذي توفره خوادم Google. "\n\n"لم يتم تغيير إعدادات \"الوقت والتاريخ\" على هذا الجهاز."
30 | "الوقت صحيح فعلاً"
31 | "لم يتم ضبط الساعة الداخلية لأداة المصادقة نظرًا لأنها تتم مزامنتها مع خوادم Google فعلاً."
32 | "مزامنة الآن"
33 | "حدثت مشكلة أثناء الاتصال بخادم Google. الرجاء التحقق من إعدادات الشبكة وإعادة المحاولة."
34 |
35 |
--------------------------------------------------------------------------------