Loading packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt +0 −1 Original line number Diff line number Diff line Loading @@ -191,7 +191,6 @@ class SideFpsOverlayViewBinderTest : SysuiTestCase() { val clickListenerCaptor = ArgumentCaptor.forClass(View.OnClickListener::class.java) verify(sideFpsView).setOnClickListener(clickListenerCaptor.capture()) clickListenerCaptor.value.onClick(sideFpsView) verify(lottieAnimationView).toggleAnimation() } } Loading packages/SystemUI/res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -3452,6 +3452,10 @@ <string name="keyguard_try_fingerprint">Use fingerprint to open</string> <!-- Accessibility announcement to inform user to unlock using the fingerprint sensor [CHAR LIMIT=NONE] --> <string name="accessibility_fingerprint_bouncer">Authentication required. Touch the fingerprint sensor to authenticate.</string> <!-- Accessibility action label for resuming animation --> <string name="resume_animation">Resume animation</string> <!-- Accessibility action label for pausing animation --> <string name="pause_animation">Pause animation</string> <!-- Content description for a chip in the status bar showing that the user is currently on a call. [CHAR LIMIT=NONE] --> <string name="ongoing_call_content_description">Ongoing call</string> Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt +67 −31 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ import android.view.LayoutInflater import android.view.View import android.view.WindowManager import android.view.accessibility.AccessibilityEvent import androidx.core.view.AccessibilityDelegateCompat import androidx.core.view.ViewCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView Loading Loading @@ -67,6 +70,59 @@ constructor( private val sfpsSensorInteractor: Lazy<SideFpsSensorInteractor>, private val windowManager: Lazy<WindowManager>, ) : CoreStartable { private val pauseDelegate: AccessibilityDelegateCompat = object : AccessibilityDelegateCompat() { override fun onInitializeAccessibilityNodeInfo( host: View, info: AccessibilityNodeInfoCompat, ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction( AccessibilityNodeInfoCompat.AccessibilityActionCompat( AccessibilityNodeInfoCompat.ACTION_CLICK, host.context.getString(R.string.pause_animation), ) ) } override fun dispatchPopulateAccessibilityEvent( host: View, event: AccessibilityEvent, ): Boolean { return if (event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { true } else { super.dispatchPopulateAccessibilityEvent(host, event) } } } private val resumeDelegate: AccessibilityDelegateCompat = object : AccessibilityDelegateCompat() { override fun onInitializeAccessibilityNodeInfo( host: View, info: AccessibilityNodeInfoCompat, ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction( AccessibilityNodeInfoCompat.AccessibilityActionCompat( AccessibilityNodeInfoCompat.ACTION_CLICK, host.context.getString(R.string.resume_animation), ) ) } override fun dispatchPopulateAccessibilityEvent( host: View, event: AccessibilityEvent, ): Boolean { return if (event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { true } else { super.dispatchPopulateAccessibilityEvent(host, event) } } } override fun start() { applicationScope.launch { Loading Loading @@ -135,6 +191,7 @@ constructor( overlayView!!.setOnClickListener { v -> v.requireViewById<LottieAnimationView>(R.id.sidefps_animation).toggleAnimation() } ViewCompat.setAccessibilityDelegate(overlayView!!, pauseDelegate) Log.d(TAG, "show(): adding overlayView $overlayView") windowManager.get().addView(overlayView, overlayViewModel.defaultOverlayViewParams) } Loading Loading @@ -177,29 +234,6 @@ constructor( overlayShowAnimator.start() /** * Intercepts TYPE_WINDOW_STATE_CHANGED accessibility event, preventing Talkback * from speaking @string/accessibility_fingerprint_label twice when sensor location * indicator is in focus */ it.setAccessibilityDelegate( object : View.AccessibilityDelegate() { override fun dispatchPopulateAccessibilityEvent( host: View, event: AccessibilityEvent, ): Boolean { return if ( event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED ) { true } else { super.dispatchPopulateAccessibilityEvent(host, event) } } } ) repeatOnLifecycle(Lifecycle.State.STARTED) { launch { viewModel.lottieCallbacks.collect { callbacks -> Loading @@ -224,6 +258,16 @@ constructor( } } } private fun LottieAnimationView.toggleAnimation() { if (isAnimating) { pauseAnimation() ViewCompat.setAccessibilityDelegate(this, resumeDelegate) } else { resumeAnimation() ViewCompat.setAccessibilityDelegate(this, pauseDelegate) } } } private fun LottieAnimationView.addOverlayDynamicColor(colorCallbacks: List<LottieCallback>) { Loading @@ -236,11 +280,3 @@ private fun LottieAnimationView.addOverlayDynamicColor(colorCallbacks: List<Lott resumeAnimation() } } fun LottieAnimationView.toggleAnimation() { if (isAnimating) { pauseAnimation() } else { resumeAnimation() } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt +0 −1 Original line number Diff line number Diff line Loading @@ -191,7 +191,6 @@ class SideFpsOverlayViewBinderTest : SysuiTestCase() { val clickListenerCaptor = ArgumentCaptor.forClass(View.OnClickListener::class.java) verify(sideFpsView).setOnClickListener(clickListenerCaptor.capture()) clickListenerCaptor.value.onClick(sideFpsView) verify(lottieAnimationView).toggleAnimation() } } Loading
packages/SystemUI/res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -3452,6 +3452,10 @@ <string name="keyguard_try_fingerprint">Use fingerprint to open</string> <!-- Accessibility announcement to inform user to unlock using the fingerprint sensor [CHAR LIMIT=NONE] --> <string name="accessibility_fingerprint_bouncer">Authentication required. Touch the fingerprint sensor to authenticate.</string> <!-- Accessibility action label for resuming animation --> <string name="resume_animation">Resume animation</string> <!-- Accessibility action label for pausing animation --> <string name="pause_animation">Pause animation</string> <!-- Content description for a chip in the status bar showing that the user is currently on a call. [CHAR LIMIT=NONE] --> <string name="ongoing_call_content_description">Ongoing call</string> Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt +67 −31 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ import android.view.LayoutInflater import android.view.View import android.view.WindowManager import android.view.accessibility.AccessibilityEvent import androidx.core.view.AccessibilityDelegateCompat import androidx.core.view.ViewCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView Loading Loading @@ -67,6 +70,59 @@ constructor( private val sfpsSensorInteractor: Lazy<SideFpsSensorInteractor>, private val windowManager: Lazy<WindowManager>, ) : CoreStartable { private val pauseDelegate: AccessibilityDelegateCompat = object : AccessibilityDelegateCompat() { override fun onInitializeAccessibilityNodeInfo( host: View, info: AccessibilityNodeInfoCompat, ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction( AccessibilityNodeInfoCompat.AccessibilityActionCompat( AccessibilityNodeInfoCompat.ACTION_CLICK, host.context.getString(R.string.pause_animation), ) ) } override fun dispatchPopulateAccessibilityEvent( host: View, event: AccessibilityEvent, ): Boolean { return if (event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { true } else { super.dispatchPopulateAccessibilityEvent(host, event) } } } private val resumeDelegate: AccessibilityDelegateCompat = object : AccessibilityDelegateCompat() { override fun onInitializeAccessibilityNodeInfo( host: View, info: AccessibilityNodeInfoCompat, ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction( AccessibilityNodeInfoCompat.AccessibilityActionCompat( AccessibilityNodeInfoCompat.ACTION_CLICK, host.context.getString(R.string.resume_animation), ) ) } override fun dispatchPopulateAccessibilityEvent( host: View, event: AccessibilityEvent, ): Boolean { return if (event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { true } else { super.dispatchPopulateAccessibilityEvent(host, event) } } } override fun start() { applicationScope.launch { Loading Loading @@ -135,6 +191,7 @@ constructor( overlayView!!.setOnClickListener { v -> v.requireViewById<LottieAnimationView>(R.id.sidefps_animation).toggleAnimation() } ViewCompat.setAccessibilityDelegate(overlayView!!, pauseDelegate) Log.d(TAG, "show(): adding overlayView $overlayView") windowManager.get().addView(overlayView, overlayViewModel.defaultOverlayViewParams) } Loading Loading @@ -177,29 +234,6 @@ constructor( overlayShowAnimator.start() /** * Intercepts TYPE_WINDOW_STATE_CHANGED accessibility event, preventing Talkback * from speaking @string/accessibility_fingerprint_label twice when sensor location * indicator is in focus */ it.setAccessibilityDelegate( object : View.AccessibilityDelegate() { override fun dispatchPopulateAccessibilityEvent( host: View, event: AccessibilityEvent, ): Boolean { return if ( event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED ) { true } else { super.dispatchPopulateAccessibilityEvent(host, event) } } } ) repeatOnLifecycle(Lifecycle.State.STARTED) { launch { viewModel.lottieCallbacks.collect { callbacks -> Loading @@ -224,6 +258,16 @@ constructor( } } } private fun LottieAnimationView.toggleAnimation() { if (isAnimating) { pauseAnimation() ViewCompat.setAccessibilityDelegate(this, resumeDelegate) } else { resumeAnimation() ViewCompat.setAccessibilityDelegate(this, pauseDelegate) } } } private fun LottieAnimationView.addOverlayDynamicColor(colorCallbacks: List<LottieCallback>) { Loading @@ -236,11 +280,3 @@ private fun LottieAnimationView.addOverlayDynamicColor(colorCallbacks: List<Lott resumeAnimation() } } fun LottieAnimationView.toggleAnimation() { if (isAnimating) { pauseAnimation() } else { resumeAnimation() } }