From 5f8620d57117f9f0fcdfdc7c220f4dc4d05098aa Mon Sep 17 00:00:00 2001 From: Milton Wu Date: Mon, 26 Jun 2023 15:06:14 +0800 Subject: [PATCH] [BiometricsV2] Refactor EnrollingUdfpsFragment Refactor FingerprintEnrollEnrollingUdfpsFragment to kotlin and add bindView() method for it Bug: 286198032 Test: atest FingerprintEnrollmentActivityTest Test: atest BiometricsMicrobenchmark:biometrics-enrollment-test Test: Manually test enrollment as Udfps device Change-Id: Ife1e14ffabc4716acc53b67f641ba9cf159319f2 --- ...ngerprintEnrollEnrollingUdfpsFragment.java | 622 ------------------ ...FingerprintEnrollEnrollingUdfpsFragment.kt | 619 +++++++++++++++++ 2 files changed, 619 insertions(+), 622 deletions(-) delete mode 100644 src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.java create mode 100644 src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.kt diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.java deleted file mode 100644 index b5fe6094134..00000000000 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.java +++ /dev/null @@ -1,622 +0,0 @@ -/* - * 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 static android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL; - -import android.annotation.RawRes; -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.hardware.fingerprint.FingerprintManager; -import android.os.Bundle; -import android.text.TextUtils; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Surface; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import androidx.activity.OnBackPressedCallback; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.lifecycle.Observer; -import androidx.lifecycle.ViewModelProvider; - -import com.android.settings.R; -import com.android.settings.biometrics.BiometricUtils; -import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog; -import com.android.settings.biometrics2.ui.model.EnrollmentProgress; -import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage; -import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel; -import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel; -import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel; -import com.android.settings.biometrics2.ui.widget.UdfpsEnrollView; -import com.android.settingslib.display.DisplayDensityUtils; - -import com.airbnb.lottie.LottieAnimationView; -import com.airbnb.lottie.LottieCompositionFactory; - -/** - * Fragment is used to handle enrolling process for udfps - */ -public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { - - private static final String TAG = FingerprintEnrollEnrollingUdfpsFragment.class.getSimpleName(); - - private static final int PROGRESS_BAR_MAX = 10000; - - private static final int STAGE_UNKNOWN = -1; - private static final int STAGE_CENTER = 0; - private static final int STAGE_GUIDED = 1; - private static final int STAGE_FINGERTIP = 2; - private static final int STAGE_LEFT_EDGE = 3; - private static final int STAGE_RIGHT_EDGE = 4; - - private FingerprintEnrollEnrollingViewModel mEnrollingViewModel; - private DeviceRotationViewModel mRotationViewModel; - private FingerprintEnrollProgressViewModel mProgressViewModel; - - private LottieAnimationView mIllustrationLottie; - private boolean mHaveShownUdfpsTipLottie; - private boolean mHaveShownUdfpsLeftEdgeLottie; - private boolean mHaveShownUdfpsRightEdgeLottie; - private boolean mHaveShownUdfpsCenterLottie; - private boolean mHaveShownUdfpsGuideLottie; - - private TextView mTitleText; - private TextView mSubTitleText; - private UdfpsEnrollView mUdfpsEnrollView; - private Button mSkipBtn; - private ImageView mIcon; - - private boolean mShouldShowLottie; - private boolean mIsAccessibilityEnabled; - - private int mRotation = -1; - - private final View.OnClickListener mOnSkipClickListener = v -> { - mEnrollingViewModel.setOnSkipPressed(); - cancelEnrollment(); - }; - - private final Observer mProgressObserver = progress -> { - if (progress != null) { - onEnrollmentProgressChange(progress); - } - }; - private final Observer mHelpMessageObserver = helpMessage -> { - if (helpMessage != null) { - onEnrollmentHelp(helpMessage); - } - }; - private final Observer mErrorMessageObserver = errorMessage -> { - if (errorMessage != null) { - onEnrollmentError(errorMessage); - } - }; - private final Observer mAcquireObserver = isAcquiredGood -> { - if (isAcquiredGood != null) { - onAcquired(isAcquiredGood); - } - }; - private final Observer mPointerDownObserver = sensorId -> { - if (sensorId != null) { - onPointerDown(sensorId); - } - }; - private final Observer mPointerUpObserver = sensorId -> { - if (sensorId != null) { - onPointerUp(sensorId); - } - }; - - private final Observer mRotationObserver = rotation -> { - if (rotation != null) { - onRotationChanged(rotation); - } - }; - - private final OnBackPressedCallback mOnBackPressedCallback = new OnBackPressedCallback(true) { - @Override - public void handleOnBackPressed() { - setEnabled(false); - mEnrollingViewModel.setOnBackPressed(); - cancelEnrollment(); - } - }; - - @Override - public void onAttach(@NonNull Context context) { - final FragmentActivity activity = getActivity(); - final ViewModelProvider provider = new ViewModelProvider(activity); - mEnrollingViewModel = provider.get(FingerprintEnrollEnrollingViewModel.class); - mRotationViewModel = provider.get(DeviceRotationViewModel.class); - mProgressViewModel = provider.get(FingerprintEnrollProgressViewModel.class); - super.onAttach(context); - activity.getOnBackPressedDispatcher().addCallback(mOnBackPressedCallback); - } - - @Override - public void onDetach() { - mOnBackPressedCallback.setEnabled(false); - super.onDetach(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mIsAccessibilityEnabled = mEnrollingViewModel.isAccessibilityEnabled(); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - final RelativeLayout containView = (RelativeLayout) inflater.inflate( - R.layout.udfps_enroll_enrolling_v2, container, false); - - final Activity activity = getActivity(); - mIcon = containView.findViewById(R.id.sud_layout_icon); - mTitleText = containView.findViewById(R.id.suc_layout_title); - mSubTitleText = containView.findViewById(R.id.sud_layout_subtitle); - mSkipBtn = containView.findViewById(R.id.skip_btn); - mSkipBtn.setOnClickListener(mOnSkipClickListener); - mUdfpsEnrollView = containView.findViewById(R.id.udfps_animation_view); - mUdfpsEnrollView.setSensorProperties( - mEnrollingViewModel.getFirstFingerprintSensorPropertiesInternal()); - mShouldShowLottie = shouldShowLottie(); - final boolean isLandscape = BiometricUtils.isReverseLandscape(activity) - || BiometricUtils.isLandscape(activity); - updateOrientation(containView, (isLandscape - ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT)); - - mRotation = mRotationViewModel.getLiveData().getValue(); - configLayout(mRotation); - return containView; - } - - @Override - public void onStart() { - super.onStart(); - startEnrollment(); - updateProgress(false /* animate */, mProgressViewModel.getProgressLiveData().getValue()); - final EnrollmentStatusMessage msg = mProgressViewModel.getHelpMessageLiveData().getValue(); - if (msg != null) { - onEnrollmentHelp(msg); - } else { - updateTitleAndDescription(); - } - } - - @Override - public void onResume() { - super.onResume(); - mRotationViewModel.getLiveData().observe(this, mRotationObserver); - } - - @Override - public void onPause() { - mRotationViewModel.getLiveData().removeObserver(mRotationObserver); - super.onPause(); - } - - @Override - public void onStop() { - removeEnrollmentObservers(); - if (!getActivity().isChangingConfigurations() && mProgressViewModel.isEnrolling()) { - mProgressViewModel.cancelEnrollment(); - } - super.onStop(); - } - - private void removeEnrollmentObservers() { - preRemoveEnrollmentObservers(); - mProgressViewModel.getErrorMessageLiveData().removeObserver(mErrorMessageObserver); - } - - private void preRemoveEnrollmentObservers() { - mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver); - mProgressViewModel.getHelpMessageLiveData().removeObserver(mHelpMessageObserver); - mProgressViewModel.getAcquireLiveData().removeObserver(mAcquireObserver); - mProgressViewModel.getPointerDownLiveData().removeObserver(mPointerDownObserver); - mProgressViewModel.getPointerUpLiveData().removeObserver(mPointerUpObserver); - } - - private void cancelEnrollment() { - preRemoveEnrollmentObservers(); - mProgressViewModel.cancelEnrollment(); - } - - private void startEnrollment() { - final boolean startResult = mProgressViewModel.startEnrollment(ENROLL_ENROLL); - if (!startResult) { - Log.e(TAG, "startEnrollment(), failed"); - } - mProgressViewModel.getProgressLiveData().observe(this, mProgressObserver); - mProgressViewModel.getHelpMessageLiveData().observe(this, mHelpMessageObserver); - mProgressViewModel.getErrorMessageLiveData().observe(this, mErrorMessageObserver); - mProgressViewModel.getAcquireLiveData().observe(this, mAcquireObserver); - mProgressViewModel.getPointerDownLiveData().observe(this, mPointerDownObserver); - mProgressViewModel.getPointerUpLiveData().observe(this, mPointerUpObserver); - } - - private void updateProgress(boolean animate, @NonNull EnrollmentProgress enrollmentProgress) { - if (!mProgressViewModel.isEnrolling()) { - Log.d(TAG, "Enrollment not started yet"); - return; - } - - final int progress = getProgress(enrollmentProgress); - - if (mProgressViewModel.getProgressLiveData().getValue().getSteps() != -1) { - mUdfpsEnrollView.onEnrollmentProgress(enrollmentProgress.getRemaining(), - enrollmentProgress.getSteps()); - } - - if (animate) { - animateProgress(progress); - } else if (progress >= PROGRESS_BAR_MAX) { - mDelayedFinishRunnable.run(); - } - } - - private int getProgress(@NonNull EnrollmentProgress progress) { - if (progress.getSteps() == -1) { - return 0; - } - int displayProgress = Math.max(0, progress.getSteps() + 1 - progress.getRemaining()); - return PROGRESS_BAR_MAX * displayProgress / (progress.getSteps() + 1); - } - - private void animateProgress(int progress) { - // UDFPS animations are owned by SystemUI - if (progress >= PROGRESS_BAR_MAX) { - // Wait for any animations in SysUI to finish, then proceed to next page - getActivity().getMainThreadHandler().postDelayed(mDelayedFinishRunnable, 400L); - } - } - - private void updateTitleAndDescription() { - switch (getCurrentStage()) { - case STAGE_CENTER: - mTitleText.setText(R.string.security_settings_fingerprint_enroll_repeat_title); - if (mIsAccessibilityEnabled || mIllustrationLottie == null) { - mSubTitleText.setText(R.string.security_settings_udfps_enroll_start_message); - } else if (!mHaveShownUdfpsCenterLottie) { - mHaveShownUdfpsCenterLottie = true; - // Note: Update string reference when differentiate in between udfps & sfps - mIllustrationLottie.setContentDescription( - getString(R.string.security_settings_sfps_enroll_finger_center_title) - ); - configureEnrollmentStage(R.raw.udfps_center_hint_lottie); - } - break; - - case STAGE_GUIDED: - mTitleText.setText(R.string.security_settings_fingerprint_enroll_repeat_title); - if (mIsAccessibilityEnabled || mIllustrationLottie == null) { - mSubTitleText.setText( - R.string.security_settings_udfps_enroll_repeat_a11y_message); - } else if (!mHaveShownUdfpsGuideLottie) { - mHaveShownUdfpsGuideLottie = true; - mIllustrationLottie.setContentDescription( - getString(R.string.security_settings_fingerprint_enroll_repeat_message) - ); - // TODO(b/228100413) Could customize guided lottie animation - configureEnrollmentStage(R.raw.udfps_center_hint_lottie); - } - break; - case STAGE_FINGERTIP: - mTitleText.setText(R.string.security_settings_udfps_enroll_fingertip_title); - if (!mHaveShownUdfpsTipLottie && mIllustrationLottie != null) { - mHaveShownUdfpsTipLottie = true; - mIllustrationLottie.setContentDescription( - getString(R.string.security_settings_udfps_tip_fingerprint_help) - ); - configureEnrollmentStage(R.raw.udfps_tip_hint_lottie); - } - break; - case STAGE_LEFT_EDGE: - mTitleText.setText(R.string.security_settings_udfps_enroll_left_edge_title); - if (!mHaveShownUdfpsLeftEdgeLottie && mIllustrationLottie != null) { - mHaveShownUdfpsLeftEdgeLottie = true; - mIllustrationLottie.setContentDescription( - getString(R.string.security_settings_udfps_side_fingerprint_help) - ); - configureEnrollmentStage(R.raw.udfps_left_edge_hint_lottie); - } else if (mIllustrationLottie == null) { - if (isStageHalfCompleted()) { - mSubTitleText.setText( - R.string.security_settings_fingerprint_enroll_repeat_message); - } else { - mSubTitleText.setText(R.string.security_settings_udfps_enroll_edge_message); - } - } - break; - case STAGE_RIGHT_EDGE: - mTitleText.setText(R.string.security_settings_udfps_enroll_right_edge_title); - if (!mHaveShownUdfpsRightEdgeLottie && mIllustrationLottie != null) { - mHaveShownUdfpsRightEdgeLottie = true; - mIllustrationLottie.setContentDescription( - getString(R.string.security_settings_udfps_side_fingerprint_help) - ); - configureEnrollmentStage(R.raw.udfps_right_edge_hint_lottie); - - } else if (mIllustrationLottie == null) { - if (isStageHalfCompleted()) { - mSubTitleText.setText( - R.string.security_settings_fingerprint_enroll_repeat_message); - } else { - mSubTitleText.setText(R.string.security_settings_udfps_enroll_edge_message); - } - } - break; - - case STAGE_UNKNOWN: - default: - mTitleText.setText(R.string.security_settings_fingerprint_enroll_udfps_title); - mSubTitleText.setText(R.string.security_settings_udfps_enroll_start_message); - final CharSequence description = getString( - R.string.security_settings_udfps_enroll_a11y); - getActivity().setTitle(description); - break; - } - } - - private boolean shouldShowLottie() { - DisplayDensityUtils displayDensity = new DisplayDensityUtils(getContext()); - int currentDensityIndex = displayDensity.getCurrentIndexForDefaultDisplay(); - final int currentDensity = displayDensity.getDefaultDisplayDensityValues() - [currentDensityIndex]; - final int defaultDensity = displayDensity.getDefaultDensityForDefaultDisplay(); - return defaultDensity == currentDensity; - } - - private void updateOrientation(@NonNull RelativeLayout content, int orientation) { - switch (orientation) { - case Configuration.ORIENTATION_LANDSCAPE: { - mIllustrationLottie = null; - break; - } - case Configuration.ORIENTATION_PORTRAIT: { - if (mShouldShowLottie) { - mIllustrationLottie = content.findViewById(R.id.illustration_lottie); - } - break; - } - default: - Log.e(TAG, "Error unhandled configuration change"); - break; - } - } - - private int getCurrentStage() { - EnrollmentProgress progressLiveData = mProgressViewModel.getProgressLiveData().getValue(); - - if (progressLiveData == null || progressLiveData.getSteps() == -1) { - return STAGE_UNKNOWN; - } - - final int progressSteps = progressLiveData.getSteps() - progressLiveData.getRemaining(); - if (progressSteps < getStageThresholdSteps(0)) { - return STAGE_CENTER; - } else if (progressSteps < getStageThresholdSteps(1)) { - return STAGE_GUIDED; - } else if (progressSteps < getStageThresholdSteps(2)) { - return STAGE_FINGERTIP; - } else if (progressSteps < getStageThresholdSteps(3)) { - return STAGE_LEFT_EDGE; - } else { - return STAGE_RIGHT_EDGE; - } - } - - private boolean isStageHalfCompleted() { - EnrollmentProgress progressLiveData = mProgressViewModel.getProgressLiveData().getValue(); - if (progressLiveData == null || progressLiveData.getSteps() == -1) { - return false; - } - - final int progressSteps = progressLiveData.getSteps() - progressLiveData.getRemaining(); - int prevThresholdSteps = 0; - for (int i = 0; i < mEnrollingViewModel.getEnrollStageCount(); i++) { - final int thresholdSteps = getStageThresholdSteps(i); - if (progressSteps >= prevThresholdSteps && progressSteps < thresholdSteps) { - final int adjustedProgress = progressSteps - prevThresholdSteps; - final int adjustedThreshold = thresholdSteps - prevThresholdSteps; - return adjustedProgress >= adjustedThreshold / 2; - } - prevThresholdSteps = thresholdSteps; - } - - // After last enrollment step. - return true; - } - - private int getStageThresholdSteps(int index) { - - EnrollmentProgress progressLiveData = mProgressViewModel.getProgressLiveData().getValue(); - - if (progressLiveData == null || progressLiveData.getSteps() == -1) { - Log.w(TAG, "getStageThresholdSteps: Enrollment not started yet"); - return 1; - } - return Math.round(progressLiveData.getSteps() - * mEnrollingViewModel.getEnrollStageThreshold(index)); - } - - private void configureEnrollmentStage(@RawRes int lottie) { - mSubTitleText.setText(""); - LottieCompositionFactory.fromRawRes(getActivity(), lottie) - .addListener((c) -> { - mIllustrationLottie.setComposition(c); - mIllustrationLottie.setVisibility(View.VISIBLE); - mIllustrationLottie.playAnimation(); - }); - } - - private void onEnrollmentProgressChange(@NonNull EnrollmentProgress progress) { - updateProgress(true /* animate */, progress); - - updateTitleAndDescription(); - - if (mIsAccessibilityEnabled) { - final int steps = progress.getSteps(); - final int remaining = progress.getRemaining(); - final int percent = (int) (((float) (steps - remaining) / (float) steps) * 100); - CharSequence announcement = getActivity().getString( - R.string.security_settings_udfps_enroll_progress_a11y_message, percent); - mEnrollingViewModel.sendAccessibilityEvent(announcement); - } - - } - - private void onEnrollmentHelp(@NonNull EnrollmentStatusMessage helpMessage) { - final CharSequence helpStr = helpMessage.getStr(); - if (!TextUtils.isEmpty(helpStr)) { - showError(helpStr); - mUdfpsEnrollView.onEnrollmentHelp(); - } - } - private void onEnrollmentError(@NonNull EnrollmentStatusMessage errorMessage) { - removeEnrollmentObservers(); - - if (mEnrollingViewModel.getOnBackPressed() - && errorMessage.getMsgId() == FingerprintManager.FINGERPRINT_ERROR_CANCELED) { - mEnrollingViewModel.onCancelledDueToOnBackPressed(); - } else if (mEnrollingViewModel.getOnSkipPressed() - && errorMessage.getMsgId() == FingerprintManager.FINGERPRINT_ERROR_CANCELED) { - mEnrollingViewModel.onCancelledDueToOnSkipPressed(); - } else { - final int errMsgId = errorMessage.getMsgId(); - mEnrollingViewModel.showErrorDialog( - new FingerprintEnrollEnrollingViewModel.ErrorDialogData( - getString(FingerprintErrorDialog.getErrorMessage(errMsgId)), - getString(FingerprintErrorDialog.getErrorTitle(errMsgId)), - errMsgId - )); - mProgressViewModel.cancelEnrollment(); - } - } - - private void onAcquired(boolean isAcquiredGood) { - if (mUdfpsEnrollView != null) { - mUdfpsEnrollView.onAcquired(isAcquiredGood); - } - } - - private void onPointerDown(int sensorId) { - if (mUdfpsEnrollView != null) { - mUdfpsEnrollView.onPointerDown(sensorId); - } - } - - private void onPointerUp(int sensorId) { - if (mUdfpsEnrollView != null) { - mUdfpsEnrollView.onPointerUp(sensorId); - } - } - - private void showError(CharSequence error) { - mTitleText.setText(error); - mTitleText.setContentDescription(error); - mSubTitleText.setContentDescription(""); - } - - private void onRotationChanged(int newRotation) { - if( (newRotation +2) % 4 == mRotation) { - mRotation = newRotation; - configLayout(newRotation); - } - } - - private void configLayout(int newRotation) { - final Activity activity = getActivity(); - if (newRotation == Surface.ROTATION_270) { - RelativeLayout.LayoutParams iconLP = new RelativeLayout.LayoutParams(-2, -2); - iconLP.addRule(RelativeLayout.ALIGN_PARENT_TOP); - iconLP.addRule(RelativeLayout.END_OF, R.id.udfps_animation_view); - iconLP.topMargin = (int) convertDpToPixel(76.64f, activity); - iconLP.leftMargin = (int) convertDpToPixel(151.54f, activity); - mIcon.setLayoutParams(iconLP); - - RelativeLayout.LayoutParams titleLP = new RelativeLayout.LayoutParams(-1, -2); - titleLP.addRule(RelativeLayout.ALIGN_PARENT_TOP); - titleLP.addRule(RelativeLayout.END_OF, R.id.udfps_animation_view); - titleLP.topMargin = (int) convertDpToPixel(138f, activity); - titleLP.leftMargin = (int) convertDpToPixel(144f, activity); - mTitleText.setLayoutParams(titleLP); - - RelativeLayout.LayoutParams subtitleLP = new RelativeLayout.LayoutParams(-1, -2); - subtitleLP.addRule(RelativeLayout.ALIGN_PARENT_TOP); - subtitleLP.addRule(RelativeLayout.END_OF, R.id.udfps_animation_view); - subtitleLP.topMargin = (int) convertDpToPixel(198f, activity); - subtitleLP.leftMargin = (int) convertDpToPixel(144f, activity); - mSubTitleText.setLayoutParams(subtitleLP); - } else if (newRotation == Surface.ROTATION_90) { - DisplayMetrics metrics = activity.getResources().getDisplayMetrics(); - RelativeLayout.LayoutParams iconLP = new RelativeLayout.LayoutParams(-2, -2); - iconLP.addRule(RelativeLayout.ALIGN_PARENT_TOP); - iconLP.addRule(RelativeLayout.ALIGN_PARENT_START); - iconLP.topMargin = (int) convertDpToPixel(76.64f, activity); - iconLP.leftMargin = (int) convertDpToPixel(71.99f, activity); - mIcon.setLayoutParams(iconLP); - - RelativeLayout.LayoutParams titleLP = new RelativeLayout.LayoutParams( - metrics.widthPixels / 2, -2); - titleLP.addRule(RelativeLayout.ALIGN_PARENT_TOP); - titleLP.addRule(RelativeLayout.ALIGN_PARENT_START, R.id.udfps_animation_view); - titleLP.topMargin = (int) convertDpToPixel(138f, activity); - titleLP.leftMargin = (int) convertDpToPixel(66f, activity); - mTitleText.setLayoutParams(titleLP); - - RelativeLayout.LayoutParams subtitleLP = new RelativeLayout.LayoutParams( - metrics.widthPixels / 2, -2); - subtitleLP.addRule(RelativeLayout.ALIGN_PARENT_TOP); - subtitleLP.addRule(RelativeLayout.ALIGN_PARENT_START); - subtitleLP.topMargin = (int) convertDpToPixel(198f, activity); - subtitleLP.leftMargin = (int) convertDpToPixel(66f, activity); - mSubTitleText.setLayoutParams(subtitleLP); - } - - if (newRotation == Surface.ROTATION_90 || newRotation == Surface.ROTATION_270) { - RelativeLayout.LayoutParams skipBtnLP = - (RelativeLayout.LayoutParams) mSkipBtn.getLayoutParams(); - skipBtnLP.topMargin = (int) convertDpToPixel(26f, activity); - skipBtnLP.leftMargin = (int) convertDpToPixel(54f, activity); - mSkipBtn.requestLayout(); - } - } - - private float convertDpToPixel(float dp, Context context) { - return dp * getDensity(context); - } - - private float getDensity(Context context) { - DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - return metrics.density; - } - - // Give the user a chance to see progress completed before jumping to the next stage. - private final Runnable mDelayedFinishRunnable = () -> mEnrollingViewModel.onEnrollingDone(); -} diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.kt b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.kt new file mode 100644 index 00000000000..a71c0070dcf --- /dev/null +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.kt @@ -0,0 +1,619 @@ +/* + * 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.annotation.RawRes +import android.content.Context +import android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL +import android.hardware.fingerprint.FingerprintManager.FINGERPRINT_ERROR_CANCELED +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.Surface +import android.view.Surface.ROTATION_270 +import android.view.Surface.ROTATION_90 +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.ImageView +import android.widget.RelativeLayout +import android.widget.TextView +import androidx.activity.OnBackPressedCallback +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import com.airbnb.lottie.LottieAnimationView +import com.airbnb.lottie.LottieComposition +import com.airbnb.lottie.LottieCompositionFactory +import com.android.settings.R +import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog +import com.android.settings.biometrics2.ui.model.EnrollmentProgress +import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage +import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel +import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel +import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel +import com.android.settings.biometrics2.ui.widget.UdfpsEnrollView +import com.android.settingslib.display.DisplayDensityUtils +import kotlin.math.roundToInt + +/** + * Fragment is used to handle enrolling process for udfps + */ +class FingerprintEnrollEnrollingUdfpsFragment : Fragment() { + + private var _enrollingViewModel: FingerprintEnrollEnrollingViewModel? = null + private val enrollingViewModel: FingerprintEnrollEnrollingViewModel + get() = _enrollingViewModel!! + + private var _rotationViewModel: DeviceRotationViewModel? = null + private val rotationViewModel: DeviceRotationViewModel + get() = _rotationViewModel!! + + private var _progressViewModel: FingerprintEnrollProgressViewModel? = null + private val progressViewModel: FingerprintEnrollProgressViewModel + get() = _progressViewModel!! + + private var illustrationLottie: LottieAnimationView? = null + + private var haveShownTipLottie = false + private var haveShownLeftEdgeLottie = false + private var haveShownRightEdgeLottie = false + private var haveShownCenterLottie = false + private var haveShownGuideLottie = false + + private var enrollingUdfpsView: RelativeLayout? = null + + private val titleText: TextView + get() = enrollingUdfpsView!!.findViewById(R.id.suc_layout_title)!! + + private val subTitleText: TextView + get() = enrollingUdfpsView!!.findViewById(R.id.sud_layout_subtitle)!! + + private val udfpsEnrollView: UdfpsEnrollView + get() = enrollingUdfpsView!!.findViewById(R.id.udfps_animation_view)!! + + private val skipBtn: Button + get() = enrollingUdfpsView!!.findViewById