Loading packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SeekableSliderHapticPluginTest.kt +6 −8 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope Loading Loading @@ -75,7 +74,7 @@ class SeekableSliderHapticPluginTest : SysuiTestCase() { fun start_afterStop_startsTheTrackingAgain() = runOnStartedPlugin { // WHEN the plugin is restarted plugin.stop() plugin.start() plugin.startInScope(CoroutineScope(UnconfinedTestDispatcher(testScheduler))) // THEN the tracking begins again assertThat(plugin.isTracking).isTrue() Loading Loading @@ -131,22 +130,21 @@ class SeekableSliderHapticPluginTest : SysuiTestCase() { private fun runOnStartedPlugin(test: suspend TestScope.() -> Unit) = with(kosmos) { testScope.runTest { createPlugin(this, UnconfinedTestDispatcher(testScheduler)) // GIVEN that the plugin is started plugin.start() val pluginScope = CoroutineScope(UnconfinedTestDispatcher(testScheduler)) createPlugin() // GIVEN that the plugin is started in a test scope plugin.startInScope(pluginScope) // THEN run the test test() } } private fun createPlugin(scope: CoroutineScope, dispatcher: CoroutineDispatcher) { private fun createPlugin() { plugin = SeekableSliderHapticPlugin( vibratorHelper, kosmos.fakeSystemClock, dispatcher, scope, ) } Loading packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt→packages/SystemUI/src/com/android/systemui/haptics/slider/HapticSliderViewBinder.kt +40 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * Copyright (C) 2024 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. Loading @@ -14,33 +14,27 @@ * limitations under the License. */ package com.android.systemui.settings.brightness package com.android.systemui.haptics.slider import android.view.VelocityTracker import com.android.systemui.haptics.slider.SeekableSliderEventProducer /** Plugin component for the System UI brightness slider to incorporate dynamic haptics */ interface BrightnessSliderHapticPlugin { /** Finger velocity tracker */ val velocityTracker: VelocityTracker? get() = null /** Producer of slider events from the underlying [android.widget.SeekBar] */ val seekableSliderEventProducer: SeekableSliderEventProducer? get() = null import android.view.View import androidx.lifecycle.lifecycleScope import com.android.systemui.lifecycle.repeatWhenAttached import kotlinx.coroutines.awaitCancellation object HapticSliderViewBinder { /** * Start the plugin. * * This starts the tracking of slider states, events and triggering of haptic feedback. * Binds a [SeekableSliderHapticPlugin] to a [View]. The binded view should be a * [android.widget.SeekBar] or a container of a [android.widget.SeekBar] */ fun start() {} /** * Stop the plugin * * This stops the tracking of slider states, events and triggers of haptic feedback. */ fun stop() {} @JvmStatic fun bind(view: View?, plugin: SeekableSliderHapticPlugin) { view?.repeatWhenAttached { plugin.startInScope(lifecycleScope) try { awaitCancellation() } finally { plugin.stop() } } } } packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderHapticPlugin.kt +25 −28 Original line number Diff line number Diff line Loading @@ -20,11 +20,8 @@ import android.view.MotionEvent import android.view.VelocityTracker import android.widget.SeekBar import androidx.annotation.VisibleForTesting import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.util.time.SystemClock import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay Loading @@ -43,10 +40,8 @@ class SeekableSliderHapticPlugin constructor( vibratorHelper: VibratorHelper, systemClock: SystemClock, @Main private val mainDispatcher: CoroutineDispatcher, @Application private val applicationScope: CoroutineScope, sliderHapticFeedbackConfig: SliderHapticFeedbackConfig = SliderHapticFeedbackConfig(), sliderTrackerConfig: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(), private val sliderTrackerConfig: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(), ) { private val velocityTracker = VelocityTracker.obtain() Loading @@ -61,19 +56,15 @@ constructor( systemClock, ) private val sliderTracker = SeekableSliderTracker( sliderHapticFeedbackProvider, sliderEventProducer, mainDispatcher, sliderTrackerConfig, ) private var sliderTracker: SeekableSliderTracker? = null private var pluginScope: CoroutineScope? = null val isTracking: Boolean get() = sliderTracker.isTracking get() = sliderTracker?.isTracking == true val trackerState: SliderState get() = sliderTracker.currentState val trackerState: SliderState? get() = sliderTracker?.currentState /** * A waiting [Job] for a timer that estimates the key-up event when a key-down event is Loading @@ -89,14 +80,20 @@ constructor( get() = keyUpJob != null && keyUpJob?.isActive == true /** * Start the plugin. * * This starts the tracking of slider states, events and triggering of haptic feedback. * Specify the scope for the plugin's operations and start the slider tracker in this scope. * This also involves the key-up timer job. */ fun start() { if (!isTracking) { sliderTracker.startTracking() } fun startInScope(scope: CoroutineScope) { if (sliderTracker != null) stop() sliderTracker = SeekableSliderTracker( sliderHapticFeedbackProvider, sliderEventProducer, scope, sliderTrackerConfig, ) pluginScope = scope sliderTracker?.startTracking() } /** Loading @@ -104,7 +101,7 @@ constructor( * * This stops the tracking of slider states, events and triggers of haptic feedback. */ fun stop() = sliderTracker.stopTracking() fun stop() = sliderTracker?.stopTracking() /** React to a touch event */ fun onTouchEvent(event: MotionEvent?) { Loading Loading @@ -147,9 +144,9 @@ constructor( /** * An external key was pressed (e.g., a volume key). * * This event is used to estimate the key-up event based on by running a timer as a waiting * coroutine in the [keyUpTimerScope]. A key-up event in a slider corresponds to an onArrowUp * event. Therefore, [onArrowUp] must be called after the timeout. * This event is used to estimate the key-up event based on a running a timer as a waiting * coroutine in the [pluginScope]. A key-up event in a slider corresponds to an onArrowUp event. * Therefore, [onArrowUp] must be called after the timeout. */ fun onKeyDown() { if (!isTracking) return Loading @@ -159,7 +156,7 @@ constructor( keyUpJob?.cancel() } keyUpJob = applicationScope.launch { pluginScope?.launch { delay(KEY_UP_TIMEOUT) onArrowUp() } Loading packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt +5 −8 Original line number Diff line number Diff line Loading @@ -17,9 +17,7 @@ package com.android.systemui.haptics.slider import androidx.annotation.VisibleForTesting import com.android.systemui.dagger.qualifiers.Main import kotlin.math.abs import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay Loading @@ -31,21 +29,20 @@ import kotlinx.coroutines.launch * * The tracker runs a state machine to execute actions on touch-based events typical of a seekable * slider such as [android.widget.SeekBar]. Coroutines responsible for running the state machine, * collecting slider events and maintaining waiting states are run on the main thread via the * [com.android.systemui.dagger.qualifiers.Main] coroutine dispatcher. * collecting slider events and maintaining waiting states are run on the provided [CoroutineScope]. * * @param[sliderStateListener] Listener of the slider state. * @param[sliderEventProducer] Producer of slider events arising from the slider. * @param[mainDispatcher] [CoroutineDispatcher] used to launch coroutines for the collection of * slider events and the launch of timer jobs. * @param[trackerScope] [CoroutineScope] used to launch coroutines for the collection of slider * events and the launch of timer jobs. * @property[config] Configuration parameters of the slider tracker. */ class SeekableSliderTracker( sliderStateListener: SliderStateListener, sliderEventProducer: SliderEventProducer, @Main mainDispatcher: CoroutineDispatcher, trackerScope: CoroutineScope, private val config: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(), ) : SliderTracker(CoroutineScope(mainDispatcher), sliderStateListener, sliderEventProducer) { ) : SliderTracker(trackerScope, sliderStateListener, sliderEventProducer) { // History of the latest progress collected from slider events private var latestProgress = 0f Loading packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java +14 −42 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ import com.android.internal.logging.UiEventLogger; import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.Gefingerpoken; import com.android.systemui.classifier.Classifier; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.haptics.slider.SeekableSliderEventProducer; import com.android.systemui.haptics.slider.HapticSliderViewBinder; import com.android.systemui.haptics.slider.SeekableSliderHapticPlugin; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.res.R; import com.android.systemui.statusbar.VibratorHelper; Loading @@ -42,8 +42,6 @@ import com.android.systemui.util.time.SystemClock; import javax.inject.Inject; import kotlinx.coroutines.CoroutineDispatcher; /** * {@code ViewController} for a {@code BrightnessSliderView} * Loading @@ -63,23 +61,16 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV private final FalsingManager mFalsingManager; private final UiEventLogger mUiEventLogger; private final BrightnessSliderHapticPlugin mBrightnessSliderHapticPlugin; private final SeekableSliderHapticPlugin mBrightnessSliderHapticPlugin; private final Gefingerpoken mOnInterceptListener = new Gefingerpoken() { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { mBrightnessSliderHapticPlugin.onTouchEvent(ev); int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { mFalsingManager.isFalseTouch(Classifier.BRIGHTNESS_SLIDER); if (mBrightnessSliderHapticPlugin.getVelocityTracker() != null) { mBrightnessSliderHapticPlugin.getVelocityTracker().clear(); } } else if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) { if (mBrightnessSliderHapticPlugin.getVelocityTracker() != null) { mBrightnessSliderHapticPlugin.getVelocityTracker().addMovement(ev); } } return false; } Loading @@ -93,7 +84,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV BrightnessSliderView brightnessSliderView, FalsingManager falsingManager, UiEventLogger uiEventLogger, BrightnessSliderHapticPlugin brightnessSliderHapticPlugin) { SeekableSliderHapticPlugin brightnessSliderHapticPlugin) { super(brightnessSliderView); mFalsingManager = falsingManager; mUiEventLogger = uiEventLogger; Loading @@ -112,7 +103,6 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV protected void onViewAttached() { mView.setOnSeekBarChangeListener(mSeekListener); mView.setOnInterceptListener(mOnInterceptListener); mBrightnessSliderHapticPlugin.start(); } @Override Loading @@ -120,7 +110,6 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV mView.setOnSeekBarChangeListener(null); mView.setOnDispatchTouchEventListener(null); mView.setOnInterceptListener(null); mBrightnessSliderHapticPlugin.stop(); } @Override Loading Loading @@ -225,10 +214,8 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (mListener != null) { mListener.onChanged(mTracking, progress, false); SeekableSliderEventProducer eventProducer = mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer(); if (eventProducer != null && fromUser) { eventProducer.onProgressChanged(seekBar, progress, fromUser); if (fromUser) { mBrightnessSliderHapticPlugin.onProgressChanged(seekBar, progress, fromUser); } } } Loading @@ -239,11 +226,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV mUiEventLogger.log(BrightnessSliderEvent.BRIGHTNESS_SLIDER_STARTED_TRACKING_TOUCH); if (mListener != null) { mListener.onChanged(mTracking, getValue(), false); SeekableSliderEventProducer eventProducer = mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer(); if (eventProducer != null) { eventProducer.onStartTrackingTouch(seekBar); } mBrightnessSliderHapticPlugin.onStartTrackingTouch(seekBar); } if (mMirrorController != null) { Loading @@ -258,11 +241,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV mUiEventLogger.log(BrightnessSliderEvent.BRIGHTNESS_SLIDER_STOPPED_TRACKING_TOUCH); if (mListener != null) { mListener.onChanged(mTracking, getValue(), true); SeekableSliderEventProducer eventProducer = mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer(); if (eventProducer != null) { eventProducer.onStopTrackingTouch(seekBar); } mBrightnessSliderHapticPlugin.onStopTrackingTouch(seekBar); } if (mMirrorController != null) { Loading @@ -280,21 +259,18 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV private final UiEventLogger mUiEventLogger; private final VibratorHelper mVibratorHelper; private final SystemClock mSystemClock; private final CoroutineDispatcher mMainDispatcher; @Inject public Factory( FalsingManager falsingManager, UiEventLogger uiEventLogger, VibratorHelper vibratorHelper, SystemClock clock, @Main CoroutineDispatcher mainDispatcher SystemClock clock ) { mFalsingManager = falsingManager; mUiEventLogger = uiEventLogger; mVibratorHelper = vibratorHelper; mSystemClock = clock; mMainDispatcher = mainDispatcher; } /** Loading @@ -310,15 +286,11 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV int layout = getLayout(); BrightnessSliderView root = (BrightnessSliderView) LayoutInflater.from(context) .inflate(layout, viewRoot, false); BrightnessSliderHapticPlugin plugin; if (hapticBrightnessSlider()) { plugin = new BrightnessSliderHapticPluginImpl( SeekableSliderHapticPlugin plugin = new SeekableSliderHapticPlugin( mVibratorHelper, mSystemClock, mMainDispatcher ); } else { plugin = new BrightnessSliderHapticPlugin() {}; mSystemClock); if (hapticBrightnessSlider()) { HapticSliderViewBinder.bind(viewRoot, plugin); } return new BrightnessSliderController(root, mFalsingManager, mUiEventLogger, plugin); } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SeekableSliderHapticPluginTest.kt +6 −8 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope Loading Loading @@ -75,7 +74,7 @@ class SeekableSliderHapticPluginTest : SysuiTestCase() { fun start_afterStop_startsTheTrackingAgain() = runOnStartedPlugin { // WHEN the plugin is restarted plugin.stop() plugin.start() plugin.startInScope(CoroutineScope(UnconfinedTestDispatcher(testScheduler))) // THEN the tracking begins again assertThat(plugin.isTracking).isTrue() Loading Loading @@ -131,22 +130,21 @@ class SeekableSliderHapticPluginTest : SysuiTestCase() { private fun runOnStartedPlugin(test: suspend TestScope.() -> Unit) = with(kosmos) { testScope.runTest { createPlugin(this, UnconfinedTestDispatcher(testScheduler)) // GIVEN that the plugin is started plugin.start() val pluginScope = CoroutineScope(UnconfinedTestDispatcher(testScheduler)) createPlugin() // GIVEN that the plugin is started in a test scope plugin.startInScope(pluginScope) // THEN run the test test() } } private fun createPlugin(scope: CoroutineScope, dispatcher: CoroutineDispatcher) { private fun createPlugin() { plugin = SeekableSliderHapticPlugin( vibratorHelper, kosmos.fakeSystemClock, dispatcher, scope, ) } Loading
packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt→packages/SystemUI/src/com/android/systemui/haptics/slider/HapticSliderViewBinder.kt +40 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * Copyright (C) 2024 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. Loading @@ -14,33 +14,27 @@ * limitations under the License. */ package com.android.systemui.settings.brightness package com.android.systemui.haptics.slider import android.view.VelocityTracker import com.android.systemui.haptics.slider.SeekableSliderEventProducer /** Plugin component for the System UI brightness slider to incorporate dynamic haptics */ interface BrightnessSliderHapticPlugin { /** Finger velocity tracker */ val velocityTracker: VelocityTracker? get() = null /** Producer of slider events from the underlying [android.widget.SeekBar] */ val seekableSliderEventProducer: SeekableSliderEventProducer? get() = null import android.view.View import androidx.lifecycle.lifecycleScope import com.android.systemui.lifecycle.repeatWhenAttached import kotlinx.coroutines.awaitCancellation object HapticSliderViewBinder { /** * Start the plugin. * * This starts the tracking of slider states, events and triggering of haptic feedback. * Binds a [SeekableSliderHapticPlugin] to a [View]. The binded view should be a * [android.widget.SeekBar] or a container of a [android.widget.SeekBar] */ fun start() {} /** * Stop the plugin * * This stops the tracking of slider states, events and triggers of haptic feedback. */ fun stop() {} @JvmStatic fun bind(view: View?, plugin: SeekableSliderHapticPlugin) { view?.repeatWhenAttached { plugin.startInScope(lifecycleScope) try { awaitCancellation() } finally { plugin.stop() } } } }
packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderHapticPlugin.kt +25 −28 Original line number Diff line number Diff line Loading @@ -20,11 +20,8 @@ import android.view.MotionEvent import android.view.VelocityTracker import android.widget.SeekBar import androidx.annotation.VisibleForTesting import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.util.time.SystemClock import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay Loading @@ -43,10 +40,8 @@ class SeekableSliderHapticPlugin constructor( vibratorHelper: VibratorHelper, systemClock: SystemClock, @Main private val mainDispatcher: CoroutineDispatcher, @Application private val applicationScope: CoroutineScope, sliderHapticFeedbackConfig: SliderHapticFeedbackConfig = SliderHapticFeedbackConfig(), sliderTrackerConfig: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(), private val sliderTrackerConfig: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(), ) { private val velocityTracker = VelocityTracker.obtain() Loading @@ -61,19 +56,15 @@ constructor( systemClock, ) private val sliderTracker = SeekableSliderTracker( sliderHapticFeedbackProvider, sliderEventProducer, mainDispatcher, sliderTrackerConfig, ) private var sliderTracker: SeekableSliderTracker? = null private var pluginScope: CoroutineScope? = null val isTracking: Boolean get() = sliderTracker.isTracking get() = sliderTracker?.isTracking == true val trackerState: SliderState get() = sliderTracker.currentState val trackerState: SliderState? get() = sliderTracker?.currentState /** * A waiting [Job] for a timer that estimates the key-up event when a key-down event is Loading @@ -89,14 +80,20 @@ constructor( get() = keyUpJob != null && keyUpJob?.isActive == true /** * Start the plugin. * * This starts the tracking of slider states, events and triggering of haptic feedback. * Specify the scope for the plugin's operations and start the slider tracker in this scope. * This also involves the key-up timer job. */ fun start() { if (!isTracking) { sliderTracker.startTracking() } fun startInScope(scope: CoroutineScope) { if (sliderTracker != null) stop() sliderTracker = SeekableSliderTracker( sliderHapticFeedbackProvider, sliderEventProducer, scope, sliderTrackerConfig, ) pluginScope = scope sliderTracker?.startTracking() } /** Loading @@ -104,7 +101,7 @@ constructor( * * This stops the tracking of slider states, events and triggers of haptic feedback. */ fun stop() = sliderTracker.stopTracking() fun stop() = sliderTracker?.stopTracking() /** React to a touch event */ fun onTouchEvent(event: MotionEvent?) { Loading Loading @@ -147,9 +144,9 @@ constructor( /** * An external key was pressed (e.g., a volume key). * * This event is used to estimate the key-up event based on by running a timer as a waiting * coroutine in the [keyUpTimerScope]. A key-up event in a slider corresponds to an onArrowUp * event. Therefore, [onArrowUp] must be called after the timeout. * This event is used to estimate the key-up event based on a running a timer as a waiting * coroutine in the [pluginScope]. A key-up event in a slider corresponds to an onArrowUp event. * Therefore, [onArrowUp] must be called after the timeout. */ fun onKeyDown() { if (!isTracking) return Loading @@ -159,7 +156,7 @@ constructor( keyUpJob?.cancel() } keyUpJob = applicationScope.launch { pluginScope?.launch { delay(KEY_UP_TIMEOUT) onArrowUp() } Loading
packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt +5 −8 Original line number Diff line number Diff line Loading @@ -17,9 +17,7 @@ package com.android.systemui.haptics.slider import androidx.annotation.VisibleForTesting import com.android.systemui.dagger.qualifiers.Main import kotlin.math.abs import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay Loading @@ -31,21 +29,20 @@ import kotlinx.coroutines.launch * * The tracker runs a state machine to execute actions on touch-based events typical of a seekable * slider such as [android.widget.SeekBar]. Coroutines responsible for running the state machine, * collecting slider events and maintaining waiting states are run on the main thread via the * [com.android.systemui.dagger.qualifiers.Main] coroutine dispatcher. * collecting slider events and maintaining waiting states are run on the provided [CoroutineScope]. * * @param[sliderStateListener] Listener of the slider state. * @param[sliderEventProducer] Producer of slider events arising from the slider. * @param[mainDispatcher] [CoroutineDispatcher] used to launch coroutines for the collection of * slider events and the launch of timer jobs. * @param[trackerScope] [CoroutineScope] used to launch coroutines for the collection of slider * events and the launch of timer jobs. * @property[config] Configuration parameters of the slider tracker. */ class SeekableSliderTracker( sliderStateListener: SliderStateListener, sliderEventProducer: SliderEventProducer, @Main mainDispatcher: CoroutineDispatcher, trackerScope: CoroutineScope, private val config: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(), ) : SliderTracker(CoroutineScope(mainDispatcher), sliderStateListener, sliderEventProducer) { ) : SliderTracker(trackerScope, sliderStateListener, sliderEventProducer) { // History of the latest progress collected from slider events private var latestProgress = 0f Loading
packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java +14 −42 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ import com.android.internal.logging.UiEventLogger; import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.Gefingerpoken; import com.android.systemui.classifier.Classifier; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.haptics.slider.SeekableSliderEventProducer; import com.android.systemui.haptics.slider.HapticSliderViewBinder; import com.android.systemui.haptics.slider.SeekableSliderHapticPlugin; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.res.R; import com.android.systemui.statusbar.VibratorHelper; Loading @@ -42,8 +42,6 @@ import com.android.systemui.util.time.SystemClock; import javax.inject.Inject; import kotlinx.coroutines.CoroutineDispatcher; /** * {@code ViewController} for a {@code BrightnessSliderView} * Loading @@ -63,23 +61,16 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV private final FalsingManager mFalsingManager; private final UiEventLogger mUiEventLogger; private final BrightnessSliderHapticPlugin mBrightnessSliderHapticPlugin; private final SeekableSliderHapticPlugin mBrightnessSliderHapticPlugin; private final Gefingerpoken mOnInterceptListener = new Gefingerpoken() { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { mBrightnessSliderHapticPlugin.onTouchEvent(ev); int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { mFalsingManager.isFalseTouch(Classifier.BRIGHTNESS_SLIDER); if (mBrightnessSliderHapticPlugin.getVelocityTracker() != null) { mBrightnessSliderHapticPlugin.getVelocityTracker().clear(); } } else if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) { if (mBrightnessSliderHapticPlugin.getVelocityTracker() != null) { mBrightnessSliderHapticPlugin.getVelocityTracker().addMovement(ev); } } return false; } Loading @@ -93,7 +84,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV BrightnessSliderView brightnessSliderView, FalsingManager falsingManager, UiEventLogger uiEventLogger, BrightnessSliderHapticPlugin brightnessSliderHapticPlugin) { SeekableSliderHapticPlugin brightnessSliderHapticPlugin) { super(brightnessSliderView); mFalsingManager = falsingManager; mUiEventLogger = uiEventLogger; Loading @@ -112,7 +103,6 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV protected void onViewAttached() { mView.setOnSeekBarChangeListener(mSeekListener); mView.setOnInterceptListener(mOnInterceptListener); mBrightnessSliderHapticPlugin.start(); } @Override Loading @@ -120,7 +110,6 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV mView.setOnSeekBarChangeListener(null); mView.setOnDispatchTouchEventListener(null); mView.setOnInterceptListener(null); mBrightnessSliderHapticPlugin.stop(); } @Override Loading Loading @@ -225,10 +214,8 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (mListener != null) { mListener.onChanged(mTracking, progress, false); SeekableSliderEventProducer eventProducer = mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer(); if (eventProducer != null && fromUser) { eventProducer.onProgressChanged(seekBar, progress, fromUser); if (fromUser) { mBrightnessSliderHapticPlugin.onProgressChanged(seekBar, progress, fromUser); } } } Loading @@ -239,11 +226,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV mUiEventLogger.log(BrightnessSliderEvent.BRIGHTNESS_SLIDER_STARTED_TRACKING_TOUCH); if (mListener != null) { mListener.onChanged(mTracking, getValue(), false); SeekableSliderEventProducer eventProducer = mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer(); if (eventProducer != null) { eventProducer.onStartTrackingTouch(seekBar); } mBrightnessSliderHapticPlugin.onStartTrackingTouch(seekBar); } if (mMirrorController != null) { Loading @@ -258,11 +241,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV mUiEventLogger.log(BrightnessSliderEvent.BRIGHTNESS_SLIDER_STOPPED_TRACKING_TOUCH); if (mListener != null) { mListener.onChanged(mTracking, getValue(), true); SeekableSliderEventProducer eventProducer = mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer(); if (eventProducer != null) { eventProducer.onStopTrackingTouch(seekBar); } mBrightnessSliderHapticPlugin.onStopTrackingTouch(seekBar); } if (mMirrorController != null) { Loading @@ -280,21 +259,18 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV private final UiEventLogger mUiEventLogger; private final VibratorHelper mVibratorHelper; private final SystemClock mSystemClock; private final CoroutineDispatcher mMainDispatcher; @Inject public Factory( FalsingManager falsingManager, UiEventLogger uiEventLogger, VibratorHelper vibratorHelper, SystemClock clock, @Main CoroutineDispatcher mainDispatcher SystemClock clock ) { mFalsingManager = falsingManager; mUiEventLogger = uiEventLogger; mVibratorHelper = vibratorHelper; mSystemClock = clock; mMainDispatcher = mainDispatcher; } /** Loading @@ -310,15 +286,11 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV int layout = getLayout(); BrightnessSliderView root = (BrightnessSliderView) LayoutInflater.from(context) .inflate(layout, viewRoot, false); BrightnessSliderHapticPlugin plugin; if (hapticBrightnessSlider()) { plugin = new BrightnessSliderHapticPluginImpl( SeekableSliderHapticPlugin plugin = new SeekableSliderHapticPlugin( mVibratorHelper, mSystemClock, mMainDispatcher ); } else { plugin = new BrightnessSliderHapticPlugin() {}; mSystemClock); if (hapticBrightnessSlider()) { HapticSliderViewBinder.bind(viewRoot, plugin); } return new BrightnessSliderController(root, mFalsingManager, mUiEventLogger, plugin); } Loading