Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c320afa7 authored by Joshua Mccloskey's avatar Joshua Mccloskey Committed by Android (Google) Code Review
Browse files

Merge "Added UI tests for FingerprintEnrollIntro" into main

parents 2770170e b7021c8e
Loading
Loading
Loading
Loading
+166 −155
Original line number Diff line number Diff line
@@ -17,9 +17,8 @@

<com.google.android.setupdesign.GlifLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="?attr/fingerprint_layout_theme"
    android:id="@+id/setup_wizard_layout"
    style="?attr/fingerprint_layout_theme"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

@@ -58,9 +57,9 @@ android:layout_height="match_parent">

            <!-- How it works -->
            <TextView
                style="@style/BiometricEnrollIntroTitle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
            style="@style/BiometricEnrollIntroTitle"
                android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_title_2" />

            <LinearLayout
@@ -74,14 +73,16 @@ android:layout_height="match_parent">
                    android:layout_height="wrap_content"
                    android:contentDescription="@null"
                    android:src="@drawable/ic_fingerprint_24dp" />

                <Space
                    android:layout_width="16dp"
                    android:layout_height="wrap_content" />

                <TextView
                    android:id="@+id/footer_message_2"
                    style="@style/BiometricEnrollIntroMessage"
                    android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/BiometricEnrollIntroMessage" />
                    android:layout_height="wrap_content" />
            </LinearLayout>

            <LinearLayout
@@ -95,22 +96,24 @@ android:layout_height="match_parent">
                    android:layout_height="wrap_content"
                    android:contentDescription="@null"
                    android:src="@drawable/ic_lock_24dp" />

                <Space
                    android:layout_width="16dp"
                    android:layout_height="wrap_content" />

                <TextView
                    android:id="@+id/footer_message_3"
                    style="@style/BiometricEnrollIntroMessage"
                    android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/BiometricEnrollIntroMessage" />
                    android:layout_height="wrap_content" />
            </LinearLayout>

            <!-- You're in control -->
            <TextView
                android:id="@+id/footer_title_1"
                style="@style/BiometricEnrollIntroTitle"
                android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@style/BiometricEnrollIntroTitle" />
                android:layout_height="wrap_content" />

            <LinearLayout
                android:layout_width="match_parent"
@@ -123,22 +126,24 @@ android:layout_height="match_parent">
                    android:layout_height="wrap_content"
                    android:contentDescription="@null"
                    android:src="@drawable/ic_trash_can" />

                <Space
                    android:layout_width="16dp"
                    android:layout_height="wrap_content" />

                <TextView
                    android:id="@+id/footer_message_4"
                    style="@style/BiometricEnrollIntroMessage"
                    android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/BiometricEnrollIntroMessage" />
                    android:layout_height="wrap_content" />
            </LinearLayout>

            <!-- Keep in mind -->
            <TextView
                android:id="@+id/footer_title_2"
                style="@style/BiometricEnrollIntroTitle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
            style="@style/BiometricEnrollIntroTitle"
                android:text="@string/security_settings_face_enroll_introduction_info_title" />

            <LinearLayout
@@ -152,14 +157,16 @@ android:layout_height="match_parent">
                    android:layout_height="wrap_content"
                    android:contentDescription="@null"
                    android:src="@drawable/ic_info_outline_24dp" />

                <Space
                    android:layout_width="16dp"
                    android:layout_height="wrap_content" />

                <TextView
                    android:id="@+id/footer_message_5"
                    style="@style/BiometricEnrollIntroMessage"
                    android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/BiometricEnrollIntroMessage" />
                    android:layout_height="wrap_content" />
            </LinearLayout>

            <LinearLayout
@@ -173,14 +180,16 @@ android:layout_height="match_parent">
                    android:layout_height="wrap_content"
                    android:contentDescription="@null"
                    android:src="@drawable/ic_guarantee" />

                <Space
                    android:layout_width="16dp"
                    android:layout_height="wrap_content" />

                <TextView
                    android:id="@+id/footer_message_6"
                    style="@style/BiometricEnrollIntroMessage"
                    android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/BiometricEnrollIntroMessage" />
                    android:layout_height="wrap_content" />
            </LinearLayout>

            <LinearLayout
@@ -194,15 +203,17 @@ android:layout_height="match_parent">
                    android:layout_height="wrap_content"
                    android:contentDescription="@null"
                    android:src="@drawable/ic_link_24dp" />

                <Space
                    android:layout_width="16dp"
                    android:layout_height="wrap_content" />

                <TextView
                    android:id="@+id/footer_learn_more"
                android:linksClickable="true"
                    style="@style/BiometricEnrollIntroMessage"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                style="@style/BiometricEnrollIntroMessage"
                    android:linksClickable="true"
                    android:paddingBottom="0dp"
                    android:text="@string/security_settings_fingerprint_v2_enroll_introduction_message_learn_more" />
            </LinearLayout>
+5 −2
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import com.android.settings.biometrics.BiometricEnrollBase.CONFIRM_REQUEST
import com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED
import com.android.settings.biometrics.GatekeeperPasswordProvider
import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractorImpl
import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollConfirmationV2Fragment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollEnrollingV2Fragment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollFindSensorV2Fragment
@@ -82,6 +83,7 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
  private lateinit var accessibilityViewModel: AccessibilityViewModel
  private lateinit var foldStateViewModel: FoldStateViewModel
  private lateinit var orientationStateViewModel: OrientationStateViewModel
  private lateinit var fingerprintScrollViewModel: FingerprintScrollViewModel
  private val coroutineDispatcher = Dispatchers.Default

  /** Result listener for ChooseLock activity flow. */
@@ -210,6 +212,7 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
      )[FingerprintEnrollViewModel::class.java]

    // Initialize scroll view model
    fingerprintScrollViewModel =
      ViewModelProvider(this, FingerprintScrollViewModel.FingerprintScrollViewModelFactory())[
        FingerprintScrollViewModel::class.java]

+69 −48
Original line number Diff line number Diff line
@@ -25,10 +25,13 @@ import android.os.Bundle
import android.text.Html
import android.text.method.LinkMovementMethod
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.ScrollView
import android.widget.TextView
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
@@ -72,33 +75,53 @@ private data class TextModel(
 * 2. How the data will be stored
 * 3. How the user can access and remove their data
 */
class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll_introduction) {
class FingerprintEnrollIntroV2Fragment() : Fragment(R.layout.fingerprint_v2_enroll_introduction) {

  /** Used for testing purposes */
  private var factory: ViewModelProvider.Factory? = null

  @VisibleForTesting
  constructor(theFactory: ViewModelProvider.Factory) : this() {
    factory = theFactory
  }

  private val viewModelProvider: ViewModelProvider by lazy {
    if (factory != null) {
      ViewModelProvider(requireActivity(), factory!!)
    } else {
      ViewModelProvider(requireActivity())
    }
  }

  private lateinit var footerBarMixin: FooterBarMixin
  private lateinit var textModel: TextModel
  private lateinit var navigationViewModel: FingerprintEnrollNavigationViewModel
  private lateinit var fingerprintEnrollViewModel: FingerprintEnrollViewModel
  private lateinit var fingerprintScrollViewModel: FingerprintScrollViewModel
  private lateinit var gateKeeperViewModel: FingerprintGatekeeperViewModel

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    navigationViewModel =
      ViewModelProvider(requireActivity())[FingerprintEnrollNavigationViewModel::class.java]
    fingerprintEnrollViewModel =
      ViewModelProvider(requireActivity())[FingerprintEnrollViewModel::class.java]
    fingerprintScrollViewModel =
      ViewModelProvider(requireActivity())[FingerprintScrollViewModel::class.java]
    gateKeeperViewModel =
      ViewModelProvider(requireActivity())[FingerprintGatekeeperViewModel::class.java]

  // Note that the ViewModels cannot be requested before the onCreate call
  private val navigationViewModel: FingerprintEnrollNavigationViewModel by lazy {
    viewModelProvider[FingerprintEnrollNavigationViewModel::class.java]
  }
  private val fingerprintViewModel: FingerprintEnrollViewModel by lazy {
    viewModelProvider[FingerprintEnrollViewModel::class.java]
  }
  private val fingerprintScrollViewModel: FingerprintScrollViewModel by lazy {
    viewModelProvider[FingerprintScrollViewModel::class.java]
  }
  private val gateKeeperViewModel: FingerprintGatekeeperViewModel by lazy {
    viewModelProvider[FingerprintGatekeeperViewModel::class.java]
  }

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
  override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
  ): View? =
    super.onCreateView(inflater, container, savedInstanceState).also { theView ->
      val view = theView!!

    lifecycleScope.launch {
      viewLifecycleOwner.lifecycleScope.launch {
        combine(
            navigationViewModel.enrollType,
          fingerprintEnrollViewModel.sensorType,
            fingerprintViewModel.sensorType,
          ) { enrollType, sensorType ->
            Pair(enrollType, sensorType)
          }
@@ -111,9 +134,10 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll

            setupFooterBarAndScrollView(view)

          if (savedInstanceState == null) {
            getLayout()?.setHeaderText(textModel.headerText)
            getLayout()?.setDescriptionText(textModel.descriptionText)
            val layout = view as GlifLayout

            layout.setHeaderText(textModel.headerText)
            layout.setDescriptionText(textModel.descriptionText)

            // Set color filter for the following icons.
            val colorFilter = getIconColorFilter()
@@ -159,7 +183,7 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll
            view.requireViewById<TextView?>(R.id.footer_title_2).setText(textModel.footerTitleOne)
          }
      }
    }
      return view
    }

  private fun setFooterLink(view: View) {
@@ -185,17 +209,18 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll
        navigationViewModel.nextStep()
      }

    val layout: GlifLayout = requireActivity().requireViewById(R.id.setup_wizard_layout)
    val layout: GlifLayout = view.findViewById(R.id.setup_wizard_layout)!!
    footerBarMixin = layout.getMixin(FooterBarMixin::class.java)
    footerBarMixin.primaryButton =
      FooterButton.Builder(requireActivity())
      FooterButton.Builder(requireContext())
        .setText(R.string.security_settings_face_enroll_introduction_more)
        .setListener(onNextButtonClick)
        .setButtonType(FooterButton.ButtonType.OPT_IN)
        .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary)
        .build()

    footerBarMixin.setSecondaryButton(
      FooterButton.Builder(requireActivity())
      FooterButton.Builder(requireContext())
        .setText(textModel.negativeButton)
        .setListener({ Log.d(TAG, "prevClicked") })
        .setButtonType(FooterButton.ButtonType.NEXT)
@@ -211,8 +236,8 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll

    val requireScrollMixin = layout.getMixin(RequireScrollMixin::class.java)
    requireScrollMixin.requireScrollWithButton(
      requireActivity(),
      footerBarMixin.primaryButton,
      requireContext(),
      primaryButton,
      R.string.security_settings_face_enroll_introduction_more,
      onNextButtonClick
    )
@@ -224,7 +249,7 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll
      }
    }

    lifecycleScope.launch {
    viewLifecycleOwner.lifecycleScope.launch {
      fingerprintScrollViewModel.hasReadConsentScreen.collect { consented ->
        if (consented) {
          primaryButton.setText(
@@ -244,7 +269,7 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll
    // the flow. For instance if someone launches the activity with an invalid challenge, it
    // either 1) Fails or 2) Launched confirmDeviceCredential
    primaryButton.isEnabled = false
    lifecycleScope.launch {
    viewLifecycleOwner.lifecycleScope.launch {
      gateKeeperViewModel.hasValidGatekeeperInfo.collect { primaryButton.isEnabled = it }
    }
  }
@@ -284,8 +309,4 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll
      PorterDuff.Mode.SRC_IN
    )
  }

  private fun getLayout(): GlifLayout? {
    return requireView().findViewById(R.id.setup_wizard_layout) as GlifLayout?
  }
}
+0 −11
Original line number Diff line number Diff line
@@ -31,11 +31,6 @@ import kotlinx.coroutines.launch

private const val TAG = "FingerprintEnrollNavigationViewModel"

/** Interface to validate a gatekeeper hat */
interface Validator {
  fun validateGateKeeper(challenge: Long?): Boolean
}

/**
 * The [EnrollType] for fingerprint enrollment indicates information on how the flow should behave.
 */
@@ -56,7 +51,6 @@ object Unicorn : EnrollType()
 */
class FingerprintEnrollNavigationViewModel(
  private val dispatcher: CoroutineDispatcher,
  private val validator: Validator,
  private val fingerprintManagerInteractor: FingerprintManagerInteractor,
  private val gatekeeperViewModel: FingerprintGatekeeperViewModel,
  private val canSkipConfirm: Boolean
@@ -145,11 +139,6 @@ class FingerprintEnrollNavigationViewModel(

      return FingerprintEnrollNavigationViewModel(
        backgroundDispatcher,
        object : Validator {
          override fun validateGateKeeper(challenge: Long?): Boolean {
            return challenge != null
          }
        },
        fingerprintManagerInteractor,
        fingerprintGatekeeperViewModel,
        canSkipConfirm,
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ android_app {
        "androidx.fragment_fragment-testing",
        "frameworks-base-testutils",
        "androidx.fragment_fragment",
        "androidx.lifecycle_lifecycle-runtime-testing",
        "kotlinx_coroutines_test",
    ],

    aaptflags: ["--extra-packages com.android.settings"],
Loading