2 * Copyright (C) 2017 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings;
19 import android.app.Activity;
20 import android.app.admin.DevicePolicyManager;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.support.test.filters.MediumTest;
25 import android.support.test.rule.ActivityTestRule;
26 import android.support.test.runner.AndroidJUnit4;
27 import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
28 import android.support.test.runner.lifecycle.Stage;
29 import android.support.test.uiautomator.UiDevice;
30 import android.support.test.uiautomator.UiObject;
31 import android.support.test.uiautomator.UiSelector;
33 import android.text.format.DateUtils;
34 import android.view.KeyEvent;
36 import com.android.settings.R;
38 import java.util.Collection;
40 import org.junit.After;
41 import org.junit.Assert;
42 import org.junit.Before;
43 import org.junit.Rule;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
47 import static android.support.test.InstrumentationRegistry.getInstrumentation;
48 import static com.google.common.truth.Truth.assertThat;
49 import static org.junit.Assert.assertTrue;
52 * Tests for {@link ChooseLockGenericTest}
56 * -r -g ${ANDROID_PRODUCT_OUT}/data/app/SettingsTests/SettingsTests.apk &&
57 * adb shell am instrument -e class com.android.settings.ChooseLockGenericTest \
58 * -w com.android.settings.tests/android.support.test.runner.AndroidJUnitRunner
60 @RunWith(AndroidJUnit4.class)
62 public class ChooseLockGenericTest {
63 private static final long TIMEOUT = 5 * DateUtils.SECOND_IN_MILLIS;
64 private static final Intent PHISHING_ATTACK_INTENT = new Intent()
65 .putExtra("confirm_credentials", false)
66 .putExtra("password_confirmed", true);
68 private UiDevice mDevice;
69 private Context mTargetContext;
70 private String mSettingPackage;
71 private PackageManager mPackageManager;
73 public ActivityTestRule<ChooseLockGeneric> mChooseLockGenericActivityRule =
74 new ActivityTestRule<>(
75 ChooseLockGeneric.class,
76 true /* enable touch at launch */,
77 false /* don't launch at every test */);
80 public void setUp() throws Exception {
81 mDevice = UiDevice.getInstance(getInstrumentation());
82 mTargetContext = getInstrumentation().getTargetContext();
83 mSettingPackage = mTargetContext.getPackageName();
84 mPackageManager = mTargetContext.getPackageManager();
90 public void tearDown() throws Exception {
95 public void testConfirmLockPasswordShown_deviceWithPassword() throws Exception, Throwable {
96 // GIVEN a PIN password is set on this device at set up.
97 // WHEN ChooseLockGeneric is launched with no extras.
98 mChooseLockGenericActivityRule.launchActivity(null /* No extras */);
99 // THEN ConfirmLockPassword.InternalActivity is shown.
100 assertThat(getCurrentActivity()).isInstanceOf(ConfirmLockPassword.InternalActivity.class);
104 public void testConfirmLockPasswordShown_deviceWithPassword_phishingAttack()
105 throws Exception, Throwable {
106 // GIVEN a PIN password is set on this device at set up.
107 // WHEN ChooseLockGeneric is launched with extras to by-pass lock password confirmation.
108 mChooseLockGenericActivityRule.launchActivity(PHISHING_ATTACK_INTENT);
109 // THEN ConfirmLockPassword.InternalActivity is still shown.
110 assertThat(getCurrentActivity()).isInstanceOf(ConfirmLockPassword.InternalActivity.class);
113 private Activity getCurrentActivity() throws Throwable {
114 getInstrumentation().waitForIdleSync();
115 final Activity[] activity = new Activity[1];
116 getInstrumentation().runOnMainSync(new Runnable() {
119 Collection<Activity> activities = ActivityLifecycleMonitorRegistry.getInstance()
120 .getActivitiesInStage(Stage.RESUMED);
121 activity[0] = activities.iterator().next();
127 private void launchNewPassword() throws Exception {
128 Intent newPasswordIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD)
129 .setPackage(mSettingPackage)
130 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
131 getInstrumentation().getContext().startActivity(newPasswordIntent);
132 mDevice.waitForIdle();
135 /** Sets a PIN password, 12345, for testing. */
136 private void setPassword() throws Exception {
139 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
140 // Set "lock_none", but it actually means we don't want to enroll a fingerprint.
141 UiObject view = new UiObject(
142 new UiSelector().resourceId(mSettingPackage + ":id/lock_none"));
143 assertTrue("lock_none", view.waitForExists(TIMEOUT));
145 mDevice.waitForIdle();
148 // Pick PIN from the option list
149 UiObject view = new UiObject(new UiSelector()
150 .resourceId(mSettingPackage + ":id/lock_pin"));
151 assertTrue("lock_pin", view.waitForExists(TIMEOUT));
153 mDevice.waitForIdle();
155 // Ignore any interstitial options
156 view = new UiObject(new UiSelector()
157 .resourceId(mSettingPackage + ":id/encrypt_dont_require_password"));
158 if (view.waitForExists(TIMEOUT)) {
160 mDevice.waitForIdle();
163 // Yes, we really want to
164 view = new UiObject(new UiSelector()
165 .resourceId(mSettingPackage + ":id/next_button"));
166 if (view.waitForExists(TIMEOUT)) {
168 mDevice.waitForIdle();
172 view = new UiObject(new UiSelector()
173 .resourceId(mSettingPackage + ":id/password_entry"));
174 assertTrue("password_entry", view.waitForExists(TIMEOUT));
176 // Enter it twice to confirm
183 /** Clears the previous set PIN password. */
184 private void clearPassword() throws Exception {
188 UiObject view = new UiObject(
189 new UiSelector().resourceId(mSettingPackage + ":id/password_entry"));
190 if (!view.waitForExists(TIMEOUT)) {
191 // Odd, maybe there is a crash dialog showing; try dismissing it
193 mDevice.waitForIdle();
195 assertTrue("password_entry", view.waitForExists(TIMEOUT));
200 // Set back to "none"
201 view = new UiObject(new UiSelector().resourceId(mSettingPackage + ":id/lock_none"));
202 assertTrue("lock_none", view.waitForExists(TIMEOUT));
204 mDevice.waitForIdle();
206 // Yes, we really want "none" if prompted again
207 view = new UiObject(new UiSelector().resourceId(mSettingPackage + ":id/lock_none"));
208 if (view.waitForExists(TIMEOUT)) {
210 mDevice.waitForIdle();
213 // Yes, we really want to
214 view = new UiObject(new UiSelector()
215 .resourceId("android:id/button1"));
216 if (view.waitForExists(TIMEOUT)) {
218 mDevice.waitForIdle();
224 private void enterTestPin() throws Exception {
225 mDevice.waitForIdle();
226 mDevice.pressKeyCode(KeyEvent.KEYCODE_1);
227 mDevice.pressKeyCode(KeyEvent.KEYCODE_2);
228 mDevice.pressKeyCode(KeyEvent.KEYCODE_3);
229 mDevice.pressKeyCode(KeyEvent.KEYCODE_4);
230 mDevice.pressKeyCode(KeyEvent.KEYCODE_5);
231 mDevice.waitForIdle();
232 mDevice.pressEnter();
233 mDevice.waitForIdle();