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.password; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static com.google.common.truth.Truth.assertWithMessage; 21 22 import static org.robolectric.RuntimeEnvironment.application; 23 24 import android.content.ComponentName; 25 import android.content.Intent; 26 import android.content.pm.PackageManager; 27 import android.os.UserHandle; 28 import android.view.View; 29 import android.widget.Button; 30 31 import androidx.appcompat.app.AlertDialog; 32 import androidx.fragment.app.FragmentActivity; 33 34 import com.android.internal.widget.LockPatternView; 35 import com.android.internal.widget.LockPatternView.Cell; 36 import com.android.internal.widget.LockPatternView.DisplayMode; 37 import com.android.settings.R; 38 import com.android.settings.SetupRedactionInterstitial; 39 import com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment; 40 import com.android.settings.password.ChooseLockPattern.IntentBuilder; 41 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; 42 import com.android.settings.testutils.shadow.ShadowLockPatternUtils; 43 import com.android.settings.testutils.shadow.ShadowUtils; 44 45 import com.google.android.setupcompat.PartnerCustomizationLayout; 46 import com.google.android.setupcompat.template.FooterBarMixin; 47 48 import org.junit.Before; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 import org.robolectric.RobolectricTestRunner; 52 import org.robolectric.Shadows; 53 import org.robolectric.android.controller.ActivityController; 54 import org.robolectric.annotation.Config; 55 import org.robolectric.shadows.ShadowPackageManager; 56 import org.robolectric.util.ReflectionHelpers; 57 import org.robolectric.util.ReflectionHelpers.ClassParameter; 58 59 import java.util.Arrays; 60 61 @RunWith(RobolectricTestRunner.class) 62 @Config(shadows = {ShadowUtils.class, ShadowAlertDialogCompat.class, ShadowLockPatternUtils.class}) 63 public class SetupChooseLockPatternTest { 64 65 private SetupChooseLockPattern mActivity; 66 67 @Before setUp()68 public void setUp() { 69 application.getPackageManager().setComponentEnabledSetting( 70 new ComponentName(application, SetupRedactionInterstitial.class), 71 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 72 PackageManager.DONT_KILL_APP); 73 74 final Intent intent = 75 SetupChooseLockPattern.modifyIntentForSetup( 76 application, 77 new IntentBuilder(application) 78 .setUserId(UserHandle.myUserId()) 79 .build()); 80 mActivity = ActivityController.of(new SetupChooseLockPattern(), intent).setup().get(); 81 } 82 83 @Test chooseLockSaved_shouldEnableRedactionInterstitial()84 public void chooseLockSaved_shouldEnableRedactionInterstitial() { 85 findFragment(mActivity).onChosenLockSaveFinished(false, null); 86 87 ShadowPackageManager spm = Shadows.shadowOf(application.getPackageManager()); 88 ComponentName cname = new ComponentName(application, SetupRedactionInterstitial.class); 89 final int componentEnabled = spm.getComponentEnabledSettingFlags(cname) 90 & PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 91 assertThat(componentEnabled).isEqualTo(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 92 } 93 94 @Test optionsButton_whenPatternSelected_shouldBeVisible()95 public void optionsButton_whenPatternSelected_shouldBeVisible() { 96 Button button = mActivity.findViewById(R.id.screen_lock_options); 97 assertThat(button).isNotNull(); 98 assertThat(button.getVisibility()).isEqualTo(View.VISIBLE); 99 100 LockPatternView lockPatternView = mActivity.findViewById(R.id.lockPattern); 101 ReflectionHelpers.callInstanceMethod(lockPatternView, "notifyPatternDetected"); 102 103 enterPattern(); 104 assertThat(button.getVisibility()).isEqualTo(View.VISIBLE); 105 } 106 verifyScreenLockOptionsShown()107 private void verifyScreenLockOptionsShown() { 108 Button button = mActivity.findViewById(R.id.screen_lock_options); 109 assertThat(button).isNotNull(); 110 assertThat(button.getVisibility()).isEqualTo(View.VISIBLE); 111 112 button.performClick(); 113 AlertDialog chooserDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); 114 assertThat(chooserDialog).isNotNull(); 115 int count = chooserDialog.getListView().getCount(); 116 assertWithMessage("List items shown").that(count).isEqualTo(3); 117 } 118 119 @Config(qualifiers = "sw400dp") 120 @Test sw400dp_shouldShowScreenLockOptions()121 public void sw400dp_shouldShowScreenLockOptions() { 122 verifyScreenLockOptionsShown(); 123 } 124 125 @Config(qualifiers = "sw400dp-land") 126 @Test sw400dpLandscape_shouldShowScreenLockOptions()127 public void sw400dpLandscape_shouldShowScreenLockOptions() { 128 verifyScreenLockOptionsShown(); 129 } 130 verifyScreenLockOptionsHidden()131 private void verifyScreenLockOptionsHidden() { 132 Button button = mActivity.findViewById(R.id.screen_lock_options); 133 assertThat(button).isNotNull(); 134 assertThat(button.getVisibility()).isEqualTo(View.GONE); 135 } 136 137 @Config(qualifiers = "sw300dp") 138 @Test smallScreens_shouldHideScreenLockOptions()139 public void smallScreens_shouldHideScreenLockOptions() { 140 verifyScreenLockOptionsHidden(); 141 } 142 143 @Config(qualifiers = "sw300dp-land") 144 @Test smallScreensLandscape_shouldHideScreenLockOptions()145 public void smallScreensLandscape_shouldHideScreenLockOptions() { 146 verifyScreenLockOptionsHidden(); 147 } 148 149 @Test skipButton_shouldBeVisible_duringNonFingerprintFlow()150 public void skipButton_shouldBeVisible_duringNonFingerprintFlow() { 151 PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout); 152 final Button skipOrClearButton = 153 layout.getMixin(FooterBarMixin.class).getSecondaryButtonView(); 154 assertThat(skipOrClearButton).isNotNull(); 155 assertThat(skipOrClearButton.getVisibility()).isEqualTo(View.VISIBLE); 156 157 skipOrClearButton.performClick(); 158 AlertDialog chooserDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); 159 assertThat(chooserDialog).isNotNull(); 160 } 161 162 @Test clearButton_shouldBeVisible_duringRetryStage()163 public void clearButton_shouldBeVisible_duringRetryStage() { 164 enterPattern(); 165 166 PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout); 167 final Button skipOrClearButton = 168 layout.getMixin(FooterBarMixin.class).getSecondaryButtonView(); 169 assertThat(skipOrClearButton.getVisibility()).isEqualTo(View.VISIBLE); 170 assertThat(skipOrClearButton.isEnabled()).isTrue(); 171 172 skipOrClearButton.performClick(); 173 assertThat(findFragment(mActivity).mChosenPattern).isNull(); 174 } 175 176 @Test createActivity_enterPattern_clearButtonShouldBeShown()177 public void createActivity_enterPattern_clearButtonShouldBeShown() { 178 ChooseLockPatternFragment fragment = findFragment(mActivity); 179 180 PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout); 181 final Button skipOrClearButton = 182 layout.getMixin(FooterBarMixin.class).getSecondaryButtonView(); 183 assertThat(skipOrClearButton.isEnabled()).isTrue(); 184 assertThat(skipOrClearButton.getVisibility()).isEqualTo(View.VISIBLE); 185 assertThat(skipOrClearButton.getText()) 186 .isEqualTo(application.getString(R.string.skip_label)); 187 188 enterPattern(); 189 assertThat(skipOrClearButton.isEnabled()).isTrue(); 190 assertThat(skipOrClearButton.getVisibility()).isEqualTo(View.VISIBLE); 191 assertThat(skipOrClearButton.getText()) 192 .isEqualTo(application.getString(R.string.lockpattern_retry_button_text)); 193 } 194 findFragment(FragmentActivity activity)195 private ChooseLockPatternFragment findFragment(FragmentActivity activity) { 196 return (ChooseLockPatternFragment) 197 activity.getSupportFragmentManager().findFragmentById(R.id.main_content); 198 } 199 enterPattern()200 private void enterPattern() { 201 LockPatternView lockPatternView = mActivity.findViewById(R.id.lockPattern); 202 lockPatternView.setPattern( 203 DisplayMode.Animate, 204 Arrays.asList( 205 createCell(0, 0), 206 createCell(0, 1), 207 createCell(1, 1), 208 createCell(1, 0))); 209 ReflectionHelpers.callInstanceMethod(lockPatternView, "notifyPatternDetected"); 210 } 211 createCell(int row, int column)212 private Cell createCell(int row, int column) { 213 return ReflectionHelpers.callConstructor( 214 Cell.class, 215 ClassParameter.from(int.class, row), 216 ClassParameter.from(int.class, column)); 217 } 218 } 219