• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 com.android.settings;
18 
19 import static android.support.test.InstrumentationRegistry.getInstrumentation;
20 import static android.support.test.InstrumentationRegistry.getTargetContext;
21 
22 import static com.google.common.truth.Truth.assertThat;
23 
24 import static org.junit.Assert.assertTrue;
25 
26 import android.app.Activity;
27 import android.app.ActivityManager;
28 import android.app.ActivityManager.AppTask;
29 import android.app.KeyguardManager;
30 import android.app.admin.DevicePolicyManager;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.support.test.filters.MediumTest;
34 import android.support.test.rule.ActivityTestRule;
35 import android.support.test.runner.AndroidJUnit4;
36 import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
37 import android.support.test.runner.lifecycle.Stage;
38 import android.support.test.uiautomator.UiDevice;
39 import android.support.test.uiautomator.UiObject;
40 import android.support.test.uiautomator.UiSelector;
41 import android.text.format.DateUtils;
42 
43 import com.android.internal.widget.LockPatternUtils;
44 
45 import org.junit.Before;
46 import org.junit.Rule;
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 
50 import java.util.Collection;
51 import java.util.List;
52 
53 /**
54  * Tests for {@link ChooseLockGenericTest}
55  *
56  * m SettingsTests &&
57  * adb install \
58  * -r -g  ${ANDROID_PRODUCT_OUT}/data/app/SettingsTests/SettingsTests.apk &&
59  * adb shell am instrument -e class com.android.settings.ChooseLockGenericTest \
60  * -w com.android.settings.tests/android.support.test.runner.AndroidJUnitRunner
61  */
62 @RunWith(AndroidJUnit4.class)
63 @MediumTest
64 public class ChooseLockGenericTest {
65     private static final long TIMEOUT = 5 * DateUtils.SECOND_IN_MILLIS;
66     private static final Intent PHISHING_ATTACK_INTENT = new Intent()
67             .putExtra("confirm_credentials", false)
68             .putExtra("password_confirmed", true);
69 
70     private UiDevice mDevice;
71     private Context mTargetContext;
72     private String mSettingPackage;
73 
74     @Rule
75     public ActivityTestRule<ChooseLockGeneric> mChooseLockGenericActivityRule =
76             new ActivityTestRule<>(
77                     ChooseLockGeneric.class,
78                     true /* enable touch at launch */,
79                     false /* don't launch at every test */);
80 
81     @Before
setUp()82     public void setUp() throws Exception {
83         mDevice = UiDevice.getInstance(getInstrumentation());
84         mTargetContext = getInstrumentation().getTargetContext();
85         mSettingPackage = mTargetContext.getPackageName();
86     }
87 
88     @Test
testConfirmLockPasswordShown_deviceWithPassword()89     public void testConfirmLockPasswordShown_deviceWithPassword() throws Throwable {
90         setPassword();
91         try {
92             // GIVEN a PIN password is set on this device at set up.
93             // WHEN ChooseLockGeneric is launched with no extras.
94             mChooseLockGenericActivityRule.launchActivity(null /* No extras */);
95             // THEN ConfirmLockPassword.InternalActivity is shown.
96             assertThat(getCurrentActivity())
97                     .isInstanceOf(ConfirmLockPassword.InternalActivity.class);
98         } finally {
99             finishAllAppTasks();
100             mDevice.waitForIdle();
101             clearPassword();
102         }
103     }
104 
105     @Test
testConfirmLockPasswordShown_deviceWithPassword_phishingAttack()106     public void testConfirmLockPasswordShown_deviceWithPassword_phishingAttack() throws Throwable {
107         setPassword();
108         try {
109             // GIVEN a PIN password is set on this device at set up.
110             // WHEN ChooseLockGeneric is launched with extras to by-pass lock password confirmation.
111             mChooseLockGenericActivityRule.launchActivity(PHISHING_ATTACK_INTENT);
112             // THEN ConfirmLockPassword.InternalActivity is still shown.
113             assertThat(getCurrentActivity())
114                     .isInstanceOf(ConfirmLockPassword.InternalActivity.class);
115         } finally {
116             finishAllAppTasks();
117             mDevice.waitForIdle();
118             clearPassword();
119         }
120     }
121 
122     @Test
testForFingerprint_inflateLayout()123     public void testForFingerprint_inflateLayout() {
124         mChooseLockGenericActivityRule.launchActivity(new Intent()
125                 .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true));
126 
127         assertThat(mChooseLockGenericActivityRule.getActivity().isResumed()).isTrue();
128     }
129 
getCurrentActivity()130     private Activity getCurrentActivity() throws Throwable {
131         getInstrumentation().waitForIdleSync();
132         final Activity[] activity = new Activity[1];
133         getInstrumentation().runOnMainSync(() -> {
134             Collection<Activity> activities = ActivityLifecycleMonitorRegistry.getInstance()
135                     .getActivitiesInStage(Stage.RESUMED);
136             activity[0] = activities.iterator().next();
137         });
138         return activity[0];
139     }
140 
141     /** Sets a PIN password, 12345, for testing. */
setPassword()142     private void setPassword() throws Exception {
143         Intent newPasswordIntent = new Intent(getTargetContext(), ChooseLockGeneric.class)
144                 .putExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
145                         DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
146                 .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
147                         "12345")
148                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
149         getInstrumentation().getContext().startActivity(newPasswordIntent);
150         mDevice.waitForIdle();
151 
152 
153         // Ignore any interstitial options
154         UiObject view = new UiObject(new UiSelector()
155                 .resourceId(mSettingPackage + ":id/encrypt_dont_require_password"));
156         if (view.waitForExists(TIMEOUT)) {
157             view.click();
158             mDevice.waitForIdle();
159         }
160 
161         // Set our PIN
162         view = new UiObject(new UiSelector()
163                 .resourceId(mSettingPackage + ":id/password_entry"));
164         assertTrue("password_entry", view.waitForExists(TIMEOUT));
165 
166         // Enter it twice to confirm
167         enterTestPin(view);
168         enterTestPin(view);
169 
170         mDevice.pressBack();
171 
172         assertThat(getTargetContext().getSystemService(KeyguardManager.class).isDeviceSecure())
173                 .isTrue();
174     }
175 
176     /** Clears the previous set PIN password. */
clearPassword()177     private void clearPassword() throws Exception {
178         Intent newPasswordIntent = new Intent(getTargetContext(), ChooseLockGeneric.class)
179                 .putExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
180                         DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)
181                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
182                         | Intent.FLAG_ACTIVITY_CLEAR_TASK);
183         getInstrumentation().getContext().startActivity(newPasswordIntent);
184         mDevice.waitForIdle();
185 
186         // Enter current PIN
187         UiObject view = new UiObject(
188                 new UiSelector().resourceId(mSettingPackage + ":id/password_entry"));
189         if (!view.waitForExists(TIMEOUT)) {
190             // Odd, maybe there is a crash dialog showing; try dismissing it
191             mDevice.pressBack();
192             mDevice.waitForIdle();
193 
194             assertTrue("password_entry", view.waitForExists(TIMEOUT));
195         }
196 
197         enterTestPin(view);
198 
199         mDevice.pressBack();
200 
201         assertThat(getTargetContext().getSystemService(KeyguardManager.class).isDeviceSecure())
202                 .isFalse();
203     }
204 
finishAllAppTasks()205     private void finishAllAppTasks() {
206         final ActivityManager activityManager =
207                 getTargetContext().getSystemService(ActivityManager.class);
208         final List<AppTask> appTasks = activityManager.getAppTasks();
209         for (ActivityManager.AppTask task : appTasks) {
210             task.finishAndRemoveTask();
211         }
212     }
213 
enterTestPin(UiObject view)214     private void enterTestPin(UiObject view) throws Exception {
215         mDevice.waitForIdle();
216         view.setText("12345");
217         mDevice.pressEnter();
218         mDevice.waitForIdle();
219     }
220 }
221