Loading packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml +1 −1 Original line number Original line Diff line number Diff line Loading @@ -47,7 +47,7 @@ android:layout_height="wrap_content" android:layout_height="wrap_content" android:fillViewport="true" android:fillViewport="true" android:fadeScrollbars="false" android:fadeScrollbars="false" android:paddingBottom="36dp" android:paddingBottom="24dp" android:paddingHorizontal="24dp" android:paddingHorizontal="24dp" android:paddingTop="24dp" android:paddingTop="24dp" app:layout_constrainedHeight="true" app:layout_constrainedHeight="true" Loading packages/SystemUI/res/values/dimens.xml +3 −3 Original line number Original line Diff line number Diff line Loading @@ -1094,9 +1094,9 @@ <dimen name="remote_input_history_extra_height">60dp</dimen> <dimen name="remote_input_history_extra_height">60dp</dimen> <!-- Biometric Dialog values --> <!-- Biometric Dialog values --> <dimen name="biometric_dialog_face_icon_size">54dp</dimen> <dimen name="biometric_dialog_face_icon_size">68dp</dimen> <dimen name="biometric_dialog_fingerprint_icon_width">80dp</dimen> <dimen name="biometric_dialog_fingerprint_icon_width">100dp</dimen> <dimen name="biometric_dialog_fingerprint_icon_height">80dp</dimen> <dimen name="biometric_dialog_fingerprint_icon_height">100dp</dimen> <dimen name="biometric_dialog_button_negative_max_width">160dp</dimen> <dimen name="biometric_dialog_button_negative_max_width">160dp</dimen> <dimen name="biometric_dialog_button_positive_max_width">136dp</dimen> <dimen name="biometric_dialog_button_positive_max_width">136dp</dimen> <dimen name="biometric_dialog_corner_size">28dp</dimen> <dimen name="biometric_dialog_corner_size">28dp</dimen> Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +6 −2 Original line number Original line Diff line number Diff line Loading @@ -230,9 +230,13 @@ public class AuthContainerView extends LinearLayout @Override @Override public void onUseDeviceCredential() { public void onUseDeviceCredential() { mConfig.mCallback.onDeviceCredentialPressed(getRequestId()); mConfig.mCallback.onDeviceCredentialPressed(getRequestId()); if (constraintBp()) { addCredentialView(false /* animatePanel */, true /* animateContents */); } else { mHandler.postDelayed(() -> { mHandler.postDelayed(() -> { addCredentialView(false /* animatePanel */, true /* animateContents */); addCredentialView(false /* animatePanel */, true /* animateContents */); }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS); }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS); } // TODO(b/313469218): Remove Config // TODO(b/313469218): Remove Config mConfig.mPromptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL); mConfig.mPromptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL); Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +12 −4 Original line number Original line Diff line number Diff line Loading @@ -87,7 +87,9 @@ object BiometricViewBinder { * * * TODO(b/288175072): May be able to remove this once constraint layout is implemented * TODO(b/288175072): May be able to remove this once constraint layout is implemented */ */ if (!constraintBp()) { view.visibility = View.INVISIBLE view.visibility = View.INVISIBLE } val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!! val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!! val textColorError = val textColorError = Loading @@ -102,6 +104,12 @@ object BiometricViewBinder { val descriptionView = view.requireViewById<TextView>(R.id.description) val descriptionView = view.requireViewById<TextView>(R.id.description) val customizedViewContainer = val customizedViewContainer = view.requireViewById<LinearLayout>(R.id.customized_view_container) view.requireViewById<LinearLayout>(R.id.customized_view_container) val udfpsGuidanceView = if (constraintBp()) { view.requireViewById<View>(R.id.panel) } else { backgroundView } // set selected to enable marquee unless a screen reader is enabled // set selected to enable marquee unless a screen reader is enabled logoView.isSelected = logoView.isSelected = Loading Loading @@ -226,8 +234,8 @@ object BiometricViewBinder { } } lifecycleScope.launch { lifecycleScope.launch { viewModel.showBpWithoutIconForCredential.collect { viewModel.showBpWithoutIconForCredential.collect { showWithoutIcon -> if (!it) { if (!showWithoutIcon) { PromptIconViewBinder.bind( PromptIconViewBinder.bind( iconView, iconView, iconOverlayView, iconOverlayView, Loading Loading @@ -428,7 +436,7 @@ object BiometricViewBinder { } } // Talkback directional guidance // Talkback directional guidance backgroundView.setOnHoverListener { _, event -> udfpsGuidanceView.setOnHoverListener { _, event -> launch { launch { viewModel.onAnnounceAccessibilityHint( viewModel.onAnnounceAccessibilityHint( event, event, Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +228 −121 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.animation.Animator import android.animation.AnimatorSet import android.animation.AnimatorSet import android.animation.ValueAnimator import android.animation.ValueAnimator import android.graphics.Outline import android.graphics.Outline import android.graphics.Rect import android.transition.AutoTransition import android.transition.AutoTransition import android.transition.TransitionManager import android.transition.TransitionManager import android.util.TypedValue import android.util.TypedValue Loading @@ -36,7 +37,6 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.Guideline import androidx.constraintlayout.widget.Guideline import androidx.core.animation.addListener import androidx.core.animation.addListener import androidx.core.view.doOnAttach import androidx.core.view.doOnLayout import androidx.core.view.doOnLayout import androidx.core.view.isGone import androidx.core.view.isGone import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope Loading Loading @@ -106,6 +106,52 @@ object BiometricViewSizeBinder { ) ) .toInt() .toInt() var currentSize: PromptSize? = null var currentPosition: PromptPosition = PromptPosition.Bottom panelView.outlineProvider = object : ViewOutlineProvider() { override fun getOutline(view: View, outline: Outline) { when (currentPosition) { PromptPosition.Right -> { outline.setRoundRect( 0, 0, view.width + cornerRadiusPx, view.height, cornerRadiusPx.toFloat() ) } PromptPosition.Left -> { outline.setRoundRect( -cornerRadiusPx, 0, view.width, view.height, cornerRadiusPx.toFloat() ) } PromptPosition.Top -> { outline.setRoundRect( 0, -cornerRadiusPx, view.width, view.height, cornerRadiusPx.toFloat() ) } PromptPosition.Bottom -> { outline.setRoundRect( 0, 0, view.width, view.height + cornerRadiusPx, cornerRadiusPx.toFloat() ) } } } } // ConstraintSets for animating between prompt sizes // ConstraintSets for animating between prompt sizes val mediumConstraintSet = ConstraintSet() val mediumConstraintSet = ConstraintSet() mediumConstraintSet.clone(view as ConstraintLayout) mediumConstraintSet.clone(view as ConstraintLayout) Loading @@ -115,7 +161,9 @@ object BiometricViewSizeBinder { val largeConstraintSet = ConstraintSet() val largeConstraintSet = ConstraintSet() largeConstraintSet.clone(mediumConstraintSet) largeConstraintSet.clone(mediumConstraintSet) largeConstraintSet.constrainMaxWidth(R.id.panel, view.width) largeConstraintSet.constrainMaxWidth(R.id.panel, 0) largeConstraintSet.setGuidelineBegin(R.id.leftGuideline, 0) largeConstraintSet.setGuidelineEnd(R.id.rightGuideline, 0) // TODO: Investigate better way to handle 180 rotations // TODO: Investigate better way to handle 180 rotations val flipConstraintSet = ConstraintSet() val flipConstraintSet = ConstraintSet() Loading @@ -138,65 +186,134 @@ object BiometricViewSizeBinder { } } } } fun roundCorners(size: PromptSize, position: PromptPosition) { view.repeatWhenAttached { var left = 0 lifecycleScope.launch { var top = 0 viewModel.iconPosition.collect { position -> var right = 0 if (position != Rect()) { var bottom = 0 val iconParams = when (size) { iconHolderView.layoutParams as ConstraintLayout.LayoutParams PromptSize.SMALL, PromptSize.MEDIUM -> if (position.left != 0) { when (position) { iconParams.endToEnd = ConstraintSet.UNSET PromptPosition.Right -> { iconParams.leftMargin = position.left left = 0 mediumConstraintSet.clear( top = 0 R.id.biometric_icon, right = view.width + cornerRadiusPx ConstraintSet.END bottom = view.height ) mediumConstraintSet.connect( R.id.biometric_icon, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START ) mediumConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.START, position.left ) smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.END) smallConstraintSet.connect( R.id.biometric_icon, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START ) smallConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.START, position.left ) } } PromptPosition.Left -> { if (position.top != 0) { left = -cornerRadiusPx iconParams.bottomToBottom = ConstraintSet.UNSET top = 0 iconParams.topMargin = position.top right = view.width mediumConstraintSet.clear( bottom = view.height R.id.biometric_icon, ConstraintSet.BOTTOM ) mediumConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.TOP, position.top ) smallConstraintSet.clear( R.id.biometric_icon, ConstraintSet.BOTTOM ) smallConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.TOP, position.top ) } } PromptPosition.Top -> { if (position.right != 0) { left = 0 iconParams.startToStart = ConstraintSet.UNSET top = -cornerRadiusPx iconParams.rightMargin = position.right right = panelView.width mediumConstraintSet.clear( bottom = view.height R.id.biometric_icon, ConstraintSet.START ) mediumConstraintSet.connect( R.id.biometric_icon, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END ) mediumConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.END, position.right ) smallConstraintSet.clear( R.id.biometric_icon, ConstraintSet.START ) smallConstraintSet.connect( R.id.biometric_icon, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END ) smallConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.END, position.right ) } } PromptPosition.Bottom -> { if (position.bottom != 0) { left = 0 iconParams.topToTop = ConstraintSet.UNSET top = 0 iconParams.bottomMargin = position.bottom right = panelView.width mediumConstraintSet.clear( bottom = view.height + cornerRadiusPx R.id.biometric_icon, ConstraintSet.TOP ) mediumConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.BOTTOM, position.bottom ) smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.TOP) smallConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.BOTTOM, position.bottom ) } } iconHolderView.layoutParams = iconParams } } PromptSize.LARGE -> { left = 0 top = 0 right = view.width bottom = view.height } } } } lifecycleScope.launch { // Round the panel outline viewModel.iconSize.collect { iconSize -> panelView.outlineProvider = iconHolderView.layoutParams.width = iconSize.first object : ViewOutlineProvider() { iconHolderView.layoutParams.height = iconSize.second override fun getOutline(view: View, outline: Outline) { mediumConstraintSet.constrainWidth(R.id.biometric_icon, iconSize.first) outline.setRoundRect( mediumConstraintSet.constrainHeight( left, R.id.biometric_icon, top, iconSize.second right, bottom, cornerRadiusPx.toFloat() ) ) } } } } } view.repeatWhenAttached { var currentSize: PromptSize? = null lifecycleScope.launch { lifecycleScope.launch { viewModel.guidelineBounds.collect { bounds -> viewModel.guidelineBounds.collect { bounds -> Loading Loading @@ -249,7 +366,6 @@ object BiometricViewSizeBinder { lifecycleScope.launch { lifecycleScope.launch { combine(viewModel.position, viewModel.size, ::Pair).collect { combine(viewModel.position, viewModel.size, ::Pair).collect { (position, size) -> (position, size) -> view.doOnAttach { setVisibilities(size) setVisibilities(size) if (position.isLeft) { if (position.isLeft) { Loading @@ -274,8 +390,6 @@ object BiometricViewSizeBinder { ) ) } } roundCorners(size, position) when { when { size.isSmall -> { size.isSmall -> { if (position.isLeft) { if (position.isLeft) { Loading @@ -290,10 +404,7 @@ object BiometricViewSizeBinder { ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong() ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong() ) ) TransitionManager.beginDelayedTransition( TransitionManager.beginDelayedTransition(view, autoTransition) view, autoTransition ) if (position.isLeft) { if (position.isLeft) { flipConstraintSet.applyTo(view) flipConstraintSet.applyTo(view) Loading @@ -308,32 +419,28 @@ object BiometricViewSizeBinder { mediumConstraintSet.applyTo(view) mediumConstraintSet.applyTo(view) } } } } size.isLarge -> { size.isLarge && currentSize.isMedium -> { val autoTransition = AutoTransition() val autoTransition = AutoTransition() autoTransition.setDuration( autoTransition.setDuration( ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong() ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong() ) ) TransitionManager.beginDelayedTransition( TransitionManager.beginDelayedTransition(view, autoTransition) view, autoTransition ) largeConstraintSet.applyTo(view) largeConstraintSet.applyTo(view) } } } } currentSize = size currentSize = size view.visibility = View.VISIBLE currentPosition = position viewModel.setIsIconViewLoaded(false) notifyAccessibilityChanged() notifyAccessibilityChanged() panelView.invalidateOutline() view.invalidate() view.invalidate() view.requestLayout() view.requestLayout() } } } } } } } } } } else if (panelViewController != null) { } else if (panelViewController != null) { val iconHolderView = view.requireViewById<View>(R.id.biometric_icon_frame) val iconHolderView = view.requireViewById<View>(R.id.biometric_icon_frame) val iconPadding = view.resources.getDimension(R.dimen.biometric_dialog_icon_padding) val iconPadding = view.resources.getDimension(R.dimen.biometric_dialog_icon_padding) Loading Loading
packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml +1 −1 Original line number Original line Diff line number Diff line Loading @@ -47,7 +47,7 @@ android:layout_height="wrap_content" android:layout_height="wrap_content" android:fillViewport="true" android:fillViewport="true" android:fadeScrollbars="false" android:fadeScrollbars="false" android:paddingBottom="36dp" android:paddingBottom="24dp" android:paddingHorizontal="24dp" android:paddingHorizontal="24dp" android:paddingTop="24dp" android:paddingTop="24dp" app:layout_constrainedHeight="true" app:layout_constrainedHeight="true" Loading
packages/SystemUI/res/values/dimens.xml +3 −3 Original line number Original line Diff line number Diff line Loading @@ -1094,9 +1094,9 @@ <dimen name="remote_input_history_extra_height">60dp</dimen> <dimen name="remote_input_history_extra_height">60dp</dimen> <!-- Biometric Dialog values --> <!-- Biometric Dialog values --> <dimen name="biometric_dialog_face_icon_size">54dp</dimen> <dimen name="biometric_dialog_face_icon_size">68dp</dimen> <dimen name="biometric_dialog_fingerprint_icon_width">80dp</dimen> <dimen name="biometric_dialog_fingerprint_icon_width">100dp</dimen> <dimen name="biometric_dialog_fingerprint_icon_height">80dp</dimen> <dimen name="biometric_dialog_fingerprint_icon_height">100dp</dimen> <dimen name="biometric_dialog_button_negative_max_width">160dp</dimen> <dimen name="biometric_dialog_button_negative_max_width">160dp</dimen> <dimen name="biometric_dialog_button_positive_max_width">136dp</dimen> <dimen name="biometric_dialog_button_positive_max_width">136dp</dimen> <dimen name="biometric_dialog_corner_size">28dp</dimen> <dimen name="biometric_dialog_corner_size">28dp</dimen> Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +6 −2 Original line number Original line Diff line number Diff line Loading @@ -230,9 +230,13 @@ public class AuthContainerView extends LinearLayout @Override @Override public void onUseDeviceCredential() { public void onUseDeviceCredential() { mConfig.mCallback.onDeviceCredentialPressed(getRequestId()); mConfig.mCallback.onDeviceCredentialPressed(getRequestId()); if (constraintBp()) { addCredentialView(false /* animatePanel */, true /* animateContents */); } else { mHandler.postDelayed(() -> { mHandler.postDelayed(() -> { addCredentialView(false /* animatePanel */, true /* animateContents */); addCredentialView(false /* animatePanel */, true /* animateContents */); }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS); }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS); } // TODO(b/313469218): Remove Config // TODO(b/313469218): Remove Config mConfig.mPromptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL); mConfig.mPromptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL); Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +12 −4 Original line number Original line Diff line number Diff line Loading @@ -87,7 +87,9 @@ object BiometricViewBinder { * * * TODO(b/288175072): May be able to remove this once constraint layout is implemented * TODO(b/288175072): May be able to remove this once constraint layout is implemented */ */ if (!constraintBp()) { view.visibility = View.INVISIBLE view.visibility = View.INVISIBLE } val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!! val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!! val textColorError = val textColorError = Loading @@ -102,6 +104,12 @@ object BiometricViewBinder { val descriptionView = view.requireViewById<TextView>(R.id.description) val descriptionView = view.requireViewById<TextView>(R.id.description) val customizedViewContainer = val customizedViewContainer = view.requireViewById<LinearLayout>(R.id.customized_view_container) view.requireViewById<LinearLayout>(R.id.customized_view_container) val udfpsGuidanceView = if (constraintBp()) { view.requireViewById<View>(R.id.panel) } else { backgroundView } // set selected to enable marquee unless a screen reader is enabled // set selected to enable marquee unless a screen reader is enabled logoView.isSelected = logoView.isSelected = Loading Loading @@ -226,8 +234,8 @@ object BiometricViewBinder { } } lifecycleScope.launch { lifecycleScope.launch { viewModel.showBpWithoutIconForCredential.collect { viewModel.showBpWithoutIconForCredential.collect { showWithoutIcon -> if (!it) { if (!showWithoutIcon) { PromptIconViewBinder.bind( PromptIconViewBinder.bind( iconView, iconView, iconOverlayView, iconOverlayView, Loading Loading @@ -428,7 +436,7 @@ object BiometricViewBinder { } } // Talkback directional guidance // Talkback directional guidance backgroundView.setOnHoverListener { _, event -> udfpsGuidanceView.setOnHoverListener { _, event -> launch { launch { viewModel.onAnnounceAccessibilityHint( viewModel.onAnnounceAccessibilityHint( event, event, Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +228 −121 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.animation.Animator import android.animation.AnimatorSet import android.animation.AnimatorSet import android.animation.ValueAnimator import android.animation.ValueAnimator import android.graphics.Outline import android.graphics.Outline import android.graphics.Rect import android.transition.AutoTransition import android.transition.AutoTransition import android.transition.TransitionManager import android.transition.TransitionManager import android.util.TypedValue import android.util.TypedValue Loading @@ -36,7 +37,6 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.Guideline import androidx.constraintlayout.widget.Guideline import androidx.core.animation.addListener import androidx.core.animation.addListener import androidx.core.view.doOnAttach import androidx.core.view.doOnLayout import androidx.core.view.doOnLayout import androidx.core.view.isGone import androidx.core.view.isGone import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope Loading Loading @@ -106,6 +106,52 @@ object BiometricViewSizeBinder { ) ) .toInt() .toInt() var currentSize: PromptSize? = null var currentPosition: PromptPosition = PromptPosition.Bottom panelView.outlineProvider = object : ViewOutlineProvider() { override fun getOutline(view: View, outline: Outline) { when (currentPosition) { PromptPosition.Right -> { outline.setRoundRect( 0, 0, view.width + cornerRadiusPx, view.height, cornerRadiusPx.toFloat() ) } PromptPosition.Left -> { outline.setRoundRect( -cornerRadiusPx, 0, view.width, view.height, cornerRadiusPx.toFloat() ) } PromptPosition.Top -> { outline.setRoundRect( 0, -cornerRadiusPx, view.width, view.height, cornerRadiusPx.toFloat() ) } PromptPosition.Bottom -> { outline.setRoundRect( 0, 0, view.width, view.height + cornerRadiusPx, cornerRadiusPx.toFloat() ) } } } } // ConstraintSets for animating between prompt sizes // ConstraintSets for animating between prompt sizes val mediumConstraintSet = ConstraintSet() val mediumConstraintSet = ConstraintSet() mediumConstraintSet.clone(view as ConstraintLayout) mediumConstraintSet.clone(view as ConstraintLayout) Loading @@ -115,7 +161,9 @@ object BiometricViewSizeBinder { val largeConstraintSet = ConstraintSet() val largeConstraintSet = ConstraintSet() largeConstraintSet.clone(mediumConstraintSet) largeConstraintSet.clone(mediumConstraintSet) largeConstraintSet.constrainMaxWidth(R.id.panel, view.width) largeConstraintSet.constrainMaxWidth(R.id.panel, 0) largeConstraintSet.setGuidelineBegin(R.id.leftGuideline, 0) largeConstraintSet.setGuidelineEnd(R.id.rightGuideline, 0) // TODO: Investigate better way to handle 180 rotations // TODO: Investigate better way to handle 180 rotations val flipConstraintSet = ConstraintSet() val flipConstraintSet = ConstraintSet() Loading @@ -138,65 +186,134 @@ object BiometricViewSizeBinder { } } } } fun roundCorners(size: PromptSize, position: PromptPosition) { view.repeatWhenAttached { var left = 0 lifecycleScope.launch { var top = 0 viewModel.iconPosition.collect { position -> var right = 0 if (position != Rect()) { var bottom = 0 val iconParams = when (size) { iconHolderView.layoutParams as ConstraintLayout.LayoutParams PromptSize.SMALL, PromptSize.MEDIUM -> if (position.left != 0) { when (position) { iconParams.endToEnd = ConstraintSet.UNSET PromptPosition.Right -> { iconParams.leftMargin = position.left left = 0 mediumConstraintSet.clear( top = 0 R.id.biometric_icon, right = view.width + cornerRadiusPx ConstraintSet.END bottom = view.height ) mediumConstraintSet.connect( R.id.biometric_icon, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START ) mediumConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.START, position.left ) smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.END) smallConstraintSet.connect( R.id.biometric_icon, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START ) smallConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.START, position.left ) } } PromptPosition.Left -> { if (position.top != 0) { left = -cornerRadiusPx iconParams.bottomToBottom = ConstraintSet.UNSET top = 0 iconParams.topMargin = position.top right = view.width mediumConstraintSet.clear( bottom = view.height R.id.biometric_icon, ConstraintSet.BOTTOM ) mediumConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.TOP, position.top ) smallConstraintSet.clear( R.id.biometric_icon, ConstraintSet.BOTTOM ) smallConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.TOP, position.top ) } } PromptPosition.Top -> { if (position.right != 0) { left = 0 iconParams.startToStart = ConstraintSet.UNSET top = -cornerRadiusPx iconParams.rightMargin = position.right right = panelView.width mediumConstraintSet.clear( bottom = view.height R.id.biometric_icon, ConstraintSet.START ) mediumConstraintSet.connect( R.id.biometric_icon, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END ) mediumConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.END, position.right ) smallConstraintSet.clear( R.id.biometric_icon, ConstraintSet.START ) smallConstraintSet.connect( R.id.biometric_icon, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END ) smallConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.END, position.right ) } } PromptPosition.Bottom -> { if (position.bottom != 0) { left = 0 iconParams.topToTop = ConstraintSet.UNSET top = 0 iconParams.bottomMargin = position.bottom right = panelView.width mediumConstraintSet.clear( bottom = view.height + cornerRadiusPx R.id.biometric_icon, ConstraintSet.TOP ) mediumConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.BOTTOM, position.bottom ) smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.TOP) smallConstraintSet.setMargin( R.id.biometric_icon, ConstraintSet.BOTTOM, position.bottom ) } } iconHolderView.layoutParams = iconParams } } PromptSize.LARGE -> { left = 0 top = 0 right = view.width bottom = view.height } } } } lifecycleScope.launch { // Round the panel outline viewModel.iconSize.collect { iconSize -> panelView.outlineProvider = iconHolderView.layoutParams.width = iconSize.first object : ViewOutlineProvider() { iconHolderView.layoutParams.height = iconSize.second override fun getOutline(view: View, outline: Outline) { mediumConstraintSet.constrainWidth(R.id.biometric_icon, iconSize.first) outline.setRoundRect( mediumConstraintSet.constrainHeight( left, R.id.biometric_icon, top, iconSize.second right, bottom, cornerRadiusPx.toFloat() ) ) } } } } } view.repeatWhenAttached { var currentSize: PromptSize? = null lifecycleScope.launch { lifecycleScope.launch { viewModel.guidelineBounds.collect { bounds -> viewModel.guidelineBounds.collect { bounds -> Loading Loading @@ -249,7 +366,6 @@ object BiometricViewSizeBinder { lifecycleScope.launch { lifecycleScope.launch { combine(viewModel.position, viewModel.size, ::Pair).collect { combine(viewModel.position, viewModel.size, ::Pair).collect { (position, size) -> (position, size) -> view.doOnAttach { setVisibilities(size) setVisibilities(size) if (position.isLeft) { if (position.isLeft) { Loading @@ -274,8 +390,6 @@ object BiometricViewSizeBinder { ) ) } } roundCorners(size, position) when { when { size.isSmall -> { size.isSmall -> { if (position.isLeft) { if (position.isLeft) { Loading @@ -290,10 +404,7 @@ object BiometricViewSizeBinder { ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong() ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong() ) ) TransitionManager.beginDelayedTransition( TransitionManager.beginDelayedTransition(view, autoTransition) view, autoTransition ) if (position.isLeft) { if (position.isLeft) { flipConstraintSet.applyTo(view) flipConstraintSet.applyTo(view) Loading @@ -308,32 +419,28 @@ object BiometricViewSizeBinder { mediumConstraintSet.applyTo(view) mediumConstraintSet.applyTo(view) } } } } size.isLarge -> { size.isLarge && currentSize.isMedium -> { val autoTransition = AutoTransition() val autoTransition = AutoTransition() autoTransition.setDuration( autoTransition.setDuration( ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong() ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong() ) ) TransitionManager.beginDelayedTransition( TransitionManager.beginDelayedTransition(view, autoTransition) view, autoTransition ) largeConstraintSet.applyTo(view) largeConstraintSet.applyTo(view) } } } } currentSize = size currentSize = size view.visibility = View.VISIBLE currentPosition = position viewModel.setIsIconViewLoaded(false) notifyAccessibilityChanged() notifyAccessibilityChanged() panelView.invalidateOutline() view.invalidate() view.invalidate() view.requestLayout() view.requestLayout() } } } } } } } } } } else if (panelViewController != null) { } else if (panelViewController != null) { val iconHolderView = view.requireViewById<View>(R.id.biometric_icon_frame) val iconHolderView = view.requireViewById<View>(R.id.biometric_icon_frame) val iconPadding = view.resources.getDimension(R.dimen.biometric_dialog_icon_padding) val iconPadding = view.resources.getDimension(R.dimen.biometric_dialog_icon_padding) Loading