From 8e42d7c85a00adf70ac26ca9f46f1782f945696a Mon Sep 17 00:00:00 2001 From: Milton Wu Date: Sat, 17 Jun 2023 14:30:42 +0800 Subject: [PATCH] [BiometricsV2] Refactor Fingerprint intro fragment Refactor FingerprintEnrollIntroFragment to kotlin and add bindView() method for it. Bug: 286197823 Test: atest FingerprintEnrollmentActivityTest Change-Id: I44157bf2c2bea6f49382335438b16aae3e3e5b4c --- .../fingerprint_enroll_introduction.xml | 8 +- .../view/FingerprintEnrollIntroFragment.java | 310 ----------------- .../ui/view/FingerprintEnrollIntroFragment.kt | 322 ++++++++++++++++++ 3 files changed, 329 insertions(+), 311 deletions(-) delete mode 100644 src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.java create mode 100644 src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.kt diff --git a/res/layout/fingerprint_enroll_introduction.xml b/res/layout/fingerprint_enroll_introduction.xml index 5271e6a92ed..37587db3e41 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" /> @@ -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" /> @@ -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" /> @@ -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"/> @@ -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" /> 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 9cafdae5550..00000000000 --- 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 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 00000000000..2ba1df19f0a --- /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 = + 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(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 +) { + val context = view.context + + val iconFingerprint = view.findViewById(R.id.icon_fingerprint)!! + val iconDeviceLocked = view.findViewById(R.id.icon_device_locked)!! + val iconTrashCan = view.findViewById(R.id.icon_trash_can)!! + val iconInfo = view.findViewById(R.id.icon_info)!! + val iconShield = view.findViewById(R.id.icon_shield)!! + val iconLink = view.findViewById(R.id.icon_link)!! + val footerMessage6 = view.findViewById(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(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) + ) + ) + } +}