[BiometricsV2] Refactor Fingerprint intro fragment
Refactor FingerprintEnrollIntroFragment to kotlin and add bindView()
method for it.
Bug: 286197823
Test: atest FingerprintEnrollmentActivityTest
Change-Id: I44157bf2c2bea6f49382335438b16aae3e3e5b4c
diff --git a/res/layout/fingerprint_enroll_introduction.xml b/res/layout/fingerprint_enroll_introduction.xml
index 5271e6a..37587db 100644
--- a/res/layout/fingerprint_enroll_introduction.xml
+++ b/res/layout/fingerprint_enroll_introduction.xml
@@ -81,6 +81,7 @@
android:id="@+id/footer_message_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_2"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
@@ -102,6 +103,7 @@
android:id="@+id/footer_message_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_3"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
@@ -110,6 +112,7 @@
android:id="@+id/footer_title_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:text="@string/security_settings_fingerprint_enroll_introduction_footer_title_1"
style="@style/BiometricEnrollIntroTitle" />
<LinearLayout
@@ -130,6 +133,7 @@
android:id="@+id/footer_message_4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_4"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
@@ -139,7 +143,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroTitle"
- android:text="@string/security_settings_face_enroll_introduction_info_title"/>
+ android:text="@string/security_settings_fingerprint_enroll_introduction_footer_title_2"/>
<LinearLayout
android:layout_width="match_parent"
@@ -159,6 +163,7 @@
android:id="@+id/footer_message_5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_5"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
@@ -180,6 +185,7 @@
android:id="@+id/footer_message_6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:text="@string/security_settings_fingerprint_v2_enroll_introduction_footer_message_6"
style="@style/BiometricEnrollIntroMessage" />
</LinearLayout>
diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.java
deleted file mode 100644
index 9cafdae..0000000
--- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2022 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.biometrics2.ui.view;
-
-import static android.app.admin.DevicePolicyResources.Strings.Settings.FINGERPRINT_UNLOCK_DISABLED;
-
-import static com.android.settings.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX;
-
-import static com.google.android.setupdesign.util.DynamicColorPalette.ColorType.ACCENT;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-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.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.fragment.app.Fragment;
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.ViewModelProvider;
-
-import com.android.settings.R;
-import com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus;
-import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel;
-
-import com.google.android.setupcompat.template.FooterBarMixin;
-import com.google.android.setupcompat.template.FooterButton;
-import com.google.android.setupdesign.GlifLayout;
-import com.google.android.setupdesign.template.RequireScrollMixin;
-import com.google.android.setupdesign.util.DeviceHelper;
-import com.google.android.setupdesign.util.DynamicColorPalette;
-
-/**
- * Fingerprint intro onboarding page fragment implementation
- */
-public class FingerprintEnrollIntroFragment extends Fragment {
-
- private static final String TAG = "FingerprintEnrollIntroFragment";
- private static final boolean DEBUG = false;
-
- private FingerprintEnrollIntroViewModel mViewModel = null;
-
- private View mView = null;
- private FooterButton mPrimaryFooterButton = null;
- private FooterButton mSecondaryFooterButton = null;
- private final OnClickListener mOnNextClickListener = (v) -> mViewModel.onNextButtonClick();
- private final OnClickListener mOnSkipOrCancelClickListener =
- (v) -> mViewModel.onSkipOrCancelButtonClick();
- private ImageView mIconShield = null;
- private TextView mFooterMessage6 = null;
- @Nullable private PorterDuffColorFilter mIconColorFilter;
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
-
- final Context context = inflater.getContext();
- mView = inflater.inflate(R.layout.fingerprint_enroll_introduction, container, false);
-
- final ImageView iconFingerprint = mView.findViewById(R.id.icon_fingerprint);
- final ImageView iconDeviceLocked = mView.findViewById(R.id.icon_device_locked);
- final ImageView iconTrashCan = mView.findViewById(R.id.icon_trash_can);
- final ImageView iconInfo = mView.findViewById(R.id.icon_info);
- mIconShield = mView.findViewById(R.id.icon_shield);
- final ImageView iconLink = mView.findViewById(R.id.icon_link);
- iconFingerprint.getDrawable().setColorFilter(getIconColorFilter(context));
- iconDeviceLocked.getDrawable().setColorFilter(getIconColorFilter(context));
- iconTrashCan.getDrawable().setColorFilter(getIconColorFilter(context));
- iconInfo.getDrawable().setColorFilter(getIconColorFilter(context));
- mIconShield.getDrawable().setColorFilter(getIconColorFilter(context));
- iconLink.getDrawable().setColorFilter(getIconColorFilter(context));
-
- final TextView footerMessage2 = mView.findViewById(R.id.footer_message_2);
- final TextView footerMessage3 = mView.findViewById(R.id.footer_message_3);
- final TextView footerMessage4 = mView.findViewById(R.id.footer_message_4);
- final TextView footerMessage5 = mView.findViewById(R.id.footer_message_5);
- mFooterMessage6 = mView.findViewById(R.id.footer_message_6);
- footerMessage2.setText(
- R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_2);
- footerMessage3.setText(
- R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_3);
- footerMessage4.setText(
- R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_4);
- footerMessage5.setText(
- R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_5);
- mFooterMessage6.setText(
- R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_6);
-
- final TextView footerTitle1 = mView.findViewById(R.id.footer_title_1);
- final TextView footerTitle2 = mView.findViewById(R.id.footer_title_2);
- footerTitle1.setText(
- R.string.security_settings_fingerprint_enroll_introduction_footer_title_1);
- footerTitle2.setText(
- R.string.security_settings_fingerprint_enroll_introduction_footer_title_2);
-
- final TextView footerLink = mView.findViewById(R.id.footer_learn_more);
- footerLink.setMovementMethod(LinkMovementMethod.getInstance());
- final String footerLinkStr = getContext().getString(
- R.string.security_settings_fingerprint_v2_enroll_introduction_message_learn_more,
- Html.FROM_HTML_MODE_LEGACY);
- footerLink.setText(Html.fromHtml(footerLinkStr));
-
- // footer buttons
-
- return mView;
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- final Context context = view.getContext();
-
- if (mViewModel.canAssumeUdfps()) {
- mFooterMessage6.setVisibility(View.VISIBLE);
- mIconShield.setVisibility(View.VISIBLE);
- } else {
- mFooterMessage6.setVisibility(View.GONE);
- mIconShield.setVisibility(View.GONE);
- }
-
- final GlifLayoutHelper glifLayoutHelper = new GlifLayoutHelper(getActivity(), getLayout());
- if (mViewModel.isBiometricUnlockDisabledByAdmin()
- && !mViewModel.isParentalConsentRequired()) {
- glifLayoutHelper.setHeaderText(
- R.string.security_settings_fingerprint_enroll_introduction_title_unlock_disabled
- );
- glifLayoutHelper.setDescriptionText(getDescriptionDisabledByAdmin(context));
- } else {
- glifLayoutHelper.setHeaderText(
- R.string.security_settings_fingerprint_enroll_introduction_title);
- glifLayoutHelper.setDescriptionText(getString(
- R.string.security_settings_fingerprint_enroll_introduction_v3_message,
- DeviceHelper.getDeviceName(context)));
- }
- }
-
- @Override
- public void onStart() {
- final Context context = requireContext();
- final FooterBarMixin footerBarMixin = getFooterBarMixin();
- initPrimaryFooterButton(context, footerBarMixin);
- initSecondaryFooterButton(context, footerBarMixin);
- observePageStatusLiveDataIfNeed();
- super.onStart();
- }
-
- private void initPrimaryFooterButton(@NonNull Context context,
- @NonNull FooterBarMixin footerBarMixin) {
- if (footerBarMixin.getPrimaryButton() != null) {
- return;
- }
-
- mPrimaryFooterButton = new FooterButton.Builder(context)
- .setText(R.string.security_settings_fingerprint_enroll_introduction_agree)
- .setButtonType(FooterButton.ButtonType.OPT_IN)
- .setTheme(R.style.SudGlifButton_Primary)
- .build();
- mPrimaryFooterButton.setOnClickListener(mOnNextClickListener);
- footerBarMixin.setPrimaryButton(mPrimaryFooterButton);
- }
-
- private void initSecondaryFooterButton(@NonNull Context context,
- @NonNull FooterBarMixin footerBarMixin) {
- if (footerBarMixin.getSecondaryButton() != null) {
- return;
- }
-
- mSecondaryFooterButton = new FooterButton.Builder(context)
- .setText(mViewModel.getRequest().isAfterSuwOrSuwSuggestedAction()
- ? R.string.security_settings_fingerprint_enroll_introduction_cancel
- : R.string.security_settings_fingerprint_enroll_introduction_no_thanks)
- .setButtonType(FooterButton.ButtonType.NEXT)
- .setTheme(R.style.SudGlifButton_Primary)
- .build();
- mSecondaryFooterButton.setOnClickListener(mOnSkipOrCancelClickListener);
- footerBarMixin.setSecondaryButton(mSecondaryFooterButton, true /* usePrimaryStyle */);
- }
-
- private void observePageStatusLiveDataIfNeed() {
- final LiveData<FingerprintEnrollIntroStatus> statusLiveData =
- mViewModel.getPageStatusLiveData();
- final FingerprintEnrollIntroStatus status = statusLiveData.getValue();
- if (DEBUG) {
- Log.e(TAG, "observePageStatusLiveDataIfNeed() requireScrollWithButton, status:"
- + status);
- }
- if (status != null && (status.hasScrollToBottom()
- || status.getEnrollableStatus() == FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)) {
- // Update once and do not requireScrollWithButton() again when page has scrolled to
- // bottom or User has enrolled at least a fingerprint, because if we
- // requireScrollWithButton() again, primary button will become "More" after scrolling.
- updateFooterButtons(status);
- return;
- }
-
- final RequireScrollMixin requireScrollMixin = getLayout()
- .getMixin(RequireScrollMixin.class);
- requireScrollMixin.requireScrollWithButton(getActivity(), mPrimaryFooterButton,
- getMoreButtonTextRes(), mOnNextClickListener);
-
- requireScrollMixin.setOnRequireScrollStateChangedListener(
- scrollNeeded -> mViewModel.setHasScrolledToBottom(!scrollNeeded));
- statusLiveData.observe(this, this::updateFooterButtons);
- }
-
- @Override
- public void onAttach(@NonNull Context context) {
- mViewModel = new ViewModelProvider(getActivity())
- .get(FingerprintEnrollIntroViewModel.class);
- super.onAttach(context);
- }
-
- @NonNull
- private PorterDuffColorFilter getIconColorFilter(@NonNull Context context) {
- if (mIconColorFilter == null) {
- mIconColorFilter = new PorterDuffColorFilter(
- DynamicColorPalette.getColor(context, ACCENT),
- PorterDuff.Mode.SRC_IN);
- }
- return mIconColorFilter;
- }
-
- private GlifLayout getLayout() {
- return mView.findViewById(R.id.setup_wizard_layout);
- }
-
- @NonNull
- private FooterBarMixin getFooterBarMixin() {
- final GlifLayout layout = getLayout();
- return layout.getMixin(FooterBarMixin.class);
- }
-
- @NonNull
- private String getDescriptionDisabledByAdmin(@NonNull Context context) {
- final int defaultStrId =
- R.string.security_settings_fingerprint_enroll_introduction_message_unlock_disabled;
-
- final DevicePolicyManager devicePolicyManager = getActivity()
- .getSystemService(DevicePolicyManager.class);
- if (devicePolicyManager != null) {
- return devicePolicyManager.getResources().getString(FINGERPRINT_UNLOCK_DISABLED,
- () -> context.getString(defaultStrId));
- } else {
- Log.w(TAG, "getDescriptionDisabledByAdmin, null device policy manager res");
- return "";
- }
- }
-
- void updateFooterButtons(@NonNull FingerprintEnrollIntroStatus status) {
- if (DEBUG) {
- Log.d(TAG, "updateFooterButtons(" + status + ")");
- }
- mPrimaryFooterButton.setText(getContext(),
- status.getEnrollableStatus() == FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
- ? R.string.done
- : status.hasScrollToBottom()
- ? R.string.security_settings_fingerprint_enroll_introduction_agree
- : getMoreButtonTextRes());
- mSecondaryFooterButton.setVisibility(status.hasScrollToBottom()
- && status.getEnrollableStatus() != FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
- ? View.VISIBLE
- : View.INVISIBLE);
-
- final TextView errorTextView = mView.findViewById(R.id.error_text);
- switch (status.getEnrollableStatus()) {
- case FINGERPRINT_ENROLLABLE_OK:
- errorTextView.setText(null);
- errorTextView.setVisibility(View.GONE);
- break;
- case FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX:
- errorTextView.setText(R.string.fingerprint_intro_error_max);
- errorTextView.setVisibility(View.VISIBLE);
- break;
- case FINGERPRINT_ENROLLABLE_UNKNOWN:
- // default case, do nothing.
- }
- }
-
- @StringRes
- private int getMoreButtonTextRes() {
- return R.string.security_settings_face_enroll_introduction_more;
- }
-}
diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.kt b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.kt
new file mode 100644
index 0000000..2ba1df1
--- /dev/null
+++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.kt
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2023 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.biometrics2.ui.view
+
+import android.app.admin.DevicePolicyManager
+import android.app.admin.DevicePolicyResources.Strings.Settings.FINGERPRINT_UNLOCK_DISABLED
+import android.content.Context
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffColorFilter
+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.TextView
+import androidx.annotation.StringRes
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.ViewModelProvider
+import com.android.settings.R
+import com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus
+import com.android.settings.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
+import com.android.settings.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_OK
+import com.android.settings.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_UNKNOWN
+import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel
+import com.google.android.setupcompat.template.FooterBarMixin
+import com.google.android.setupcompat.template.FooterButton
+import com.google.android.setupdesign.GlifLayout
+import com.google.android.setupdesign.template.RequireScrollMixin
+import com.google.android.setupdesign.util.DeviceHelper
+import com.google.android.setupdesign.util.DynamicColorPalette
+import com.google.android.setupdesign.util.DynamicColorPalette.ColorType.ACCENT
+import java.util.function.Supplier
+
+/**
+ * Fingerprint intro onboarding page fragment implementation
+ */
+class FingerprintEnrollIntroFragment : Fragment() {
+
+ private val viewModelProvider: ViewModelProvider
+ get() = ViewModelProvider(requireActivity())
+
+ private var _viewModel: FingerprintEnrollIntroViewModel? = null
+ private val viewModel: FingerprintEnrollIntroViewModel
+ get() {
+ if (_viewModel == null) {
+ _viewModel = viewModelProvider[FingerprintEnrollIntroViewModel::class.java]
+ }
+ return _viewModel!!
+ }
+
+ private var introView: GlifLayout? = null
+
+ private var primaryFooterButton: FooterButton? = null
+
+ private var secondaryFooterButton: FooterButton? = null
+
+ private val onNextClickListener =
+ View.OnClickListener { _: View? -> viewModel.onNextButtonClick() }
+
+ private val onSkipOrCancelClickListener =
+ View.OnClickListener { _: View? -> viewModel.onSkipOrCancelButtonClick() }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ introView = inflater.inflate(
+ R.layout.fingerprint_enroll_introduction,
+ container,
+ false
+ ) as GlifLayout
+ return introView!!
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ requireActivity().bindFingerprintEnrollIntroView(
+ view = introView!!,
+ canAssumeUdfps = viewModel.canAssumeUdfps(),
+ isBiometricUnlockDisabledByAdmin = viewModel.isBiometricUnlockDisabledByAdmin,
+ isParentalConsentRequired = viewModel.isParentalConsentRequired,
+ descriptionDisabledByAdminSupplier = { getDescriptionDisabledByAdmin(view.context) }
+ )
+ }
+
+ override fun onStart() {
+ val context: Context = requireContext()
+ val footerBarMixin: FooterBarMixin = footerBarMixin
+ initPrimaryFooterButton(context, footerBarMixin)
+ initSecondaryFooterButton(context, footerBarMixin)
+ observePageStatusLiveDataIfNeed()
+ super.onStart()
+ }
+
+ private fun initPrimaryFooterButton(
+ context: Context,
+ footerBarMixin: FooterBarMixin
+ ) {
+ if (footerBarMixin.primaryButton != null) {
+ return
+ }
+ primaryFooterButton = FooterButton.Builder(context)
+ .setText(R.string.security_settings_fingerprint_enroll_introduction_agree)
+ .setButtonType(FooterButton.ButtonType.OPT_IN)
+ .setTheme(R.style.SudGlifButton_Primary)
+ .build()
+ .also {
+ it.setOnClickListener(onNextClickListener)
+ footerBarMixin.primaryButton = it
+ }
+ }
+
+ private fun initSecondaryFooterButton(
+ context: Context,
+ footerBarMixin: FooterBarMixin
+ ) {
+ if (footerBarMixin.secondaryButton != null) {
+ return
+ }
+ secondaryFooterButton = FooterButton.Builder(context)
+ .setText(
+ if (viewModel.request.isAfterSuwOrSuwSuggestedAction)
+ R.string.security_settings_fingerprint_enroll_introduction_cancel
+ else
+ R.string.security_settings_fingerprint_enroll_introduction_no_thanks
+ )
+ .setButtonType(FooterButton.ButtonType.NEXT)
+ .setTheme(R.style.SudGlifButton_Primary)
+ .build()
+ .also {
+ it.setOnClickListener(onSkipOrCancelClickListener)
+ footerBarMixin.setSecondaryButton(it, true /* usePrimaryStyle */)
+ }
+ }
+
+ private fun observePageStatusLiveDataIfNeed() {
+ val statusLiveData: LiveData<FingerprintEnrollIntroStatus> =
+ viewModel.pageStatusLiveData
+ val status: FingerprintEnrollIntroStatus? = statusLiveData.value
+
+ if (DEBUG) {
+ Log.e(
+ TAG, "observePageStatusLiveDataIfNeed() requireScrollWithButton, status:"
+ + status
+ )
+ }
+
+ if (status != null && (status.hasScrollToBottom()
+ || status.enrollableStatus === FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
+ ) {
+ // Update once and do not requireScrollWithButton() again when page has scrolled to
+ // bottom or User has enrolled at least a fingerprint, because if we
+ // requireScrollWithButton() again, primary button will become "More" after scrolling.
+ updateFooterButtons(status)
+ return
+ }
+
+ introView!!.getMixin(RequireScrollMixin::class.java).let {
+ it.requireScrollWithButton(
+ requireActivity(),
+ primaryFooterButton!!,
+ moreButtonTextRes,
+ onNextClickListener
+ )
+ it.setOnRequireScrollStateChangedListener { scrollNeeded: Boolean ->
+ viewModel.setHasScrolledToBottom(!scrollNeeded)
+ }
+ }
+ statusLiveData.observe(this) { newStatus: FingerprintEnrollIntroStatus ->
+ updateFooterButtons(newStatus)
+ }
+ }
+
+ override fun onAttach(context: Context) {
+ _viewModel = null
+ super.onAttach(context)
+ }
+
+ private val footerBarMixin: FooterBarMixin
+ get() = introView!!.getMixin(FooterBarMixin::class.java)
+
+ private fun getDescriptionDisabledByAdmin(context: Context): String? {
+ val defaultStrId: Int =
+ R.string.security_settings_fingerprint_enroll_introduction_message_unlock_disabled
+ val devicePolicyManager: DevicePolicyManager = requireActivity()
+ .getSystemService(DevicePolicyManager::class.java)
+
+ return devicePolicyManager.resources.getString(FINGERPRINT_UNLOCK_DISABLED) {
+ context.getString(defaultStrId)
+ }
+ }
+
+ private fun updateFooterButtons(status: FingerprintEnrollIntroStatus) {
+ if (DEBUG) {
+ Log.d(TAG, "updateFooterButtons($status)")
+ }
+ primaryFooterButton!!.setText(
+ context,
+ if (status.enrollableStatus === FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
+ R.string.done
+ else if (status.hasScrollToBottom())
+ R.string.security_settings_fingerprint_enroll_introduction_agree
+ else
+ moreButtonTextRes
+ )
+ secondaryFooterButton!!.visibility =
+ if (status.hasScrollToBottom()
+ && status.enrollableStatus !== FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
+ )
+ View.VISIBLE
+ else
+ View.INVISIBLE
+
+ view!!.findViewById<TextView>(R.id.error_text).let {
+ when (status.enrollableStatus) {
+ FINGERPRINT_ENROLLABLE_OK -> {
+ it.text = null
+ it.visibility = View.GONE
+ }
+
+ FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX -> {
+ it.setText(R.string.fingerprint_intro_error_max)
+ it.visibility = View.VISIBLE
+ }
+
+ FINGERPRINT_ENROLLABLE_UNKNOWN -> {}
+ }
+ }
+ }
+
+ @get:StringRes
+ private val moreButtonTextRes: Int
+ get() = R.string.security_settings_face_enroll_introduction_more
+
+ companion object {
+ private const val TAG = "FingerprintEnrollIntroFragment"
+ private const val DEBUG = false
+ }
+}
+
+fun FragmentActivity.bindFingerprintEnrollIntroView(
+ view: GlifLayout,
+ canAssumeUdfps: Boolean,
+ isBiometricUnlockDisabledByAdmin: Boolean,
+ isParentalConsentRequired: Boolean,
+ descriptionDisabledByAdminSupplier: Supplier<String?>
+) {
+ val context = view.context
+
+ val iconFingerprint = view.findViewById<ImageView>(R.id.icon_fingerprint)!!
+ val iconDeviceLocked = view.findViewById<ImageView>(R.id.icon_device_locked)!!
+ val iconTrashCan = view.findViewById<ImageView>(R.id.icon_trash_can)!!
+ val iconInfo = view.findViewById<ImageView>(R.id.icon_info)!!
+ val iconShield = view.findViewById<ImageView>(R.id.icon_shield)!!
+ val iconLink = view.findViewById<ImageView>(R.id.icon_link)!!
+ val footerMessage6 = view.findViewById<TextView>(R.id.footer_message_6)!!
+
+ PorterDuffColorFilter(
+ DynamicColorPalette.getColor(context, ACCENT),
+ PorterDuff.Mode.SRC_IN
+ ).let { colorFilter ->
+ iconFingerprint.drawable.colorFilter = colorFilter
+ iconDeviceLocked.drawable.colorFilter = colorFilter
+ iconTrashCan.drawable.colorFilter = colorFilter
+ iconInfo.drawable.colorFilter = colorFilter
+ iconShield.drawable.colorFilter = colorFilter
+ iconLink.drawable.colorFilter = colorFilter
+ }
+
+ view.findViewById<TextView>(R.id.footer_learn_more)!!.let { learnMore ->
+ learnMore.movementMethod = LinkMovementMethod.getInstance()
+ val footerLinkStr: String = context.getString(
+ R.string.security_settings_fingerprint_v2_enroll_introduction_message_learn_more,
+ Html.FROM_HTML_MODE_LEGACY
+ )
+ learnMore.text = Html.fromHtml(footerLinkStr)
+ }
+
+ if (canAssumeUdfps) {
+ footerMessage6.visibility = View.VISIBLE
+ iconShield.visibility = View.VISIBLE
+ } else {
+ footerMessage6.visibility = View.GONE
+ iconShield.visibility = View.GONE
+ }
+ val glifLayoutHelper = GlifLayoutHelper(this, view)
+ if (isBiometricUnlockDisabledByAdmin && !isParentalConsentRequired) {
+ glifLayoutHelper.setHeaderText(
+ R.string.security_settings_fingerprint_enroll_introduction_title_unlock_disabled
+ )
+ glifLayoutHelper.setDescriptionText(descriptionDisabledByAdminSupplier.get())
+ } else {
+ glifLayoutHelper.setHeaderText(
+ R.string.security_settings_fingerprint_enroll_introduction_title
+ )
+ glifLayoutHelper.setDescriptionText(
+ getString(
+ R.string.security_settings_fingerprint_enroll_introduction_v3_message,
+ DeviceHelper.getDeviceName(context)
+ )
+ )
+ }
+}