Loading src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java +25 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.content.Context; import android.os.PowerManager; import android.provider.Settings; import android.provider.Settings.Global; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import androidx.preference.Preference; import androidx.preference.Preference.OnPreferenceChangeListener; Loading @@ -42,22 +44,27 @@ import com.android.settings.widget.SeekBarPreference; * See {@link Settings.Global#AUTOMATIC_POWER_SAVE_MODE} for more details. */ public class BatterySaverScheduleSeekBarController implements OnPreferenceChangeListener { OnPreferenceChangeListener, OnSeekBarChangeListener { public static final int MAX_SEEKBAR_VALUE = 15; public static final int MIN_SEEKBAR_VALUE = 2; public static final String KEY_BATTERY_SAVER_SEEK_BAR = "battery_saver_seek_bar"; private static final int LEVEL_UNIT_SCALE = 5; @VisibleForTesting public SeekBarPreference mSeekBarPreference; private Context mContext; @VisibleForTesting int mPercentage; public BatterySaverScheduleSeekBarController(Context context) { mContext = context; mSeekBarPreference = new SeekBarPreference(context); mSeekBarPreference.setLayoutResource(R.layout.preference_widget_seekbar_settings); mSeekBarPreference.setIconSpaceReserved(false); mSeekBarPreference.setOnPreferenceChangeListener(this); mSeekBarPreference.setOnSeekBarChangeListener(this); mSeekBarPreference.setContinuousUpdates(true); mSeekBarPreference.setMax(MAX_SEEKBAR_VALUE); mSeekBarPreference.setMin(MIN_SEEKBAR_VALUE); Loading @@ -68,16 +75,28 @@ public class BatterySaverScheduleSeekBarController implements @Override public boolean onPreferenceChange(Preference preference, Object newValue) { // The nits are in intervals of 5% final int percentage = ((Integer) newValue) * 5; Settings.Global.putInt(mContext.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, percentage); final CharSequence stateDescription = formatStateDescription(percentage); mPercentage = ((Integer) newValue) * LEVEL_UNIT_SCALE; final CharSequence stateDescription = formatStateDescription(mPercentage); preference.setTitle(stateDescription); mSeekBarPreference.overrideSeekBarStateDescription(stateDescription); return true; } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {} @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) { if (mPercentage > 0) { Settings.Global.putInt(mContext.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, mPercentage); } } public void updateSeekBar() { final ContentResolver resolver = mContext.getContentResolver(); // Note: this can also be obtained via PowerManager.getPowerSaveModeTrigger() Loading src/com/android/settings/widget/SeekBarPreference.java +18 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ public class SeekBarPreference extends RestrictedPreference private CharSequence mOverrideSeekBarStateDescription; private CharSequence mSeekBarContentDescription; private CharSequence mSeekBarStateDescription; private OnSeekBarChangeListener mOnSeekBarChangeListener; public SeekBarPreference( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { Loading Loading @@ -101,6 +102,14 @@ public class SeekBarPreference extends RestrictedPreference this(context, null); } /** * A callback that notifies clients when the seekbar progress level has been * changed. See {@link OnSeekBarChangeListener} for more info. */ public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) { mOnSeekBarChangeListener = listener; } public void setShouldBlink(boolean shouldBlink) { mShouldBlink = shouldBlink; notifyChanged(); Loading Loading @@ -301,6 +310,9 @@ public class SeekBarPreference extends RestrictedPreference if (fromUser && (mContinuousUpdates || !mTrackingTouch)) { syncProgress(seekBar); } if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser); } } @Override Loading @@ -309,6 +321,9 @@ public class SeekBarPreference extends RestrictedPreference mJankMonitor.begin(InteractionJankMonitor.Configuration.Builder .withView(CUJ_SETTINGS_SLIDER, seekBar) .setTag(getKey())); if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStartTrackingTouch(seekBar); } } @Override Loading @@ -317,6 +332,9 @@ public class SeekBarPreference extends RestrictedPreference if (seekBar.getProgress() != mProgress) { syncProgress(seekBar); } if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStopTrackingTouch(seekBar); } mJankMonitor.end(CUJ_SETTINGS_SLIDER); } Loading tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java +45 −7 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ import android.content.Context; import android.os.PowerManager; import android.provider.Settings; import android.provider.Settings.Global; import android.widget.SeekBar; import androidx.preference.PreferenceScreen; Loading Loading @@ -46,22 +47,47 @@ public class BatterySaverScheduleSeekBarControllerTest { } @Test public void onPreferenceChange_updatesSettingsGlobal() { public void onPreferenceChange_withoutOnStopTrackingTouch_updatesTitleAndDescriptionOnly() { final CharSequence expectedTitle = "50%"; Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 5); setTriggerLevel(5); mController.onPreferenceChange(mController.mSeekBarPreference, 10); assertThat(Settings.Global.getInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1)) .isEqualTo(50); assertThat(getTriggerLevel()).isEqualTo(5); assertThat(mController.mSeekBarPreference.getTitle()).isEqualTo(expectedTitle); verify(mController.mSeekBarPreference).overrideSeekBarStateDescription(expectedTitle); } @Test public void onPreferenceChange_withOnStopTrackingTouch_updatesSettingsGlobal() { final CharSequence expectedTitle = "50%"; setTriggerLevel(5); mController.onPreferenceChange(mController.mSeekBarPreference, 10); mController.onStopTrackingTouch(new SeekBar(mContext)); assertThat(getTriggerLevel()).isEqualTo(50); assertThat(mController.mSeekBarPreference.getTitle()).isEqualTo(expectedTitle); verify(mController.mSeekBarPreference).overrideSeekBarStateDescription(expectedTitle); } @Test public void onStopTrackingTouch_invalidValue_noUpdates() { setTriggerLevel(5); mController.mPercentage = 0; mController.onStopTrackingTouch(new SeekBar(mContext)); assertThat(getTriggerLevel()).isEqualTo(5); } @Test public void updateSeekBar_routineMode_hasCorrectProperties() { Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC); mController.updateSeekBar(); assertThat(mController.mSeekBarPreference.isVisible()).isFalse(); verify(mController.mSeekBarPreference, never()).overrideSeekBarStateDescription(any()); } Loading @@ -71,7 +97,8 @@ public class BatterySaverScheduleSeekBarControllerTest { final CharSequence expectedTitle = "10%"; Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 10); setTriggerLevel(10); mController.updateSeekBar(); assertThat(mController.mSeekBarPreference.isVisible()).isTrue(); Loading @@ -83,8 +110,10 @@ public class BatterySaverScheduleSeekBarControllerTest { public void updateSeekBar_noneMode_hasCorrectProperties() { Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0); setTriggerLevel(0); mController.updateSeekBar(); assertThat(mController.mSeekBarPreference.isVisible()).isFalse(); verify(mController.mSeekBarPreference, never()).overrideSeekBarStateDescription(any()); } Loading @@ -93,9 +122,18 @@ public class BatterySaverScheduleSeekBarControllerTest { public void addToScreen_addsToEnd() { Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15); setTriggerLevel(15); mController.addToScreen(mScreen); assertThat(mController.mSeekBarPreference.getOrder()).isEqualTo(100); } private void setTriggerLevel(int level) { Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, level); } private int getTriggerLevel() { return Settings.Global.getInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1); } } tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java +53 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; Loading @@ -40,6 +41,7 @@ import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; Loading @@ -59,6 +61,9 @@ public class SeekBarPreferenceTest { private SeekBarPreference mSeekBarPreference; private SeekBar mSeekBar; @Mock SeekBar.OnSeekBarChangeListener mMockOnSeekBarChangeListener; @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading Loading @@ -179,6 +184,54 @@ public class SeekBarPreferenceTest { assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK); } @Test public void onProgressChanged_hasSeekBarChangeListener_receiveCallBack() { mSeekBarPreference.setOnSeekBarChangeListener(mMockOnSeekBarChangeListener); mSeekBarPreference.onProgressChanged(mSeekBar, PROGRESS, true); verify(mMockOnSeekBarChangeListener).onProgressChanged(mSeekBar, PROGRESS, true); } @Test public void onProgressChanged_noSeekBarChangeListener_noAction() { mSeekBarPreference.onProgressChanged(mSeekBar, PROGRESS, true); verifyZeroInteractions(mMockOnSeekBarChangeListener); } @Test public void onStartTrackingTouch_hasSeekBarChangeListener_receiveCallBack() { mSeekBarPreference.setOnSeekBarChangeListener(mMockOnSeekBarChangeListener); mSeekBarPreference.onStartTrackingTouch(mSeekBar); verify(mMockOnSeekBarChangeListener).onStartTrackingTouch(mSeekBar); } @Test public void onStartTrackingTouch_noSeekBarChangeListener_noAction() { mSeekBarPreference.onStartTrackingTouch(mSeekBar); verifyZeroInteractions(mMockOnSeekBarChangeListener); } @Test public void onStopTrackingTouch_hasSeekBarChangeListener_receiveCallBack() { mSeekBarPreference.setOnSeekBarChangeListener(mMockOnSeekBarChangeListener); mSeekBarPreference.onStopTrackingTouch(mSeekBar); verify(mMockOnSeekBarChangeListener).onStopTrackingTouch(mSeekBar); } @Test public void onStopTrackingTouch_noSeekBarChangeListener_noAction() { mSeekBarPreference.onStopTrackingTouch(mSeekBar); verifyZeroInteractions(mMockOnSeekBarChangeListener); } public static class TestFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { Loading Loading
src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java +25 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.content.Context; import android.os.PowerManager; import android.provider.Settings; import android.provider.Settings.Global; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import androidx.preference.Preference; import androidx.preference.Preference.OnPreferenceChangeListener; Loading @@ -42,22 +44,27 @@ import com.android.settings.widget.SeekBarPreference; * See {@link Settings.Global#AUTOMATIC_POWER_SAVE_MODE} for more details. */ public class BatterySaverScheduleSeekBarController implements OnPreferenceChangeListener { OnPreferenceChangeListener, OnSeekBarChangeListener { public static final int MAX_SEEKBAR_VALUE = 15; public static final int MIN_SEEKBAR_VALUE = 2; public static final String KEY_BATTERY_SAVER_SEEK_BAR = "battery_saver_seek_bar"; private static final int LEVEL_UNIT_SCALE = 5; @VisibleForTesting public SeekBarPreference mSeekBarPreference; private Context mContext; @VisibleForTesting int mPercentage; public BatterySaverScheduleSeekBarController(Context context) { mContext = context; mSeekBarPreference = new SeekBarPreference(context); mSeekBarPreference.setLayoutResource(R.layout.preference_widget_seekbar_settings); mSeekBarPreference.setIconSpaceReserved(false); mSeekBarPreference.setOnPreferenceChangeListener(this); mSeekBarPreference.setOnSeekBarChangeListener(this); mSeekBarPreference.setContinuousUpdates(true); mSeekBarPreference.setMax(MAX_SEEKBAR_VALUE); mSeekBarPreference.setMin(MIN_SEEKBAR_VALUE); Loading @@ -68,16 +75,28 @@ public class BatterySaverScheduleSeekBarController implements @Override public boolean onPreferenceChange(Preference preference, Object newValue) { // The nits are in intervals of 5% final int percentage = ((Integer) newValue) * 5; Settings.Global.putInt(mContext.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, percentage); final CharSequence stateDescription = formatStateDescription(percentage); mPercentage = ((Integer) newValue) * LEVEL_UNIT_SCALE; final CharSequence stateDescription = formatStateDescription(mPercentage); preference.setTitle(stateDescription); mSeekBarPreference.overrideSeekBarStateDescription(stateDescription); return true; } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {} @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) { if (mPercentage > 0) { Settings.Global.putInt(mContext.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, mPercentage); } } public void updateSeekBar() { final ContentResolver resolver = mContext.getContentResolver(); // Note: this can also be obtained via PowerManager.getPowerSaveModeTrigger() Loading
src/com/android/settings/widget/SeekBarPreference.java +18 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ public class SeekBarPreference extends RestrictedPreference private CharSequence mOverrideSeekBarStateDescription; private CharSequence mSeekBarContentDescription; private CharSequence mSeekBarStateDescription; private OnSeekBarChangeListener mOnSeekBarChangeListener; public SeekBarPreference( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { Loading Loading @@ -101,6 +102,14 @@ public class SeekBarPreference extends RestrictedPreference this(context, null); } /** * A callback that notifies clients when the seekbar progress level has been * changed. See {@link OnSeekBarChangeListener} for more info. */ public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) { mOnSeekBarChangeListener = listener; } public void setShouldBlink(boolean shouldBlink) { mShouldBlink = shouldBlink; notifyChanged(); Loading Loading @@ -301,6 +310,9 @@ public class SeekBarPreference extends RestrictedPreference if (fromUser && (mContinuousUpdates || !mTrackingTouch)) { syncProgress(seekBar); } if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser); } } @Override Loading @@ -309,6 +321,9 @@ public class SeekBarPreference extends RestrictedPreference mJankMonitor.begin(InteractionJankMonitor.Configuration.Builder .withView(CUJ_SETTINGS_SLIDER, seekBar) .setTag(getKey())); if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStartTrackingTouch(seekBar); } } @Override Loading @@ -317,6 +332,9 @@ public class SeekBarPreference extends RestrictedPreference if (seekBar.getProgress() != mProgress) { syncProgress(seekBar); } if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStopTrackingTouch(seekBar); } mJankMonitor.end(CUJ_SETTINGS_SLIDER); } Loading
tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java +45 −7 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ import android.content.Context; import android.os.PowerManager; import android.provider.Settings; import android.provider.Settings.Global; import android.widget.SeekBar; import androidx.preference.PreferenceScreen; Loading Loading @@ -46,22 +47,47 @@ public class BatterySaverScheduleSeekBarControllerTest { } @Test public void onPreferenceChange_updatesSettingsGlobal() { public void onPreferenceChange_withoutOnStopTrackingTouch_updatesTitleAndDescriptionOnly() { final CharSequence expectedTitle = "50%"; Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 5); setTriggerLevel(5); mController.onPreferenceChange(mController.mSeekBarPreference, 10); assertThat(Settings.Global.getInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1)) .isEqualTo(50); assertThat(getTriggerLevel()).isEqualTo(5); assertThat(mController.mSeekBarPreference.getTitle()).isEqualTo(expectedTitle); verify(mController.mSeekBarPreference).overrideSeekBarStateDescription(expectedTitle); } @Test public void onPreferenceChange_withOnStopTrackingTouch_updatesSettingsGlobal() { final CharSequence expectedTitle = "50%"; setTriggerLevel(5); mController.onPreferenceChange(mController.mSeekBarPreference, 10); mController.onStopTrackingTouch(new SeekBar(mContext)); assertThat(getTriggerLevel()).isEqualTo(50); assertThat(mController.mSeekBarPreference.getTitle()).isEqualTo(expectedTitle); verify(mController.mSeekBarPreference).overrideSeekBarStateDescription(expectedTitle); } @Test public void onStopTrackingTouch_invalidValue_noUpdates() { setTriggerLevel(5); mController.mPercentage = 0; mController.onStopTrackingTouch(new SeekBar(mContext)); assertThat(getTriggerLevel()).isEqualTo(5); } @Test public void updateSeekBar_routineMode_hasCorrectProperties() { Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC); mController.updateSeekBar(); assertThat(mController.mSeekBarPreference.isVisible()).isFalse(); verify(mController.mSeekBarPreference, never()).overrideSeekBarStateDescription(any()); } Loading @@ -71,7 +97,8 @@ public class BatterySaverScheduleSeekBarControllerTest { final CharSequence expectedTitle = "10%"; Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 10); setTriggerLevel(10); mController.updateSeekBar(); assertThat(mController.mSeekBarPreference.isVisible()).isTrue(); Loading @@ -83,8 +110,10 @@ public class BatterySaverScheduleSeekBarControllerTest { public void updateSeekBar_noneMode_hasCorrectProperties() { Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0); setTriggerLevel(0); mController.updateSeekBar(); assertThat(mController.mSeekBarPreference.isVisible()).isFalse(); verify(mController.mSeekBarPreference, never()).overrideSeekBarStateDescription(any()); } Loading @@ -93,9 +122,18 @@ public class BatterySaverScheduleSeekBarControllerTest { public void addToScreen_addsToEnd() { Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE); Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15); setTriggerLevel(15); mController.addToScreen(mScreen); assertThat(mController.mSeekBarPreference.getOrder()).isEqualTo(100); } private void setTriggerLevel(int level) { Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, level); } private int getTriggerLevel() { return Settings.Global.getInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1); } }
tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java +53 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; Loading @@ -40,6 +41,7 @@ import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; Loading @@ -59,6 +61,9 @@ public class SeekBarPreferenceTest { private SeekBarPreference mSeekBarPreference; private SeekBar mSeekBar; @Mock SeekBar.OnSeekBarChangeListener mMockOnSeekBarChangeListener; @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading Loading @@ -179,6 +184,54 @@ public class SeekBarPreferenceTest { assertThat(shadowOf(mSeekBar).lastHapticFeedbackPerformed()).isEqualTo(CLOCK_TICK); } @Test public void onProgressChanged_hasSeekBarChangeListener_receiveCallBack() { mSeekBarPreference.setOnSeekBarChangeListener(mMockOnSeekBarChangeListener); mSeekBarPreference.onProgressChanged(mSeekBar, PROGRESS, true); verify(mMockOnSeekBarChangeListener).onProgressChanged(mSeekBar, PROGRESS, true); } @Test public void onProgressChanged_noSeekBarChangeListener_noAction() { mSeekBarPreference.onProgressChanged(mSeekBar, PROGRESS, true); verifyZeroInteractions(mMockOnSeekBarChangeListener); } @Test public void onStartTrackingTouch_hasSeekBarChangeListener_receiveCallBack() { mSeekBarPreference.setOnSeekBarChangeListener(mMockOnSeekBarChangeListener); mSeekBarPreference.onStartTrackingTouch(mSeekBar); verify(mMockOnSeekBarChangeListener).onStartTrackingTouch(mSeekBar); } @Test public void onStartTrackingTouch_noSeekBarChangeListener_noAction() { mSeekBarPreference.onStartTrackingTouch(mSeekBar); verifyZeroInteractions(mMockOnSeekBarChangeListener); } @Test public void onStopTrackingTouch_hasSeekBarChangeListener_receiveCallBack() { mSeekBarPreference.setOnSeekBarChangeListener(mMockOnSeekBarChangeListener); mSeekBarPreference.onStopTrackingTouch(mSeekBar); verify(mMockOnSeekBarChangeListener).onStopTrackingTouch(mSeekBar); } @Test public void onStopTrackingTouch_noSeekBarChangeListener_noAction() { mSeekBarPreference.onStopTrackingTouch(mSeekBar); verifyZeroInteractions(mMockOnSeekBarChangeListener); } public static class TestFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { Loading