Allow skipping PIN setup screen

So that setup wizard can show PIN option by default.

Test: Added Robolectric and instrumentation tests
Bug: 38509560
Change-Id: Id72744dd444b9b026ca5f28f230bae3bec254b2f
(cherry picked from commit 0f897d79f698920f1c0e0c102a7985704ffa196e)
diff --git a/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java b/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java
index 26b3427..e668812 100644
--- a/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroduction.java
@@ -28,9 +28,9 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
 import com.android.settings.SetupWizardUtils;
-import com.android.settings.password.ChooseLockGeneric;
 import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
 import com.android.settings.password.SetupChooseLockGeneric;
+import com.android.settings.password.SetupSkipDialog;
 
 public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction {
 
@@ -98,9 +98,8 @@
             setResult(RESULT_SKIP);
             finish();
         } else {
-            SetupSkipDialog dialog = SetupSkipDialog.newInstance(
-                    getIntent().getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
-            dialog.show(getFragmentManager());
+            setResult(SetupSkipDialog.RESULT_SKIP);
+            finish();
         }
     }
 
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index d4bc076..b41a40f 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -201,7 +201,7 @@
         private String mFirstPin;
         private RecyclerView mPasswordRestrictionView;
         protected boolean mIsAlphaMode;
-        private Button mCancelButton;
+        protected Button mCancelButton;
         private Button mNextButton;
 
         private TextChangedHandler mTextChangedHandler;
diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java
index 4e73b87..179bd79 100644
--- a/src/com/android/settings/password/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/password/SetupChooseLockGeneric.java
@@ -35,7 +35,6 @@
 import com.android.settings.SetupEncryptionInterstitial;
 import com.android.settings.SetupWizardUtils;
 import com.android.settings.fingerprint.SetupFingerprintEnrollFindSensor;
-import com.android.settings.fingerprint.SetupSkipDialog;
 import com.android.settings.utils.SettingsDividerItemDecoration;
 import com.android.setupwizardlib.GlifPreferenceLayout;
 
diff --git a/src/com/android/settings/password/SetupChooseLockPassword.java b/src/com/android/settings/password/SetupChooseLockPassword.java
index 0c62c7c..bd935a2 100644
--- a/src/com/android/settings/password/SetupChooseLockPassword.java
+++ b/src/com/android/settings/password/SetupChooseLockPassword.java
@@ -84,6 +84,9 @@
         @Override
         public void onViewCreated(View view, Bundle savedInstanceState) {
             super.onViewCreated(view, savedInstanceState);
+
+            mCancelButton.setText(R.string.skip_label);
+
             boolean showOptionsButton = getActivity().getIntent().getBooleanExtra(
                     ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, false);
             if (showOptionsButton) {
@@ -99,6 +102,12 @@
                 case R.id.screen_lock_options:
                     launchChooseLockGeneric();
                     break;
+                case R.id.cancel_button:
+                    SetupSkipDialog dialog = SetupSkipDialog.newInstance(
+                            getActivity().getIntent()
+                                    .getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
+                    dialog.show(getFragmentManager());
+                    break;
                 default:
                     super.onClick(v);
             }
diff --git a/src/com/android/settings/fingerprint/SetupSkipDialog.java b/src/com/android/settings/password/SetupSkipDialog.java
similarity index 94%
rename from src/com/android/settings/fingerprint/SetupSkipDialog.java
rename to src/com/android/settings/password/SetupSkipDialog.java
index 842e69c..36646b7 100644
--- a/src/com/android/settings/fingerprint/SetupSkipDialog.java
+++ b/src/com/android/settings/password/SetupSkipDialog.java
@@ -14,12 +14,11 @@
  * limitations under the License
  */
 
-package com.android.settings.fingerprint;
+package com.android.settings.password;
 
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
 import android.app.FragmentManager;
 import android.content.DialogInterface;
 import android.os.Bundle;
@@ -36,7 +35,7 @@
 
     private static final String ARG_FRP_SUPPORTED = "frp_supported";
     private static final String TAG_SKIP_DIALOG = "skip_dialog";
-    private static final int RESULT_SKIP = Activity.RESULT_FIRST_USER + 10;
+    public static final int RESULT_SKIP = Activity.RESULT_FIRST_USER + 10;
 
     public static SetupSkipDialog newInstance(boolean isFrpSupported) {
         SetupSkipDialog dialog = new SetupSkipDialog();
diff --git a/tests/app/src/com/android/settings/password/SetupChooseLockPasswordAppTest.java b/tests/app/src/com/android/settings/password/SetupChooseLockPasswordAppTest.java
new file mode 100644
index 0000000..78acc3e
--- /dev/null
+++ b/tests/app/src/com/android/settings/password/SetupChooseLockPasswordAppTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.password;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.settings.R;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class SetupChooseLockPasswordAppTest {
+
+    @Rule
+    public ActivityTestRule<SetupChooseLockPassword> mActivityTestRule =
+            new ActivityTestRule<>(
+                    SetupChooseLockPassword.class,
+                    true /* enable touch at launch */,
+                    false /* don't launch at every test */);
+
+    @Test
+    public void testSkipDialogIsShown() throws Throwable {
+        SetupChooseLockPassword activity = mActivityTestRule.launchActivity(null);
+
+        onView(withId(R.id.cancel_button))
+                .check(matches(withText(R.string.skip_label)))
+                .check(matches(isDisplayed()))
+                .perform(click());
+        onView(withId(android.R.id.button1)).check(matches(isDisplayed())).perform(click());
+
+        assertThat(activity.isFinishing()).named("Is finishing").isTrue();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
new file mode 100644
index 0000000..9ee53ef
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fingerprint;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.RuntimeEnvironment.application;
+
+import android.app.KeyguardManager;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.password.SetupSkipDialog;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowEventLogWriter;
+import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
+import com.android.settings.testutils.shadow.ShadowUserManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.Shadows;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowActivity;
+import org.robolectric.shadows.ShadowKeyguardManager;
+import org.robolectric.util.ActivityController;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(
+        manifest = TestConfig.MANIFEST_PATH,
+        sdk = TestConfig.SDK_VERSION,
+        shadows = {
+                ShadowEventLogWriter.class,
+                ShadowLockPatternUtils.class,
+                ShadowUserManager.class
+        })
+public class SetupFingerprintEnrollIntroductionTest {
+
+    @Mock
+    private UserInfo mUserInfo;
+
+    private ActivityController<SetupFingerprintEnrollIntroduction> mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        final Intent intent = new Intent();
+        mController = Robolectric.buildActivity(SetupFingerprintEnrollIntroduction.class, intent);
+
+        ShadowUserManager.getShadow().setUserInfo(0, mUserInfo);
+    }
+
+    @Test
+    public void testKeyguardNotSecure_shouldFinishWithSetupSkipDialogResultSkip() {
+        getShadowKeyguardManager().setIsKeyguardSecure(false);
+
+        mController.create().resume();
+
+        final Button skipButton = mController.get().findViewById(R.id.fingerprint_cancel_button);
+        assertThat(skipButton.getVisibility()).named("Skip visible").isEqualTo(View.VISIBLE);
+        skipButton.performClick();
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(mController.get());
+        assertThat(mController.get().isFinishing()).named("Is finishing").isTrue();
+        assertThat(shadowActivity.getResultCode()).named("Result code")
+                .isEqualTo(SetupSkipDialog.RESULT_SKIP);
+    }
+
+    @Test
+    public void testKeyguardSecure_shouldFinishWithFingerprintResultSkip() {
+        getShadowKeyguardManager().setIsKeyguardSecure(true);
+
+        mController.create().resume();
+
+        final Button skipButton = mController.get().findViewById(R.id.fingerprint_cancel_button);
+        assertThat(skipButton.getVisibility()).named("Skip visible").isEqualTo(View.VISIBLE);
+        skipButton.performClick();
+
+        ShadowActivity shadowActivity = Shadows.shadowOf(mController.get());
+        assertThat(mController.get().isFinishing()).named("Is finishing").isTrue();
+        assertThat(shadowActivity.getResultCode()).named("Result code")
+                .isEqualTo(FingerprintEnrollBase.RESULT_SKIP);
+    }
+
+    private ShadowKeyguardManager getShadowKeyguardManager() {
+        return Shadows.shadowOf(application.getSystemService(KeyguardManager.class));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
index b1419ba..7c56dc6 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.testutils.shadow;
 
+import android.app.admin.DevicePolicyManager;
+
 import com.android.internal.widget.LockPatternUtils;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
@@ -27,4 +29,9 @@
     public boolean isSecure(int id) {
         return true;
     }
+
+    @Implementation
+    public int getActivePasswordQuality(int userId) {
+        return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
index c67ad36..61346bc 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
@@ -16,11 +16,19 @@
 
 package com.android.settings.testutils.shadow;
 
+import android.annotation.UserIdInt;
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.os.UserManager;
+import android.util.SparseArray;
 
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
+import org.robolectric.internal.ShadowExtractor;
+
+import java.util.Collections;
+import java.util.List;
 
 /**
  * This class provides the API 24 implementation of UserManager.get(Context).
@@ -28,8 +36,34 @@
 @Implements(UserManager.class)
 public class ShadowUserManager {
 
+    private SparseArray<UserInfo> mUserInfos = new SparseArray<>();
+
+    public void setUserInfo(int userHandle, UserInfo userInfo) {
+        mUserInfos.put(userHandle, userInfo);
+    }
+
+    @Implementation
+    public UserInfo getUserInfo(int userHandle) {
+        return mUserInfos.get(userHandle);
+    }
+
+    @Implementation
+    public List<UserInfo> getProfiles(@UserIdInt int userHandle) {
+        return Collections.emptyList();
+    }
+
+    @Implementation
+    public int getCredentialOwnerProfile(@UserIdInt int userHandle) {
+        return userHandle;
+    }
+
     @Implementation
     public static UserManager get(Context context) {
         return (UserManager) context.getSystemService(Context.USER_SERVICE);
     }
+
+    public static ShadowUserManager getShadow() {
+        return (ShadowUserManager) ShadowExtractor.extract(
+                RuntimeEnvironment.application.getSystemService(UserManager.class));
+    }
 }
diff --git a/tests/unit/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java b/tests/unit/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
deleted file mode 100644
index 8afed18..0000000
--- a/tests/unit/src/com/android/settings/fingerprint/SetupFingerprintEnrollIntroductionTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.fingerprint;
-
-
-import static org.mockito.Mockito.doReturn;
-
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.test.ActivityUnitTestCase;
-import android.view.View;
-import android.widget.Button;
-
-import com.android.settings.R;
-
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class SetupFingerprintEnrollIntroductionTest
-        extends ActivityUnitTestCase<SetupFingerprintEnrollIntroduction> {
-
-    private TestContext mContext;
-
-    @Mock
-    private KeyguardManager mKeyguardManager;
-
-    private SetupFingerprintEnrollIntroduction mActivity;
-
-    public SetupFingerprintEnrollIntroductionTest() {
-        super(SetupFingerprintEnrollIntroduction.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        MockitoAnnotations.initMocks(this);
-        mContext = new TestContext(getInstrumentation().getTargetContext());
-        setActivityContext(mContext);
-
-        getInstrumentation().runOnMainSync(() -> {
-            final Intent intent = new Intent();
-            mActivity = startActivity(intent,
-                    null /* savedInstanceState */, null /* lastNonConfigurationInstance */);
-        });
-    }
-
-    public void testKeyguardNotSecure_shouldShowSkipDialog() {
-        doReturn(false).when(mKeyguardManager).isKeyguardSecure();
-
-        getInstrumentation().runOnMainSync(() -> {
-            getInstrumentation().callActivityOnCreate(mActivity, null);
-            getInstrumentation().callActivityOnResume(mActivity);
-
-            final Button skipButton =
-                    (Button) mActivity.findViewById(R.id.fingerprint_cancel_button);
-            assertEquals(View.VISIBLE, skipButton.getVisibility());
-            skipButton.performClick();
-        });
-
-        assertFalse(isFinishCalled());
-    }
-
-    public void testKeyguardSecure_shouldNotShowSkipDialog() {
-        doReturn(true).when(mKeyguardManager).isKeyguardSecure();
-
-        getInstrumentation().runOnMainSync(() -> {
-            getInstrumentation().callActivityOnCreate(mActivity, null);
-            getInstrumentation().callActivityOnResume(mActivity);
-
-            final Button skipButton =
-                    (Button) mActivity.findViewById(R.id.fingerprint_cancel_button);
-            assertEquals(View.VISIBLE, skipButton.getVisibility());
-            skipButton.performClick();
-        });
-
-        assertTrue(isFinishCalled());
-    }
-
-    public class TestContext extends ContextWrapper {
-
-        public TestContext(Context base) {
-            super(base);
-        }
-
-        @Override
-        public Object getSystemService(String name) {
-            if (Context.KEYGUARD_SERVICE.equals(name)) {
-                return mKeyguardManager;
-            }
-            return super.getSystemService(name);
-        }
-    }
-}