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
17package com.android.settings.fingerprint;
18
19
20import static com.google.common.truth.Truth.assertThat;
21
22import static org.robolectric.RuntimeEnvironment.application;
23
24import android.app.KeyguardManager;
25import android.content.Intent;
26import android.content.pm.PackageManager;
27import android.content.pm.UserInfo;
28import android.view.View;
29import android.widget.Button;
30
31import com.android.settings.R;
32import com.android.settings.TestConfig;
33import com.android.settings.fingerprint.SetupFingerprintEnrollIntroductionTest
34        .ShadowStorageManagerWrapper;
35import com.android.settings.password.SetupChooseLockGeneric.SetupChooseLockGenericFragment;
36import com.android.settings.password.SetupSkipDialog;
37import com.android.settings.password.StorageManagerWrapper;
38import com.android.settings.testutils.SettingsRobolectricTestRunner;
39import com.android.settings.testutils.shadow.ShadowEventLogWriter;
40import com.android.settings.testutils.shadow.ShadowFingerprintManager;
41import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
42import com.android.settings.testutils.shadow.ShadowUserManager;
43
44import org.junit.After;
45import org.junit.Before;
46import org.junit.Test;
47import org.junit.runner.RunWith;
48import org.mockito.Mock;
49import org.mockito.MockitoAnnotations;
50import org.robolectric.Robolectric;
51import org.robolectric.RuntimeEnvironment;
52import org.robolectric.Shadows;
53import org.robolectric.annotation.Config;
54import org.robolectric.annotation.Implementation;
55import org.robolectric.annotation.Implements;
56import org.robolectric.shadows.ShadowActivity;
57import org.robolectric.shadows.ShadowActivity.IntentForResult;
58import org.robolectric.shadows.ShadowKeyguardManager;
59import org.robolectric.util.ActivityController;
60
61@RunWith(SettingsRobolectricTestRunner.class)
62@Config(
63        manifest = TestConfig.MANIFEST_PATH,
64        sdk = TestConfig.SDK_VERSION,
65        shadows = {
66                ShadowEventLogWriter.class,
67                ShadowFingerprintManager.class,
68                ShadowLockPatternUtils.class,
69                ShadowStorageManagerWrapper.class,
70                ShadowUserManager.class
71        })
72public class SetupFingerprintEnrollIntroductionTest {
73
74    @Mock
75    private UserInfo mUserInfo;
76
77    private ActivityController<SetupFingerprintEnrollIntroduction> mController;
78
79    @Before
80    public void setUp() {
81        MockitoAnnotations.initMocks(this);
82
83        RuntimeEnvironment.getRobolectricPackageManager()
84                .setSystemFeature(PackageManager.FEATURE_FINGERPRINT, true);
85        ShadowFingerprintManager.addToServiceMap();
86
87        final Intent intent = new Intent();
88        mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent);
89
90        ShadowUserManager.getShadow().setUserInfo(0, mUserInfo);
91    }
92
93    @After
94    public void tearDown() {
95        ShadowStorageManagerWrapper.reset();
96        ShadowFingerprintManager.reset();
97    }
98
99    @Test
100    public void testKeyguardNotSecure_shouldFinishWithSetupSkipDialogResultSkip() {
101        getShadowKeyguardManager().setIsKeyguardSecure(false);
102
103        mController.create().resume();
104
105        final Button skipButton = mController.get().findViewById(R.id.fingerprint_cancel_button);
106        assertThat(skipButton.getVisibility()).named("Skip visible").isEqualTo(View.VISIBLE);
107        skipButton.performClick();
108
109        ShadowActivity shadowActivity = Shadows.shadowOf(mController.get());
110        assertThat(mController.get().isFinishing()).named("Is finishing").isTrue();
111        assertThat(shadowActivity.getResultCode()).named("Result code")
112                .isEqualTo(SetupSkipDialog.RESULT_SKIP);
113    }
114
115    @Test
116    public void testKeyguardSecure_shouldFinishWithFingerprintResultSkip() {
117        getShadowKeyguardManager().setIsKeyguardSecure(true);
118
119        mController.create().resume();
120
121        final Button skipButton = mController.get().findViewById(R.id.fingerprint_cancel_button);
122        assertThat(skipButton.getVisibility()).named("Skip visible").isEqualTo(View.VISIBLE);
123        skipButton.performClick();
124
125        ShadowActivity shadowActivity = Shadows.shadowOf(mController.get());
126        assertThat(mController.get().isFinishing()).named("Is finishing").isTrue();
127        assertThat(shadowActivity.getResultCode()).named("Result code")
128                .isEqualTo(FingerprintEnrollBase.RESULT_SKIP);
129    }
130
131    @Test
132    public void testBackKeyPress_shouldSetIntentDataIfLockScreenAdded() {
133        getShadowKeyguardManager().setIsKeyguardSecure(false);
134
135        mController.create().resume();
136        getShadowKeyguardManager().setIsKeyguardSecure(true);
137        SetupFingerprintEnrollIntroduction activity = mController.get();
138        activity.onBackPressed();
139
140        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
141        assertThat(shadowActivity.getResultIntent()).isNotNull();
142        assertThat(shadowActivity.getResultIntent().hasExtra(
143                SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isTrue();
144    }
145
146    @Test
147    public void testBackKeyPress_shouldNotSetIntentDataIfLockScreenPresentBeforeLaunch() {
148        getShadowKeyguardManager().setIsKeyguardSecure(true);
149
150        mController.create().resume();
151        SetupFingerprintEnrollIntroduction activity = mController.get();
152        activity.onBackPressed();
153
154        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
155        assertThat(shadowActivity.getResultIntent()).isNull();
156    }
157
158    @Test
159    public void testCancelClicked_shouldSetIntentDataIfLockScreenAdded() {
160        getShadowKeyguardManager().setIsKeyguardSecure(false);
161
162        SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
163        final Button skipButton = activity.findViewById(R.id.fingerprint_cancel_button);
164        getShadowKeyguardManager().setIsKeyguardSecure(true);
165        skipButton.performClick();
166
167        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
168        assertThat(shadowActivity.getResultIntent()).isNotNull();
169        assertThat(shadowActivity.getResultIntent().hasExtra(
170                SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isTrue();
171    }
172
173    @Test
174    public void testCancelClicked_shouldNotSetIntentDataIfLockScreenPresentBeforeLaunch() {
175        getShadowKeyguardManager().setIsKeyguardSecure(true);
176
177        SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
178        final Button skipButton = activity.findViewById(R.id.fingerprint_cancel_button);
179        skipButton.performClick();
180
181        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
182        assertThat(shadowActivity.getResultIntent()).isNull();
183    }
184
185    @Test
186    public void testOnResultFromFindSensor_shouldNotSetIntentDataIfLockScreenPresentBeforeLaunch() {
187        getShadowKeyguardManager().setIsKeyguardSecure(true);
188        SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
189        activity.onActivityResult(FingerprintEnrollIntroduction.FINGERPRINT_FIND_SENSOR_REQUEST,
190                FingerprintEnrollBase.RESULT_FINISHED, null);
191        assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull();
192    }
193
194    @Test
195    public void testOnResultFromFindSensor_shouldSetIntentDataIfLockScreenAdded() {
196        getShadowKeyguardManager().setIsKeyguardSecure(false);
197        SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
198        getShadowKeyguardManager().setIsKeyguardSecure(true);
199        activity.onActivityResult(FingerprintEnrollIntroduction.FINGERPRINT_FIND_SENSOR_REQUEST,
200                FingerprintEnrollBase.RESULT_FINISHED, null);
201        assertThat(Shadows.shadowOf(activity).getResultIntent()).isNotNull();
202    }
203
204    @Test
205    public void testOnResultFromFindSensor_shouldNotSetIntentDataIfLockScreenNotAdded() {
206        getShadowKeyguardManager().setIsKeyguardSecure(false);
207        SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
208        activity.onActivityResult(FingerprintEnrollIntroduction.FINGERPRINT_FIND_SENSOR_REQUEST,
209                FingerprintEnrollBase.RESULT_FINISHED, null);
210        assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull();
211    }
212
213    @Test
214    public void testLockPattern() {
215        ShadowStorageManagerWrapper.sIsFileEncrypted = false;
216
217        mController.create().postCreate(null).resume();
218
219        SetupFingerprintEnrollIntroduction activity = mController.get();
220
221        final Button nextButton = activity.findViewById(R.id.fingerprint_next_button);
222        nextButton.performClick();
223
224        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
225        IntentForResult startedActivity = shadowActivity.getNextStartedActivityForResult();
226        assertThat(startedActivity).isNotNull();
227        assertThat(startedActivity.intent.hasExtra(
228                SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isFalse();
229    }
230
231
232    private ShadowKeyguardManager getShadowKeyguardManager() {
233        return Shadows.shadowOf(application.getSystemService(KeyguardManager.class));
234    }
235
236    @Implements(StorageManagerWrapper.class)
237    public static class ShadowStorageManagerWrapper {
238
239        private static boolean sIsFileEncrypted = true;
240
241        public static void reset() {
242            sIsFileEncrypted = true;
243        }
244
245        @Implementation
246        public static boolean isFileEncryptedNativeOrEmulated() {
247            return sIsFileEncrypted;
248        }
249    }
250}
251