View-Binder architecture on haptic sliders.
The SliderTracker and SeekableSliderHapticPlugin are refactored to
depend on a CoroutineScope. The HapticSliderViewBinder is introduced to
provide this as the lifecycle scope of a binded view. The appropriate UI
widgets are used for the binding depending on the use case: Brightness
slider for brighness slider haptics, and individual volume sliders for
volume slider haptics.
Test: atest SystemUiRoboTests:SeekableSliderHapticPluginTest
Test: atest SystemUITests:VolumeDialogImplTest
Test: atest SystemUITests:BrightnessSliderControllerTest
Flag: ACONFIG com.android.systemui.haptic_brightness_slider TRUNKFOOD
Flag: ACONFIG com.android.systemui.haptic_volume_slider STAGING
Bug: 295932558
Bug: 316953430
Change-Id: I15d4b67dabfba39d9fd3240d3505c33f386443b5
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SeekableSliderHapticPluginTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SeekableSliderHapticPluginTest.kt
index ea766f8..805b4a8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SeekableSliderHapticPluginTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SeekableSliderHapticPluginTest.kt
@@ -26,7 +26,6 @@
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
@@ -75,7 +74,7 @@
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()
@@ -131,22 +130,21 @@
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,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/HapticSliderViewBinder.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/HapticSliderViewBinder.kt
new file mode 100644
index 0000000..304fdd6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/HapticSliderViewBinder.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ * 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.systemui.haptics.slider
+
+import android.view.View
+import androidx.lifecycle.lifecycleScope
+import com.android.systemui.lifecycle.repeatWhenAttached
+import kotlinx.coroutines.awaitCancellation
+
+object HapticSliderViewBinder {
+ /**
+ * Binds a [SeekableSliderHapticPlugin] to a [View]. The binded view should be a
+ * [android.widget.SeekBar] or a container of a [android.widget.SeekBar]
+ */
+ @JvmStatic
+ fun bind(view: View?, plugin: SeekableSliderHapticPlugin) {
+ view?.repeatWhenAttached {
+ plugin.startInScope(lifecycleScope)
+ try {
+ awaitCancellation()
+ } finally {
+ plugin.stop()
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderHapticPlugin.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderHapticPlugin.kt
index 58fb6a9..931a869 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderHapticPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderHapticPlugin.kt
@@ -20,11 +20,8 @@
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
@@ -43,10 +40,8 @@
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()
@@ -61,19 +56,15 @@
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
@@ -89,14 +80,20 @@
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()
}
/**
@@ -104,7 +101,7 @@
*
* 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?) {
@@ -147,9 +144,9 @@
/**
* 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
@@ -159,7 +156,7 @@
keyUpJob?.cancel()
}
keyUpJob =
- applicationScope.launch {
+ pluginScope?.launch {
delay(KEY_UP_TIMEOUT)
onArrowUp()
}
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt
index 10098fa..0af3038 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt
@@ -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
@@ -31,21 +29,20 @@
*
* 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
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
index be1fa2b..29ed4c8 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
@@ -30,11 +30,11 @@
import com.android.internal.logging.UiEventLogger;
import com.android.settingslib.RestrictedLockUtils;
import com.android.systemui.Gefingerpoken;
-import com.android.systemui.res.R;
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;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.util.ViewController;
@@ -42,8 +42,6 @@
import javax.inject.Inject;
-import kotlinx.coroutines.CoroutineDispatcher;
-
/**
* {@code ViewController} for a {@code BrightnessSliderView}
*
@@ -63,23 +61,16 @@
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;
}
@@ -93,7 +84,7 @@
BrightnessSliderView brightnessSliderView,
FalsingManager falsingManager,
UiEventLogger uiEventLogger,
- BrightnessSliderHapticPlugin brightnessSliderHapticPlugin) {
+ SeekableSliderHapticPlugin brightnessSliderHapticPlugin) {
super(brightnessSliderView);
mFalsingManager = falsingManager;
mUiEventLogger = uiEventLogger;
@@ -112,7 +103,6 @@
protected void onViewAttached() {
mView.setOnSeekBarChangeListener(mSeekListener);
mView.setOnInterceptListener(mOnInterceptListener);
- mBrightnessSliderHapticPlugin.start();
}
@Override
@@ -120,7 +110,6 @@
mView.setOnSeekBarChangeListener(null);
mView.setOnDispatchTouchEventListener(null);
mView.setOnInterceptListener(null);
- mBrightnessSliderHapticPlugin.stop();
}
@Override
@@ -225,10 +214,8 @@
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);
}
}
}
@@ -239,11 +226,7 @@
mUiEventLogger.log(BrightnessSliderEvent.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) {
@@ -258,11 +241,7 @@
mUiEventLogger.log(BrightnessSliderEvent.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) {
@@ -280,21 +259,18 @@
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;
}
/**
@@ -310,15 +286,11 @@
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);
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt
deleted file mode 100644
index f775114..0000000
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt
+++ /dev/null
@@ -1,46 +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.systemui.settings.brightness
-
-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
-
- /**
- * Start the plugin.
- *
- * This starts the tracking of slider states, events and triggering of haptic feedback.
- */
- fun start() {}
-
- /**
- * Stop the plugin
- *
- * This stops the tracking of slider states, events and triggers of haptic feedback.
- */
- fun stop() {}
-}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt
deleted file mode 100644
index 32561f0..0000000
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt
+++ /dev/null
@@ -1,69 +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.systemui.settings.brightness
-
-import android.view.VelocityTracker
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.haptics.slider.SeekableSliderEventProducer
-import com.android.systemui.haptics.slider.SeekableSliderTracker
-import com.android.systemui.haptics.slider.SliderHapticFeedbackProvider
-import com.android.systemui.haptics.slider.SliderTracker
-import com.android.systemui.statusbar.VibratorHelper
-import com.android.systemui.util.time.SystemClock
-import kotlinx.coroutines.CoroutineDispatcher
-
-/**
- * Implementation of the [BrightnessSliderHapticPlugin].
- *
- * For the specifics of the brightness slider in System UI, a [SeekableSliderEventProducer] is used
- * as the producer of slider events, a [SliderHapticFeedbackProvider] is used as the listener of
- * slider states to play haptic feedback depending on the state, and a [SeekableSliderTracker] is
- * used as the state machine handler that tracks and manipulates the slider state.
- */
-class BrightnessSliderHapticPluginImpl
-@JvmOverloads
-constructor(
- vibratorHelper: VibratorHelper,
- systemClock: SystemClock,
- @Main mainDispatcher: CoroutineDispatcher,
- override val velocityTracker: VelocityTracker = VelocityTracker.obtain(),
- override val seekableSliderEventProducer: SeekableSliderEventProducer =
- SeekableSliderEventProducer(),
-) : BrightnessSliderHapticPlugin {
-
- private val sliderHapticFeedbackProvider: SliderHapticFeedbackProvider =
- SliderHapticFeedbackProvider(vibratorHelper, velocityTracker, clock = systemClock)
- private val sliderTracker: SliderTracker =
- SeekableSliderTracker(
- sliderHapticFeedbackProvider,
- seekableSliderEventProducer,
- mainDispatcher,
- )
-
- val isTracking: Boolean
- get() = sliderTracker.isTracking
-
- override fun start() {
- if (!sliderTracker.isTracking) {
- sliderTracker.startTracking()
- }
- }
-
- override fun stop() {
- sliderTracker.stopTracking()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index ce6d740..90c5c62 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -116,9 +116,8 @@
import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
import com.android.systemui.Prefs;
-import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.haptics.slider.HapticSliderViewBinder;
import com.android.systemui.haptics.slider.SeekableSliderHapticPlugin;
import com.android.systemui.haptics.slider.SliderHapticFeedbackConfig;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
@@ -145,9 +144,6 @@
import java.util.List;
import java.util.function.Consumer;
-import kotlinx.coroutines.CoroutineDispatcher;
-import kotlinx.coroutines.CoroutineScope;
-
/**
* Visual presentation of the volume dialog.
*
@@ -311,8 +307,6 @@
private int mOrientation;
private final Lazy<SecureSettings> mSecureSettings;
private int mDialogTimeoutMillis;
- private final CoroutineDispatcher mMainDispatcher;
- private final CoroutineScope mApplicationScope;
private final VibratorHelper mVibratorHelper;
private final com.android.systemui.util.time.SystemClock mSystemClock;
@@ -333,14 +327,10 @@
DumpManager dumpManager,
Lazy<SecureSettings> secureSettings,
VibratorHelper vibratorHelper,
- @Main CoroutineDispatcher mainDispatcher,
- @Application CoroutineScope applicationScope,
com.android.systemui.util.time.SystemClock systemClock) {
mContext =
new ContextThemeWrapper(context, R.style.volume_dialog_theme);
mHandler = new H(looper);
- mMainDispatcher = mainDispatcher;
- mApplicationScope = applicationScope;
mVibratorHelper = vibratorHelper;
mSystemClock = systemClock;
mShouldListenForJank = shouldListenForJank;
@@ -858,7 +848,10 @@
row.header.setFilters(new InputFilter[] {new InputFilter.LengthFilter(13)});
}
row.slider = row.view.findViewById(R.id.volume_row_slider);
- row.createPlugin(mVibratorHelper, mSystemClock, mMainDispatcher, mApplicationScope);
+ if (hapticVolumeSlider()) {
+ row.createPlugin(mVibratorHelper, mSystemClock);
+ HapticSliderViewBinder.bind(row.slider, row.mHapticPlugin);
+ }
row.slider.setOnSeekBarChangeListener(new VolumeSeekBarChangeListener(row));
row.number = row.view.findViewById(R.id.volume_number);
@@ -1498,7 +1491,7 @@
for (int i = 0; i < mRows.size(); i++) {
VolumeRow row = mRows.get(i);
if (row.slider.getVisibility() == VISIBLE) {
- row.addHaptics();
+ row.addTouchListener();
}
}
Trace.endSection();
@@ -2620,17 +2613,13 @@
void createPlugin(
VibratorHelper vibratorHelper,
- com.android.systemui.util.time.SystemClock systemClock,
- CoroutineDispatcher mainDispatcher,
- CoroutineScope applicationScope) {
- if (!hapticVolumeSlider() || mHapticPlugin != null) return;
+ com.android.systemui.util.time.SystemClock systemClock) {
+ if (mHapticPlugin != null) return;
mHapticPlugin = new SeekableSliderHapticPlugin(
- vibratorHelper,
- systemClock,
- mainDispatcher,
- applicationScope,
- sSliderHapticFeedbackConfig);
+ vibratorHelper,
+ systemClock,
+ sSliderHapticFeedbackConfig);
}
@@ -2647,19 +2636,9 @@
});
}
- void addHaptics() {
- if (mHapticPlugin != null) {
- addTouchListener();
- mHapticPlugin.start();
- }
- }
-
@SuppressLint("ClickableViewAccessibility")
void removeHaptics() {
slider.setOnTouchListener(null);
- if (mHapticPlugin != null) {
- mHapticPlugin.stop();
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index b1bfbe0..303531e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -23,8 +23,6 @@
import com.android.internal.jank.InteractionJankMonitor;
import com.android.systemui.CoreStartable;
-import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.plugins.VolumeDialog;
@@ -55,9 +53,6 @@
import dagger.multibindings.IntoMap;
import dagger.multibindings.IntoSet;
-import kotlinx.coroutines.CoroutineDispatcher;
-import kotlinx.coroutines.CoroutineScope;
-
/** Dagger Module for code in the volume package. */
@Module(
subcomponents = {
@@ -107,8 +102,6 @@
DumpManager dumpManager,
Lazy<SecureSettings> secureSettings,
VibratorHelper vibratorHelper,
- @Main CoroutineDispatcher mainDispatcher,
- @Application CoroutineScope applicationScope,
SystemClock systemClock) {
VolumeDialogImpl impl = new VolumeDialogImpl(
context,
@@ -127,8 +120,6 @@
dumpManager,
secureSettings,
vibratorHelper,
- mainDispatcher,
- applicationScope,
systemClock);
impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
impl.setAutomute(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt
index db04962..796d6d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt
@@ -20,8 +20,8 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestCoroutineScheduler
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
@@ -36,6 +36,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class SeekableSliderTrackerTest : SysuiTestCase() {
@@ -51,7 +52,7 @@
@Test
fun initializeSliderTracker_startsTracking() = runTest {
// GIVEN Initialized tracker
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// THEN the tracker job is active
assertThat(mSeekableSliderTracker.isTracking).isTrue()
@@ -61,7 +62,7 @@
fun stopTracking_onAnyState_resetsToIdle() = runTest {
enumValues<SliderState>().forEach {
// GIVEN Initialized tracker
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a state in the state machine
mSeekableSliderTracker.setState(it)
@@ -79,7 +80,7 @@
@Test
fun initializeSliderTracker_isIdle() = runTest {
// GIVEN Initialized tracker
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// THEN The state is idle and the listener is not called to play haptics
assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE)
@@ -88,7 +89,7 @@
@Test
fun startsTrackingTouch_onIdle_entersWaitState() = runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a start of tracking touch event
val progress = 0f
@@ -106,7 +107,7 @@
@Test
fun waitCompletes_onWait_movesToHandleAcquired() = runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a start of tracking touch event that moves the tracker to WAIT
val progress = 0f
@@ -126,7 +127,7 @@
@Test
fun impreciseTouch_onWait_movesToHandleAcquired() = runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
// slider
@@ -151,7 +152,7 @@
@Test
fun trackJump_onWait_movesToJumpTrackLocationSelected() = runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
// slider
@@ -175,7 +176,7 @@
@Test
fun upperBookendSelection_onWait_movesToBookendSelected() = runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
// slider
@@ -197,7 +198,7 @@
@Test
fun lowerBookendSelection_onWait_movesToBookendSelected() = runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
// slider
@@ -219,7 +220,7 @@
@Test
fun stopTracking_onWait_whenWaitingJobIsActive_resetsToIdle() = runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the
// slider
@@ -240,7 +241,7 @@
@Test
fun progressChangeByUser_onJumpTrackLocationSelected_movesToDragHandleDragging() = runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a JUMP_TRACK_LOCATION_SELECTED state
mSeekableSliderTracker.setState(SliderState.JUMP_TRACK_LOCATION_SELECTED)
@@ -256,7 +257,7 @@
@Test
fun touchRelease_onJumpTrackLocationSelected_movesToIdle() = runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a JUMP_TRACK_LOCATION_SELECTED state
mSeekableSliderTracker.setState(SliderState.JUMP_TRACK_LOCATION_SELECTED)
@@ -272,7 +273,7 @@
@Test
fun progressChangeByUser_onJumpBookendSelected_movesToDragHandleDragging() = runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a JUMP_BOOKEND_SELECTED state
mSeekableSliderTracker.setState(SliderState.JUMP_BOOKEND_SELECTED)
@@ -288,7 +289,7 @@
@Test
fun touchRelease_onJumpBookendSelected_movesToIdle() = runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a JUMP_BOOKEND_SELECTED state
mSeekableSliderTracker.setState(SliderState.JUMP_BOOKEND_SELECTED)
@@ -306,7 +307,7 @@
@Test
fun progressChangeByUser_onHandleAcquired_movesToDragHandleDragging() = runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a DRAG_HANDLE_ACQUIRED_BY_TOUCH state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH)
@@ -325,7 +326,7 @@
@Test
fun touchRelease_onHandleAcquired_movesToIdle() = runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a DRAG_HANDLE_ACQUIRED_BY_TOUCH state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH)
@@ -344,7 +345,7 @@
@Test
fun progressChangeByUser_onHandleDragging_progressOutsideOfBookends_doesNotChangeState() =
runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a DRAG_HANDLE_DRAGGING state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING)
@@ -366,7 +367,7 @@
fun progressChangeByUser_onHandleDragging_reachesLowerBookend_movesToHandleReachedBookend() =
runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a DRAG_HANDLE_DRAGGING state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING)
@@ -389,7 +390,7 @@
fun progressChangeByUser_onHandleDragging_reachesUpperBookend_movesToHandleReachedBookend() =
runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a DRAG_HANDLE_DRAGGING state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING)
@@ -410,7 +411,7 @@
@Test
fun touchRelease_onHandleDragging_movesToIdle() = runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a DRAG_HANDLE_DRAGGING state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING)
@@ -430,7 +431,7 @@
fun progressChangeByUser_outsideOfBookendRange_onLowerBookend_movesToDragHandleDragging() =
runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
@@ -451,7 +452,7 @@
@Test
fun progressChangeByUser_insideOfBookendRange_onLowerBookend_doesNotChangeState() = runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
@@ -473,7 +474,7 @@
fun progressChangeByUser_outsideOfBookendRange_onUpperBookend_movesToDragHandleDragging() =
runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
@@ -494,7 +495,7 @@
@Test
fun progressChangeByUser_insideOfBookendRange_onUpperBookend_doesNotChangeState() = runTest {
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
@@ -514,7 +515,7 @@
@Test
fun touchRelease_onHandleReachedBookend_movesToIdle() = runTest {
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a DRAG_HANDLE_REACHED_BOOKEND state
mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND)
@@ -531,7 +532,7 @@
@Test
fun onProgressChangeByProgram_atTheMiddle_onIdle_movesToArrowHandleMovedOnce() = runTest {
// GIVEN an initialized tracker in the IDLE state
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
// GIVEN a progress due to an external source that lands at the middle of the slider
val progress = 0.5f
@@ -550,7 +551,7 @@
fun onProgressChangeByProgram_atUpperBookend_onIdle_movesToIdle() = runTest {
// GIVEN an initialized tracker in the IDLE state
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// GIVEN a progress due to an external source that lands at the upper bookend
val progress = config.upperBookendThreshold + 0.01f
@@ -567,7 +568,7 @@
fun onProgressChangeByProgram_atLowerBookend_onIdle_movesToIdle() = runTest {
// GIVEN an initialized tracker in the IDLE state
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
// WHEN a progress is recorded due to an external source that lands at the lower bookend
val progress = config.lowerBookendThreshold - 0.01f
@@ -583,7 +584,7 @@
@Test
fun onArrowUp_onArrowMovedOnce_movesToIdle() = runTest {
// GIVEN an initialized tracker in the ARROW_HANDLE_MOVED_ONCE state
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
mSeekableSliderTracker.setState(SliderState.ARROW_HANDLE_MOVED_ONCE)
// WHEN the external stimulus is released
@@ -598,7 +599,7 @@
@Test
fun onStartTrackingTouch_onArrowMovedOnce_movesToWait() = runTest {
// GIVEN an initialized tracker in the ARROW_HANDLE_MOVED_ONCE state
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
mSeekableSliderTracker.setState(SliderState.ARROW_HANDLE_MOVED_ONCE)
// WHEN the slider starts tracking touch
@@ -615,7 +616,7 @@
@Test
fun onProgressChangeByProgram_onArrowMovedOnce_movesToArrowMovesContinuously() = runTest {
// GIVEN an initialized tracker in the ARROW_HANDLE_MOVED_ONCE state
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
mSeekableSliderTracker.setState(SliderState.ARROW_HANDLE_MOVED_ONCE)
// WHEN the slider gets an external progress change
@@ -634,7 +635,7 @@
@Test
fun onArrowUp_onArrowMovesContinuously_movesToIdle() = runTest {
// GIVEN an initialized tracker in the ARROW_HANDLE_MOVES_CONTINUOUSLY state
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
mSeekableSliderTracker.setState(SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY)
// WHEN the external stimulus is released
@@ -649,7 +650,7 @@
@Test
fun onStartTrackingTouch_onArrowMovesContinuously_movesToWait() = runTest {
// GIVEN an initialized tracker in the ARROW_HANDLE_MOVES_CONTINUOUSLY state
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
mSeekableSliderTracker.setState(SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY)
// WHEN the slider starts tracking touch
@@ -665,7 +666,7 @@
@Test
fun onProgressChangeByProgram_onArrowMovesContinuously_preservesState() = runTest {
// GIVEN an initialized tracker in the ARROW_HANDLE_MOVES_CONTINUOUSLY state
- initTracker(testScheduler)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)))
mSeekableSliderTracker.setState(SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY)
// WHEN the slider changes progress programmatically at the middle
@@ -684,7 +685,7 @@
fun onProgramProgress_atLowerBookend_onArrowMovesContinuously_movesToIdle() = runTest {
// GIVEN an initialized tracker in the ARROW_HANDLE_MOVES_CONTINUOUSLY state
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
mSeekableSliderTracker.setState(SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY)
// WHEN the slider reaches the lower bookend programmatically
@@ -702,7 +703,7 @@
fun onProgramProgress_atUpperBookend_onArrowMovesContinuously_movesToIdle() = runTest {
// GIVEN an initialized tracker in the ARROW_HANDLE_MOVES_CONTINUOUSLY state
val config = SeekableSliderTrackerConfig()
- initTracker(testScheduler, config)
+ initTracker(CoroutineScope(UnconfinedTestDispatcher(testScheduler)), config)
mSeekableSliderTracker.setState(SliderState.ARROW_HANDLE_MOVES_CONTINUOUSLY)
// WHEN the slider reaches the lower bookend programmatically
@@ -718,16 +719,11 @@
@OptIn(ExperimentalCoroutinesApi::class)
private fun initTracker(
- scheduler: TestCoroutineScheduler,
+ scope: CoroutineScope,
config: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(),
) {
mSeekableSliderTracker =
- SeekableSliderTracker(
- sliderStateListener,
- sliderEventProducer,
- UnconfinedTestDispatcher(scheduler),
- config
- )
+ SeekableSliderTracker(sliderStateListener, sliderEventProducer, scope, config)
mSeekableSliderTracker.startTracking()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
index 707a297..c0cfd73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
@@ -24,10 +24,13 @@
import com.android.settingslib.RestrictedLockUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.haptics.slider.SeekableSliderHapticPlugin
+import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.BrightnessMirrorController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
@@ -35,6 +38,7 @@
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.isNull
@@ -61,7 +65,7 @@
@Mock
private lateinit var listener: ToggleSlider.Listener
@Mock
- private lateinit var mBrightnessSliderHapticPlugin: BrightnessSliderHapticPlugin
+ private lateinit var vibratorHelper: VibratorHelper
@Captor
private lateinit var seekBarChangeCaptor: ArgumentCaptor<SeekBar.OnSeekBarChangeListener>
@@ -69,6 +73,7 @@
private lateinit var seekBar: SeekBar
private val uiEventLogger = UiEventLoggerFake()
private var mFalsingManager: FalsingManagerFake = FalsingManagerFake()
+ private val systemClock = FakeSystemClock()
private lateinit var mController: BrightnessSliderController
@@ -78,13 +83,14 @@
whenever(mirrorController.toggleSlider).thenReturn(mirror)
whenever(motionEvent.copy()).thenReturn(motionEvent)
+ whenever(vibratorHelper.getPrimitiveDurations(anyInt())).thenReturn(intArrayOf(0))
mController =
BrightnessSliderController(
brightnessSliderView,
mFalsingManager,
uiEventLogger,
- mBrightnessSliderHapticPlugin,
+ SeekableSliderHapticPlugin(vibratorHelper, systemClock),
)
mController.init()
mController.setOnChangedListener(listener)
@@ -100,7 +106,6 @@
mController.onViewAttached()
verify(brightnessSliderView).setOnSeekBarChangeListener(notNull())
- verify(mBrightnessSliderHapticPlugin).start()
}
@Test
@@ -110,7 +115,6 @@
verify(brightnessSliderView).setOnSeekBarChangeListener(isNull())
verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull())
- verify(mBrightnessSliderHapticPlugin).stop()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt
deleted file mode 100644
index 51629b5..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt
+++ /dev/null
@@ -1,102 +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.systemui.settings.brightness
-
-import android.view.VelocityTracker
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.haptics.slider.SeekableSliderEventProducer
-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.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class BrightnessSliderHapticPluginImplTest : SysuiTestCase() {
-
- @Mock private lateinit var vibratorHelper: VibratorHelper
- @Mock private lateinit var velocityTracker: VelocityTracker
- @Mock private lateinit var mainDispatcher: CoroutineDispatcher
-
- private val systemClock = FakeSystemClock()
- private val sliderEventProducer = SeekableSliderEventProducer()
-
- private lateinit var plugin: BrightnessSliderHapticPluginImpl
-
- @Before
- fun setup() {
- MockitoAnnotations.initMocks(this)
- whenever(vibratorHelper.getPrimitiveDurations(anyInt())).thenReturn(intArrayOf(0))
- }
-
- @Test
- fun start_beginsTrackingSlider() = runTest {
- createPlugin(UnconfinedTestDispatcher(testScheduler))
- plugin.start()
-
- assertThat(plugin.isTracking).isTrue()
- }
-
- @Test
- fun stop_stopsTrackingSlider() = runTest {
- createPlugin(UnconfinedTestDispatcher(testScheduler))
- // GIVEN that the plugin started the tracking component
- plugin.start()
-
- // WHEN called to stop
- plugin.stop()
-
- // THEN the tracking component stops
- assertThat(plugin.isTracking).isFalse()
- }
-
- @Test
- fun start_afterStop_startsTheTrackingAgain() = runTest {
- createPlugin(UnconfinedTestDispatcher(testScheduler))
- // GIVEN that the plugin started the tracking component
- plugin.start()
-
- // WHEN the plugin is restarted
- plugin.stop()
- plugin.start()
-
- // THEN the tracking begins again
- assertThat(plugin.isTracking).isTrue()
- }
-
- private fun createPlugin(dispatcher: CoroutineDispatcher) {
- plugin =
- BrightnessSliderHapticPluginImpl(
- vibratorHelper,
- systemClock,
- dispatcher,
- velocityTracker,
- sliderEventProducer,
- )
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 7a8dce8..8a33778 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -64,7 +64,6 @@
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.keyguard.TestScopeProvider;
import com.android.systemui.Prefs;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.AnimatorTestRule;
@@ -102,8 +101,6 @@
import java.util.Arrays;
import java.util.function.Predicate;
-import kotlinx.coroutines.Dispatchers;
-
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -208,8 +205,6 @@
mDumpManager,
mLazySecureSettings,
mVibratorHelper,
- Dispatchers.getUnconfined(),
- TestScopeProvider.getTestScope(),
new FakeSystemClock());
mDialog.init(0, null);
State state = createShellState();