Merge "Update Settings to use intensity settings as main preference keys"

This commit is contained in:
Lais Andrade
2022-01-13 02:45:41 +00:00
committed by Android (Google) Code Review
40 changed files with 1543 additions and 1703 deletions

View File

@@ -5565,8 +5565,10 @@
<string name="accessibility_autoclick_longer_desc">Longer</string>
<!-- Description for the seekbar that adjust auto click time. [CHAR_LIMIT=NONE] -->
<string name="accessibility_autoclick_seekbar_desc">Auto click time</string>
<!-- Title for accessibility preference screen for configuring vibrations. -->
<!-- Title for preference screen for configuring vibrations. [CHAR LIMIT=NONE] -->
<string name="accessibility_vibration_settings_title">Vibration &amp; haptics</string>
<!-- Summary for preference screen for configuring vibrations. [CHAR LIMIT=NONE] -->
<string name="accessibility_vibration_settings_summary">Control the vibration strength for different usages</string>
<!-- Title for the category of preferences to configure device vibrations related to calls. [CHAR LIMIT=NONE] -->
<string name="accessibility_call_vibration_category_title">Calls</string>
<!-- Title for the category of preferences to configure device vibrations related to notifications and alarms. [CHAR LIMIT=NONE] -->
@@ -5736,33 +5738,6 @@
<item quantity="other"><xliff:g id="click_delay_label">%1$s</xliff:g> seconds</item>
</plurals>
<!-- Summary for vibration settings preference when notification vibration and haptic feedback intensity are set. [CHAR LIMIT=50] -->
<string name="accessibility_vibration_summary">Ring <xliff:g id="summary_ring" example="Medium">%1$s</xliff:g>, notification <xliff:g id="summary_notification" example="Low">%2$s</xliff:g>, touch <xliff:g id="summary_touch" example="High">%3$s</xliff:g></string>
<!-- Summary for vibration settings preference when ring & notification are set to off-->
<string name="accessibility_vibration_summary_off">Ring &amp; notification set to off</string>
<!-- Summary for vibration settings preference when ring & notification are set to low-->
<string name="accessibility_vibration_summary_low">Ring &amp; notification set to low</string>
<!-- Summary for vibration settings preference when ring & notification are set to medium-->
<string name="accessibility_vibration_summary_medium">Ring &amp; notification set to medium</string>
<!-- Summary for vibration settings preference when ring & notification are set to high-->
<string name="accessibility_vibration_summary_high">Ring &amp; notification set to high</string>
<!-- Label describing an option turning vibrations off. [CHAR LIMIT=15] -->
<string name="accessibility_vibration_intensity_off">Off</string>
<!-- Label describing a low intensity vibration option. [CHAR LIMIT=15] -->
<string name="accessibility_vibration_intensity_low">Low</string>
<!-- Label describing a medium intensity vibration option. [CHAR LIMIT=15] -->
<string name="accessibility_vibration_intensity_medium">Medium</string>
<!-- Label describing a high intensity vibration option. [CHAR LIMIT=15] -->
<string name="accessibility_vibration_intensity_high">High</string>
<!-- Title for accessibility menu item to launch a settings activity. [CHAR LIMIT=15] -->
<string name="accessibility_menu_item_settings">Settings</string>
@@ -8427,6 +8402,8 @@
<string name="keywords_touch_vibration">haptics, vibrate, screen, sensitivity</string>
<!-- List of synonyms for ring vibration setting (changes whether your phone vibrates when it rings), used to match in settings search [CHAR LIMIT=NONE] -->
<string name="keywords_ring_vibration">haptics, vibrate, phone, call, sensitivity, ring</string>
<!-- List of synonyms for ring vibration setting (changes whether your phone vibrates when it rings), used to match in settings search [CHAR LIMIT=NONE] -->
<string name="keywords_ramping_ringer_vibration">haptics, vibrate, phone, call, ring, gradually</string>
<!-- List of synonyms for notification vibration setting (changes whether your phone vibrates when it shows a notification), used to match in settings search [CHAR LIMIT=NONE] -->
<string name="keywords_notification_vibration">haptics, vibrate, sensitivity</string>
<!-- List of synonyms for vibration and haptics setting, used to match in settings search [CHAR LIMIT=NONE] -->

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/accessibility_notification_vibration_title" />

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/accessibility_ring_vibration_title" />

View File

@@ -110,7 +110,8 @@
android:persistent="false"
android:title="@string/accessibility_vibration_settings_title"
settings:controller="com.android.settings.accessibility.VibrationPreferenceController"
settings:keywords="@string/keywords_vibration"/>
settings:keywords="@string/keywords_vibration"
android:summary="@string/accessibility_vibration_settings_summary"/>
</PreferenceCategory>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/accessibility_touch_vibration_title" />

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2022 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/accessibility_vibration_settings_title">
<PreferenceCategory
android:key="accessibility_call_vibration_category"
android:title="@string/accessibility_call_vibration_category_title">
<com.android.settings.widget.SeekBarPreference
android:key="ring_vibration_preference_screen"
android:title="@string/accessibility_ring_vibration_title"
app:keywords="@string/keywords_ring_vibration"
app:controller="com.android.settings.accessibility.RingVibrationIntensityPreferenceController" />
<SwitchPreference
android:key="ramping_ringer"
android:title="@string/vibrate_when_ringing_option_ramping_ringer"
app:keywords="@string/keywords_ramping_ringer_vibration"
app:controller="com.android.settings.accessibility.VibrationRampingRingerTogglePreferenceController"/>
</PreferenceCategory>
<PreferenceCategory
android:key="accessibility_notification_alarm_vibration_category"
android:title="@string/accessibility_notification_alarm_vibration_category_title">
<com.android.settings.widget.SeekBarPreference
android:key="notification_vibration_preference_screen"
android:title="@string/accessibility_notification_vibration_title"
app:keywords="@string/keywords_notification_vibration"
app:controller="com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController" />
</PreferenceCategory>
<PreferenceCategory
android:key="accessibility_interactive_haptics_category"
android:title="@string/accessibility_interactive_haptics_category_title">
<com.android.settings.widget.SeekBarPreference
android:key="touch_vibration_preference_screen"
android:title="@string/accessibility_touch_vibration_title"
app:keywords="@string/keywords_touch_vibration"
app:controller="com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -17,25 +17,23 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/accessibility_vibration_settings_title">
<PreferenceCategory
android:key="accessibility_call_vibration_category"
android:title="@string/accessibility_call_vibration_category_title">
<Preference
android:fragment="com.android.settings.accessibility.RingVibrationPreferenceFragment"
<SwitchPreference
android:key="ring_vibration_preference_screen"
android:title="@string/accessibility_ring_vibration_title"
settings:keywords="@string/keywords_ring_vibration"
app:controller="com.android.settings.accessibility.RingVibrationIntensityPreferenceController" />
app:keywords="@string/keywords_ring_vibration"
app:controller="com.android.settings.accessibility.RingVibrationTogglePreferenceController" />
<Preference
android:fragment="com.android.settings.sound.VibrateForCallsPreferenceFragment"
android:key="vibrate_for_calls"
android:title="@string/vibrate_when_ringing_title"
settings:controller="com.android.settings.sound.VibrateForCallsPreferenceController"/>
<SwitchPreference
android:key="ramping_ringer"
android:title="@string/vibrate_when_ringing_option_ramping_ringer"
app:keywords="@string/keywords_ramping_ringer_vibration"
app:controller="com.android.settings.accessibility.VibrationRampingRingerTogglePreferenceController"/>
</PreferenceCategory>
@@ -43,12 +41,11 @@
android:key="accessibility_notification_alarm_vibration_category"
android:title="@string/accessibility_notification_alarm_vibration_category_title">
<Preference
android:fragment="com.android.settings.accessibility.NotificationVibrationPreferenceFragment"
<SwitchPreference
android:key="notification_vibration_preference_screen"
android:title="@string/accessibility_notification_vibration_title"
settings:keywords="@string/keywords_notification_vibration"
app:controller="com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController" />
app:keywords="@string/keywords_notification_vibration"
app:controller="com.android.settings.accessibility.NotificationVibrationTogglePreferenceController" />
</PreferenceCategory>
@@ -56,12 +53,11 @@
android:key="accessibility_interactive_haptics_category"
android:title="@string/accessibility_interactive_haptics_category_title">
<Preference
android:fragment="com.android.settings.accessibility.TouchVibrationPreferenceFragment"
<SwitchPreference
android:key="touch_vibration_preference_screen"
android:title="@string/accessibility_touch_vibration_title"
settings:keywords="@string/keywords_touch_vibration"
app:controller="com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController" />
app:keywords="@string/keywords_touch_vibration"
app:controller="com.android.settings.accessibility.HapticFeedbackTogglePreferenceController" />
</PreferenceCategory>

View File

@@ -294,11 +294,6 @@ public class AccessibilitySettings extends DashboardFragment {
return info.loadDescription(context.getPackageManager());
}
static boolean isRampingRingerEnabled(final Context context) {
return Settings.System.getInt(
context.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, 0) == 1;
}
@VisibleForTesting
void onContentChanged() {
// If the fragment is visible then update preferences immediately, else set the flag then

View File

@@ -16,31 +16,66 @@
package com.android.settings.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import android.content.Context;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
/** Preference controller for haptic feedback intensity */
public class HapticFeedbackIntensityPreferenceController
extends VibrationIntensityPreferenceController {
@VisibleForTesting
static final String PREF_KEY = "touch_vibration_preference_screen";
/** General configuration for haptic feedback intensity settings. */
public static final class HapticFeedbackVibrationPreferenceConfig
extends VibrationPreferenceConfig {
public HapticFeedbackIntensityPreferenceController(Context context) {
super(context, PREF_KEY, Settings.System.HAPTIC_FEEDBACK_INTENSITY,
Settings.System.HAPTIC_FEEDBACK_ENABLED);
public HapticFeedbackVibrationPreferenceConfig(Context context) {
super(context, Settings.System.HAPTIC_FEEDBACK_INTENSITY,
VibrationAttributes.USAGE_TOUCH);
}
@Override
public int readIntensity() {
final int hapticFeedbackEnabled = Settings.System.getInt(mContentResolver,
Settings.System.HAPTIC_FEEDBACK_ENABLED, ON);
if (hapticFeedbackEnabled == OFF) {
// HAPTIC_FEEDBACK_ENABLED is deprecated but should still be applied if the user has
// turned it off already.
return Vibrator.VIBRATION_INTENSITY_OFF;
}
return super.readIntensity();
}
@Override
public boolean updateIntensity(int intensity) {
final boolean success = super.updateIntensity(intensity);
final boolean isIntensityOff = intensity == Vibrator.VIBRATION_INTENSITY_OFF;
Settings.System.putInt(mContentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED,
isIntensityOff ? OFF : ON);
// HAPTIC_FEEDBACK_ENABLED is deprecated but should still reflect the intensity setting.
// HARDWARE_HAPTIC_FEEDBACK_INTENSITY is dependent on this setting, but should not be
// disabled by it.
Settings.System.putInt(mContentResolver,
Settings.System.HARDWARE_HAPTIC_FEEDBACK_INTENSITY,
isIntensityOff ? getDefaultIntensity() : intensity);
return success;
}
}
public HapticFeedbackIntensityPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey, new HapticFeedbackVibrationPreferenceConfig(context));
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
protected int getDefaultIntensity() {
return mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH);
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import android.content.Context;
import com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController.HapticFeedbackVibrationPreferenceConfig;
/** Preference controller for haptic feedback with only a toggle for on/off states. */
public class HapticFeedbackTogglePreferenceController extends VibrationTogglePreferenceController {
public HapticFeedbackTogglePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey, new HapticFeedbackVibrationPreferenceConfig(context));
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
}

View File

@@ -20,25 +20,27 @@ import android.content.Context;
import android.os.VibrationAttributes;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
/** Preference controller for notification vibration intensity */
public class NotificationVibrationIntensityPreferenceController
extends VibrationIntensityPreferenceController {
@VisibleForTesting
static final String PREF_KEY = "notification_vibration_preference_screen";
/** General configuration for notification vibration intensity settings. */
public static final class NotificationVibrationPreferenceConfig
extends VibrationPreferenceConfig {
public NotificationVibrationIntensityPreferenceController(Context context) {
super(context, PREF_KEY, Settings.System.NOTIFICATION_VIBRATION_INTENSITY, "");
public NotificationVibrationPreferenceConfig(Context context) {
super(context, Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
VibrationAttributes.USAGE_NOTIFICATION);
}
}
public NotificationVibrationIntensityPreferenceController(Context context,
String preferenceKey) {
super(context, preferenceKey, new NotificationVibrationPreferenceConfig(context));
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
protected int getDefaultIntensity() {
return mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION);
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (C) 2018 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.settings.accessibility;
import android.app.settings.SettingsEnums;
import android.media.AudioAttributes;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import com.android.settings.R;
/**
* Fragment for picking accessibility shortcut service
*/
public class NotificationVibrationPreferenceFragment extends VibrationPreferenceFragment {
@Override
public int getMetricsCategory() {
return SettingsEnums.ACCESSIBILITY_VIBRATION_NOTIFICATION;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.accessibility_notification_vibration_settings;
}
/**
* Get the setting string of the vibration intensity setting this preference is dealing with.
*/
@Override
protected String getVibrationIntensitySetting() {
return Settings.System.NOTIFICATION_VIBRATION_INTENSITY;
}
@Override
protected String getVibrationEnabledSetting() {
return "";
}
@Override
protected int getPreviewVibrationAudioAttributesUsage() {
return AudioAttributes.USAGE_NOTIFICATION;
}
@Override
protected int getDefaultVibrationIntensity() {
Vibrator vibrator = getContext().getSystemService(Vibrator.class);
return vibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import android.content.Context;
import com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController.NotificationVibrationPreferenceConfig;
/** Preference controller for notification vibration with only a toggle for on/off states. */
public class NotificationVibrationTogglePreferenceController
extends VibrationTogglePreferenceController {
public NotificationVibrationTogglePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey, new NotificationVibrationPreferenceConfig(context));
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
}

View File

@@ -16,30 +16,63 @@
package com.android.settings.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import android.content.Context;
import android.media.AudioManager;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
/** Preference controller for ringtone vibration intensity */
public class RingVibrationIntensityPreferenceController
extends VibrationIntensityPreferenceController {
@VisibleForTesting
static final String PREF_KEY = "ring_vibration_preference_screen";
/** General configuration for ringtone vibration intensity settings. */
public static final class RingVibrationPreferenceConfig extends VibrationPreferenceConfig {
private final AudioManager mAudioManager;
public RingVibrationIntensityPreferenceController(Context context) {
super(context, PREF_KEY, Settings.System.RING_VIBRATION_INTENSITY,
Settings.System.VIBRATE_WHEN_RINGING, /* supportRampingRinger= */ true);
public RingVibrationPreferenceConfig(Context context) {
super(context, Settings.System.RING_VIBRATION_INTENSITY,
VibrationAttributes.USAGE_RINGTONE);
mAudioManager = context.getSystemService(AudioManager.class);
}
@Override
public int readIntensity() {
final int vibrateWhenRinging = Settings.System.getInt(mContentResolver,
Settings.System.VIBRATE_WHEN_RINGING, ON);
if ((vibrateWhenRinging == OFF)
&& !mAudioManager.isRampingRingerEnabled()) {
// VIBRATE_WHEN_RINGING is deprecated but should still be applied if the user has
// turned it off and has not enabled the ramping ringer (old three-state setting).
return Vibrator.VIBRATION_INTENSITY_OFF;
}
return super.readIntensity();
}
@Override
public boolean updateIntensity(int intensity) {
final boolean success = super.updateIntensity(intensity);
// VIBRATE_WHEN_RINGING is deprecated but should still reflect the intensity setting.
// Ramping ringer is independent of the ring intensity and should not be affected.
Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING,
(intensity == Vibrator.VIBRATION_INTENSITY_OFF) ? OFF : ON);
return success;
}
}
public RingVibrationIntensityPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey, new RingVibrationPreferenceConfig(context));
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
protected int getDefaultIntensity() {
return mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE);
}
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright (C) 2018 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.settings.accessibility;
import android.app.settings.SettingsEnums;
import android.media.AudioAttributes;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import com.android.settings.R;
/**
* Fragment for picking accessibility shortcut service
*/
public class RingVibrationPreferenceFragment extends VibrationPreferenceFragment {
@Override
public int getMetricsCategory() {
return SettingsEnums.ACCESSIBILITY_VIBRATION_RING;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.accessibility_ring_vibration_settings;
}
/**
* Get the setting string of the vibration intensity setting this preference is dealing with.
*/
@Override
protected String getVibrationIntensitySetting() {
return Settings.System.RING_VIBRATION_INTENSITY;
}
@Override
protected String getVibrationEnabledSetting() {
if (AccessibilitySettings.isRampingRingerEnabled(getContext())) {
return Settings.System.APPLY_RAMPING_RINGER;
} else {
return Settings.System.VIBRATE_WHEN_RINGING;
}
}
@Override
protected int getPreviewVibrationAudioAttributesUsage() {
return AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
}
@Override
protected int getDefaultVibrationIntensity() {
Vibrator vibrator = getContext().getSystemService(Vibrator.class);
return vibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE);
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import android.content.Context;
import com.android.settings.accessibility.RingVibrationIntensityPreferenceController.RingVibrationPreferenceConfig;
/** Preference controller for ringtone vibration with only a toggle for on/off states. */
public class RingVibrationTogglePreferenceController extends VibrationTogglePreferenceController {
public RingVibrationTogglePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey, new RingVibrationPreferenceConfig(context));
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (C) 2018 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.settings.accessibility;
import android.app.settings.SettingsEnums;
import android.media.AudioAttributes;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import com.android.settings.R;
/**
* Fragment for picking accessibility shortcut service
*/
public class TouchVibrationPreferenceFragment extends VibrationPreferenceFragment {
@Override
public int getMetricsCategory() {
return SettingsEnums.ACCESSIBILITY_VIBRATION_TOUCH;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.accessibility_touch_vibration_settings;
}
/**
* Get the setting string of the vibration intensity setting this preference is dealing with.
*/
@Override
protected String getVibrationIntensitySetting() {
return Settings.System.HAPTIC_FEEDBACK_INTENSITY;
}
@Override
protected String getVibrationEnabledSetting() {
return Settings.System.HAPTIC_FEEDBACK_ENABLED;
}
@Override
protected int getDefaultVibrationIntensity() {
Vibrator vibrator = getContext().getSystemService(Vibrator.class);
return vibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH);
}
@Override
protected int getPreviewVibrationAudioAttributesUsage() {
return AudioAttributes.USAGE_ASSISTANCE_SONIFICATION;
}
}

View File

@@ -17,116 +17,80 @@
package com.android.settings.accessibility;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.SliderPreferenceController;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
public abstract class VibrationIntensityPreferenceController extends BasePreferenceController
/**
* Abstract preference controller for a vibration intensity setting, that displays multiple
* intensity levels to the user as a slider.
*/
public abstract class VibrationIntensityPreferenceController extends SliderPreferenceController
implements LifecycleObserver, OnStart, OnStop {
protected final Vibrator mVibrator;
private final SettingObserver mSettingsContentObserver;
private final String mSettingKey;
private final String mEnabledKey;
private final boolean mSupportRampingRinger;
protected final VibrationPreferenceConfig mPreferenceConfig;
private final VibrationPreferenceConfig.SettingObserver mSettingsContentObserver;
private Preference mPreference;
public VibrationIntensityPreferenceController(Context context, String prefkey,
String settingKey, String enabledKey, boolean supportRampingRinger) {
protected VibrationIntensityPreferenceController(Context context, String prefkey,
VibrationPreferenceConfig preferenceConfig) {
super(context, prefkey);
mVibrator = mContext.getSystemService(Vibrator.class);
mSettingKey = settingKey;
mEnabledKey = enabledKey;
mSupportRampingRinger= supportRampingRinger;
mSettingsContentObserver = new SettingObserver(settingKey) {
@Override
public void onChange(boolean selfChange, Uri uri) {
updateState(mPreference);
}
};
}
public VibrationIntensityPreferenceController(Context context, String prefkey,
String settingKey, String enabledKey) {
this(context, prefkey, settingKey, enabledKey, /* supportRampingRinger= */ false);
mPreferenceConfig = preferenceConfig;
mSettingsContentObserver = new VibrationPreferenceConfig.SettingObserver(
preferenceConfig);
}
@Override
public void onStart() {
mContext.getContentResolver().registerContentObserver(
mSettingsContentObserver.uri,
false /* notifyForDescendants */,
mSettingsContentObserver);
mSettingsContentObserver.register(mContext.getContentResolver());
}
@Override
public void onStop() {
mContext.getContentResolver().unregisterContentObserver(mSettingsContentObserver);
mSettingsContentObserver.unregister(mContext.getContentResolver());
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
final SeekBarPreference preference = screen.findPreference(getPreferenceKey());
mSettingsContentObserver.onDisplayPreference(this, preference);
// TODO: remove this and replace with a different way to play the haptic preview without
// relying on the setting being propagated to the service.
preference.setContinuousUpdates(true);
preference.setMin(getMin());
preference.setMax(getMax());
}
@Override
public CharSequence getSummary() {
final int intensity = Settings.System.getInt(mContext.getContentResolver(),
mSettingKey, getDefaultIntensity());
final boolean enabled = (Settings.System.getInt(mContext.getContentResolver(),
mEnabledKey, 1) == 1) ||
(mSupportRampingRinger && AccessibilitySettings.isRampingRingerEnabled(mContext));
return getIntensityString(mContext, enabled ? intensity : Vibrator.VIBRATION_INTENSITY_OFF);
public int getMin() {
return Vibrator.VIBRATION_INTENSITY_OFF;
}
public static CharSequence getIntensityString(Context context, int intensity) {
final boolean supportsMultipleIntensities = context.getResources().getBoolean(
R.bool.config_vibration_supports_multiple_intensities);
if (supportsMultipleIntensities) {
switch (intensity) {
case Vibrator.VIBRATION_INTENSITY_OFF:
return context.getString(R.string.accessibility_vibration_intensity_off);
case Vibrator.VIBRATION_INTENSITY_LOW:
return context.getString(R.string.accessibility_vibration_intensity_low);
case Vibrator.VIBRATION_INTENSITY_MEDIUM:
return context.getString(R.string.accessibility_vibration_intensity_medium);
case Vibrator.VIBRATION_INTENSITY_HIGH:
return context.getString(R.string.accessibility_vibration_intensity_high);
default:
return "";
}
} else {
if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) {
return context.getString(R.string.switch_off_text);
} else {
return context.getString(R.string.switch_on_text);
}
}
@Override
public int getMax() {
return Vibrator.VIBRATION_INTENSITY_HIGH;
}
protected abstract int getDefaultIntensity();
@Override
public int getSliderPosition() {
final int position = mPreferenceConfig.readIntensity();
return Math.min(position, getMax());
}
private static class SettingObserver extends ContentObserver {
@Override
public boolean setSliderPosition(int position) {
final boolean success = mPreferenceConfig.updateIntensity(position);
public final Uri uri;
if (success && (position != Vibrator.VIBRATION_INTENSITY_OFF)) {
mPreferenceConfig.playVibrationPreview();
}
public SettingObserver(String settingKey) {
super(new Handler(Looper.getMainLooper()));
uri = Settings.System.getUriFor(settingKey);
}
return success;
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.preference.Preference;
import com.android.settingslib.core.AbstractPreferenceController;
/**
* Vibration intensity settings configuration to be shared between different preference
* controllers that handle the same setting key.
*/
public abstract class VibrationPreferenceConfig {
protected final ContentResolver mContentResolver;
private final Vibrator mVibrator;
private final String mSettingKey;
private final int mDefaultIntensity;
private final VibrationAttributes mVibrationAttributes;
public VibrationPreferenceConfig(Context context, String settingKey, int vibrationUsage) {
mContentResolver = context.getContentResolver();
mVibrator = context.getSystemService(Vibrator.class);
mSettingKey = settingKey;
mDefaultIntensity = mVibrator.getDefaultVibrationIntensity(vibrationUsage);
mVibrationAttributes = new VibrationAttributes.Builder()
.setUsage(vibrationUsage)
.build();
}
/** Return the setting key for this setting preference. */
public String getSettingKey() {
return mSettingKey;
}
/** Returns the default intensity to be displayed when the setting value is not set. */
public int getDefaultIntensity() {
return mDefaultIntensity;
}
/** Reads setting value for corresponding {@link VibrationPreferenceConfig} */
public int readIntensity() {
return Settings.System.getInt(mContentResolver, mSettingKey, mDefaultIntensity);
}
/** Update setting value for corresponding {@link VibrationPreferenceConfig} */
public boolean updateIntensity(int intensity) {
return Settings.System.putInt(mContentResolver, mSettingKey, intensity);
}
/** Play a vibration effect with intensity just selected by the user. */
public void playVibrationPreview() {
mVibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK),
mVibrationAttributes);
}
/** {@link ContentObserver} for a setting described by a {@link VibrationPreferenceConfig}. */
public static final class SettingObserver extends ContentObserver {
private final Uri mUri;
private AbstractPreferenceController mPreferenceController;
private Preference mPreference;
/** Creates observer for given preference. */
public SettingObserver(VibrationPreferenceConfig preferenceConfig) {
super(new Handler(/* async= */ true));
mUri = Settings.System.getUriFor(preferenceConfig.getSettingKey());
}
@Override
public void onChange(boolean selfChange, Uri uri) {
if (mUri.equals(uri) && mPreferenceController != null && mPreference != null) {
mPreferenceController.updateState(mPreference);
}
}
/**
* Register this observer to given {@link ContentResolver}, to be called from lifecycle
* {@code onStart} method.
*/
public void register(ContentResolver contentResolver) {
contentResolver.registerContentObserver(mUri, /* notifyForDescendants= */ false, this);
}
/**
* Unregister this observer from given {@link ContentResolver}, to be called from lifecycle
* {@code onStop} method.
*/
public void unregister(ContentResolver contentResolver) {
contentResolver.unregisterContentObserver(this);
}
/**
* Binds this observer to given controller and preference, once it has been displayed to the
* user.
*/
public void onDisplayPreference(AbstractPreferenceController controller,
Preference preference) {
mPreferenceController = controller;
mPreference = preference;
}
}
}

View File

@@ -1,78 +0,0 @@
/*
* Copyright (C) 2019 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.settings.accessibility;
import android.content.Context;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
public class VibrationPreferenceController extends BasePreferenceController {
private final Vibrator mVibrator;
public VibrationPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mVibrator = mContext.getSystemService(Vibrator.class);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public CharSequence getSummary() {
int ringIntensity = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.RING_VIBRATION_INTENSITY,
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
if (Settings.System.getInt(mContext.getContentResolver(),
Settings.System.VIBRATE_WHEN_RINGING, 0) == 0
&& !AccessibilitySettings.isRampingRingerEnabled(mContext)) {
ringIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
}
final CharSequence ringIntensityString =
VibrationIntensityPreferenceController.getIntensityString(mContext, ringIntensity);
final int notificationIntensity = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION));
final CharSequence notificationIntensityString =
VibrationIntensityPreferenceController.getIntensityString(mContext,
notificationIntensity);
int touchIntensity = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_INTENSITY,
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH));
if (Settings.System.getInt(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0) {
touchIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
}
final CharSequence touchIntensityString =
VibrationIntensityPreferenceController.getIntensityString(mContext, touchIntensity);
if (ringIntensity == touchIntensity && ringIntensity == notificationIntensity) {
return ringIntensityString;
} else {
return mContext.getString(R.string.accessibility_vibration_summary, ringIntensityString,
notificationIntensityString, touchIntensityString);
}
}
}

View File

@@ -1,299 +0,0 @@
/*
* Copyright (C) 2018 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.settings.accessibility;
import static android.os.Vibrator.VibrationIntensity;
import android.content.Context;
import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
import android.media.AudioAttributes;
import android.net.Uri;
import android.os.Handler;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.widget.RadioButtonPickerFragment;
import com.android.settingslib.widget.CandidateInfo;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
/**
* Fragment for changing vibration settings.
*/
public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragment {
private static final String TAG = "VibrationPreferenceFragment";
@VisibleForTesting
final static String KEY_INTENSITY_OFF = "intensity_off";
@VisibleForTesting
final static String KEY_INTENSITY_LOW = "intensity_low";
@VisibleForTesting
final static String KEY_INTENSITY_MEDIUM = "intensity_medium";
@VisibleForTesting
final static String KEY_INTENSITY_HIGH = "intensity_high";
// KEY_INTENSITY_ON is only used when the device doesn't support multiple intensity levels.
@VisibleForTesting
final static String KEY_INTENSITY_ON = "intensity_on";
private final Map<String, VibrationIntensityCandidateInfo> mCandidates;
private final SettingsObserver mSettingsObserver;
public VibrationPreferenceFragment() {
mCandidates = new ArrayMap<>();
mSettingsObserver = new SettingsObserver();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mSettingsObserver.register();
if (mCandidates.isEmpty()) {
loadCandidates(context);
}
}
private void loadCandidates(Context context) {
final boolean supportsMultipleIntensities = context.getResources().getBoolean(
R.bool.config_vibration_supports_multiple_intensities);
if (supportsMultipleIntensities) {
mCandidates.put(KEY_INTENSITY_OFF,
new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
R.string.accessibility_vibration_intensity_off,
Vibrator.VIBRATION_INTENSITY_OFF));
mCandidates.put(KEY_INTENSITY_LOW,
new VibrationIntensityCandidateInfo(KEY_INTENSITY_LOW,
R.string.accessibility_vibration_intensity_low,
Vibrator.VIBRATION_INTENSITY_LOW));
mCandidates.put(KEY_INTENSITY_MEDIUM,
new VibrationIntensityCandidateInfo(KEY_INTENSITY_MEDIUM,
R.string.accessibility_vibration_intensity_medium,
Vibrator.VIBRATION_INTENSITY_MEDIUM));
mCandidates.put(KEY_INTENSITY_HIGH,
new VibrationIntensityCandidateInfo(KEY_INTENSITY_HIGH,
R.string.accessibility_vibration_intensity_high,
Vibrator.VIBRATION_INTENSITY_HIGH));
} else {
mCandidates.put(KEY_INTENSITY_OFF,
new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
R.string.switch_off_text, Vibrator.VIBRATION_INTENSITY_OFF));
mCandidates.put(KEY_INTENSITY_ON,
new VibrationIntensityCandidateInfo(KEY_INTENSITY_ON,
R.string.switch_on_text, getDefaultVibrationIntensity()));
}
}
private boolean hasVibrationEnabledSetting() {
return !TextUtils.isEmpty(getVibrationEnabledSetting());
}
private void updateSettings(VibrationIntensityCandidateInfo candidate) {
boolean vibrationEnabled = candidate.getIntensity() != Vibrator.VIBRATION_INTENSITY_OFF;
if (hasVibrationEnabledSetting()) {
// Update vibration enabled setting
final String vibrationEnabledSetting = getVibrationEnabledSetting();
final boolean wasEnabled = TextUtils.equals(
vibrationEnabledSetting, Settings.System.APPLY_RAMPING_RINGER)
? true
: (Settings.System.getInt(
getContext().getContentResolver(), vibrationEnabledSetting, 1) == 1);
if (vibrationEnabled != wasEnabled) {
if (vibrationEnabledSetting.equals(Settings.System.APPLY_RAMPING_RINGER)) {
Settings.Global.putInt(getContext().getContentResolver(),
vibrationEnabledSetting, 0);
} else {
Settings.System.putInt(getContext().getContentResolver(),
vibrationEnabledSetting, vibrationEnabled ? 1 : 0);
}
int previousIntensity = Settings.System.getInt(getContext().getContentResolver(),
getVibrationIntensitySetting(), 0);
if (vibrationEnabled && previousIntensity == candidate.getIntensity()) {
// We can't play preview effect here for all cases because that causes a data
// race (VibratorService may access intensity settings before these settings
// are updated). But we can't just play it in intensity settings update
// observer, because the intensity settings are not changed if we turn the
// vibration off, then on.
//
// In this case we sould play the preview here.
// To be refactored in b/132952771
playVibrationPreview();
}
}
}
// There are two conditions that need to change the intensity.
// First: Vibration is enabled and we are changing its strength.
// Second: There is no setting to enable this vibration, change the intensity directly.
if (vibrationEnabled || !hasVibrationEnabledSetting()) {
// Update vibration intensity setting
Settings.System.putInt(getContext().getContentResolver(),
getVibrationIntensitySetting(), candidate.getIntensity());
}
}
@Override
public void onDetach() {
super.onDetach();
mSettingsObserver.unregister();
}
/**
* Get the setting string of the vibration intensity setting this preference is dealing with.
*/
protected abstract String getVibrationIntensitySetting();
/**
* Get the setting string of the vibration enabledness setting this preference is dealing with.
*/
protected abstract String getVibrationEnabledSetting();
/**
* Get the default intensity for the desired setting.
*/
protected abstract int getDefaultVibrationIntensity();
/**
* When a new vibration intensity is selected by the user.
*/
protected void onVibrationIntensitySelected(int intensity) { }
/**
* Play a vibration effect with intensity just selected by user
*/
protected void playVibrationPreview() {
Vibrator vibrator = getContext().getSystemService(Vibrator.class);
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
AudioAttributes.Builder builder = new AudioAttributes.Builder();
builder.setUsage(getPreviewVibrationAudioAttributesUsage());
vibrator.vibrate(effect, builder.build());
}
/**
* Get the AudioAttributes usage for vibration preview.
*/
protected int getPreviewVibrationAudioAttributesUsage() {
return AudioAttributes.USAGE_UNKNOWN;
}
@Override
protected List<? extends CandidateInfo> getCandidates() {
List<VibrationIntensityCandidateInfo> candidates = new ArrayList<>(mCandidates.values());
candidates.sort(
Comparator.comparing(VibrationIntensityCandidateInfo::getIntensity).reversed());
return candidates;
}
@Override
protected String getDefaultKey() {
int vibrationIntensity = Settings.System.getInt(getContext().getContentResolver(),
getVibrationIntensitySetting(), getDefaultVibrationIntensity());
final String vibrationEnabledSetting = getVibrationEnabledSetting();
final boolean vibrationEnabled = TextUtils.equals(
vibrationEnabledSetting, Settings.System.APPLY_RAMPING_RINGER)
? true
: (Settings.System.getInt(
getContext().getContentResolver(), vibrationEnabledSetting, 1) == 1);
if (!vibrationEnabled) {
vibrationIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
}
for (VibrationIntensityCandidateInfo candidate : mCandidates.values()) {
final boolean matchesIntensity = candidate.getIntensity() == vibrationIntensity;
final boolean matchesOn = candidate.getKey().equals(KEY_INTENSITY_ON)
&& vibrationIntensity != Vibrator.VIBRATION_INTENSITY_OFF;
if (matchesIntensity || matchesOn) {
return candidate.getKey();
}
}
return null;
}
@Override
protected boolean setDefaultKey(String key) {
VibrationIntensityCandidateInfo candidate = mCandidates.get(key);
if (candidate == null) {
Log.e(TAG, "Tried to set unknown intensity (key=" + key + ")!");
return false;
}
updateSettings(candidate);
onVibrationIntensitySelected(candidate.getIntensity());
return true;
}
@VisibleForTesting
class VibrationIntensityCandidateInfo extends CandidateInfo {
private String mKey;
private int mLabelId;
@VibrationIntensity
private int mIntensity;
public VibrationIntensityCandidateInfo(String key, int labelId, int intensity) {
super(true /* enabled */);
mKey = key;
mLabelId = labelId;
mIntensity = intensity;
}
@Override
public CharSequence loadLabel() {
return getContext().getString(mLabelId);
}
@Override
public Drawable loadIcon() {
return null;
}
@Override
public String getKey() {
return mKey;
}
public int getIntensity() {
return mIntensity;
}
}
private class SettingsObserver extends ContentObserver {
public SettingsObserver() {
super(new Handler());
}
public void register() {
getContext().getContentResolver().registerContentObserver(
Settings.System.getUriFor(getVibrationIntensitySetting()), false, this);
}
public void unregister() {
getContext().getContentResolver().unregisterContentObserver(this);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
updateCandidates();
playVibrationPreview();
}
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import android.content.Context;
import android.database.ContentObserver;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.DeviceConfig;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.google.common.annotations.VisibleForTesting;
/**
* Preference controller for the ramping ringer setting key, controlled via {@link AudioManager}.
*
* <p>This preference depends on the {@link Settings.System#RING_VIBRATION_INTENSITY}, and it will
* be disabled and display the unchecked state when the ring intensity is set to OFF. The actual
* ramping ringer setting will not be overwritten when the ring intensity is turned off, so the
* user original value will be naturally restored when the ring intensity is enabled again.
*/
public class VibrationRampingRingerTogglePreferenceController
extends TogglePreferenceController implements LifecycleObserver, OnStart, OnStop {
@VisibleForTesting
static final String DEVICE_CONFIG_KEY = "ramping_ringer_enabled";
private final ContentObserver mSettingObserver;
private final Vibrator mVibrator;
private final AudioManager mAudioManager;
private Preference mPreference;
public VibrationRampingRingerTogglePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mVibrator = context.getSystemService(Vibrator.class);
mAudioManager = context.getSystemService(AudioManager.class);
mSettingObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange, Uri uri) {
updateState(mPreference);
}
};
}
@Override
public int getAvailabilityStatus() {
final boolean rampingRingerEnabledOnTelephonyConfig =
DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_TELEPHONY, DEVICE_CONFIG_KEY, false);
return (Utils.isVoiceCapable(mContext) && !rampingRingerEnabledOnTelephonyConfig)
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@Override
public void onStart() {
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.APPLY_RAMPING_RINGER),
/* notifyForDescendants= */ false,
mSettingObserver);
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY),
/* notifyForDescendants= */ false,
mSettingObserver);
}
@Override
public void onStop() {
mContext.getContentResolver().unregisterContentObserver(mSettingObserver);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
mPreference.setEnabled(isRingVibrationEnabled());
}
@Override
public boolean isChecked() {
return isRingVibrationEnabled() && mAudioManager.isRampingRingerEnabled();
}
@Override
public boolean setChecked(boolean isChecked) {
if (isRingVibrationEnabled()) {
// Don't update ramping ringer setting value if ring vibration is disabled.
mAudioManager.setRampingRingerEnabled(isChecked);
}
return true;
}
@Override
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (preference != null) {
preference.setEnabled(isRingVibrationEnabled());
}
}
private boolean isRingVibrationEnabled() {
final int ringIntensity = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.RING_VIBRATION_INTENSITY,
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
return ringIntensity != Vibrator.VIBRATION_INTENSITY_OFF;
}
}

View File

@@ -41,7 +41,11 @@ public class VibrationSettings extends DashboardFragment {
@Override
protected int getPreferenceScreenResId() {
return R.xml.accessibility_vibration_settings;
final boolean supportsMultipleIntensities = getContext().getResources().getBoolean(
R.bool.config_vibration_supports_multiple_intensities);
return supportsMultipleIntensities
? R.xml.accessibility_vibration_intensity_settings
: R.xml.accessibility_vibration_settings;
}
@Override

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import android.content.Context;
import android.os.Vibrator;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
/** Abstract preference controller for a vibration intensity setting, that has only ON/OFF states */
public abstract class VibrationTogglePreferenceController extends TogglePreferenceController
implements LifecycleObserver, OnStart, OnStop {
protected final VibrationPreferenceConfig mPreferenceConfig;
private final VibrationPreferenceConfig.SettingObserver mSettingsContentObserver;
protected VibrationTogglePreferenceController(Context context, String preferenceKey,
VibrationPreferenceConfig preferenceConfig) {
super(context, preferenceKey);
mPreferenceConfig = preferenceConfig;
mSettingsContentObserver = new VibrationPreferenceConfig.SettingObserver(
preferenceConfig);
}
@Override
public void onStart() {
mSettingsContentObserver.register(mContext.getContentResolver());
}
@Override
public void onStop() {
mSettingsContentObserver.unregister(mContext.getContentResolver());
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
final Preference preference = screen.findPreference(getPreferenceKey());
mSettingsContentObserver.onDisplayPreference(this, preference);
}
@Override
public boolean isChecked() {
final int position = mPreferenceConfig.readIntensity();
return position != Vibrator.VIBRATION_INTENSITY_OFF;
}
@Override
public boolean setChecked(boolean isChecked) {
final int newIntensity = isChecked
? mPreferenceConfig.getDefaultIntensity()
: Vibrator.VIBRATION_INTENSITY_OFF;
final boolean success = mPreferenceConfig.updateIntensity(newIntensity);
if (success && isChecked) {
mPreferenceConfig.playVibrationPreview();
}
return success;
}
@Override
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
}

View File

@@ -25,7 +25,6 @@ import androidx.preference.Preference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.notification.app.NotificationPreferenceController;
import com.android.settingslib.RestrictedSwitchPreference;
public class VibrationPreferenceController extends NotificationPreferenceController
@@ -36,7 +35,7 @@ public class VibrationPreferenceController extends NotificationPreferenceControl
public VibrationPreferenceController(Context context, NotificationBackend backend) {
super(context, backend);
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mVibrator = context.getSystemService(Vibrator.class);
}
@Override

View File

@@ -1,66 +0,0 @@
/*
* Copyright (C) 2020 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.settings.sound;
import android.content.Context;
import android.provider.DeviceConfig;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
/**
* Controller for vibrate for calls settings.
*/
public class VibrateForCallsPreferenceController extends BasePreferenceController {
private static final int ON = 1;
private static final int OFF = 0;
@VisibleForTesting
static final String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled";
public VibrateForCallsPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
@AvailabilityStatus
public int getAvailabilityStatus() {
return Utils.isVoiceCapable(mContext) && !DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_TELEPHONY, RAMPING_RINGER_ENABLED, false)
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@Override
public CharSequence getSummary() {
if (Settings.System.getInt(
mContext.getContentResolver(),
Settings.System.APPLY_RAMPING_RINGER, OFF) == ON) {
return mContext.getText(R.string.vibrate_when_ringing_option_ramping_ringer);
} else if (Settings.System.getInt(
mContext.getContentResolver(),
Settings.System.VIBRATE_WHEN_RINGING, OFF) == ON) {
return mContext.getText(R.string.vibrate_when_ringing_option_always_vibrate);
} else {
return mContext.getText(R.string.vibrate_when_ringing_option_never_vibrate);
}
}
}

View File

@@ -1,167 +0,0 @@
/*
* Copyright (C) 2019 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.settings.sound;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.widget.RadioButtonPickerFragment;
import com.android.settingslib.widget.CandidateInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Fragment for changing vibrate for calls options.
*/
public class VibrateForCallsPreferenceFragment extends RadioButtonPickerFragment {
private static final String TAG = "VibrateForCallsPreferenceFragment";
@VisibleForTesting
static final String KEY_NEVER_VIBRATE = "never_vibrate";
@VisibleForTesting
static final String KEY_ALWAYS_VIBRATE = "always_vibrate";
@VisibleForTesting
static final String KEY_RAMPING_RINGER = "ramping_ringer";
private static final int ON = 1;
private static final int OFF = 0;
private final Map<String, VibrateForCallsCandidateInfo> mCandidates;
public VibrateForCallsPreferenceFragment() {
mCandidates = new ArrayMap<>();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
loadCandidates(context);
}
private void loadCandidates(Context context) {
mCandidates.put(KEY_NEVER_VIBRATE,
new VibrateForCallsCandidateInfo(
KEY_NEVER_VIBRATE, R.string.vibrate_when_ringing_option_never_vibrate));
mCandidates.put(KEY_ALWAYS_VIBRATE,
new VibrateForCallsCandidateInfo(
KEY_ALWAYS_VIBRATE, R.string.vibrate_when_ringing_option_always_vibrate));
mCandidates.put(KEY_RAMPING_RINGER,
new VibrateForCallsCandidateInfo(
KEY_RAMPING_RINGER, R.string.vibrate_when_ringing_option_ramping_ringer));
}
private void updateSettings(VibrateForCallsCandidateInfo candidate) {
final String key = candidate.getKey();
if (TextUtils.equals(key, KEY_ALWAYS_VIBRATE)) {
Settings.System.putInt(
getContext().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, ON);
Settings.System.putInt(
getContext().getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, OFF);
} else if (TextUtils.equals(key, KEY_RAMPING_RINGER)) {
Settings.System.putInt(
getContext().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, OFF);
Settings.System.putInt(
getContext().getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, ON);
} else {
Settings.System.putInt(
getContext().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, OFF);
Settings.System.putInt(
getContext().getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, OFF);
}
}
@Override
protected List<? extends CandidateInfo> getCandidates() {
final List<VibrateForCallsCandidateInfo> candidates = new ArrayList<>();
candidates.add(mCandidates.get(KEY_NEVER_VIBRATE));
candidates.add(mCandidates.get(KEY_ALWAYS_VIBRATE));
candidates.add(mCandidates.get(KEY_RAMPING_RINGER));
return candidates;
}
@Override
protected String getDefaultKey() {
if (Settings.System.getInt(
getContext().getContentResolver(),
Settings.System.APPLY_RAMPING_RINGER, OFF) == ON) {
return KEY_RAMPING_RINGER;
} else if (Settings.System.getInt(
getContext().getContentResolver(),
Settings.System.VIBRATE_WHEN_RINGING, OFF) == ON) {
return KEY_ALWAYS_VIBRATE;
} else {
return KEY_NEVER_VIBRATE;
}
}
@Override
protected boolean setDefaultKey(String key) {
final VibrateForCallsCandidateInfo candidate = mCandidates.get(key);
if (candidate == null) {
Log.e(TAG, "Unknown vibrate for calls candidate (key = " + key + ")!");
return false;
}
updateSettings(candidate);
return true;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.vibrate_for_calls_settings;
}
@Override
public int getMetricsCategory() {
return SettingsEnums.VIBRATE_FOR_CALLS;
}
@VisibleForTesting
class VibrateForCallsCandidateInfo extends CandidateInfo {
private final String mKey;
private final int mLabelId;
VibrateForCallsCandidateInfo(String key, int labelId) {
super(true /* enabled */);
mKey = key;
mLabelId = labelId;
}
@Override
public CharSequence loadLabel() {
return getContext().getString(mLabelId);
}
@Override
public Drawable loadIcon() {
return null;
}
@Override
public String getKey() {
return mKey;
}
}
}

View File

@@ -52,7 +52,6 @@ import androidx.test.core.app.ApplicationProvider;
import com.android.internal.content.PackageMonitor;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedPreference;
@@ -143,22 +142,6 @@ public class AccessibilitySettingsTest {
assertThat(indexableRawList).isNull();
}
@Test
@Config(shadows = {ShadowDeviceConfig.class})
public void isRampingRingerEnabled_settingsFlagOn_Enabled() {
Settings.System.putInt(
mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, ON);
assertThat(AccessibilitySettings.isRampingRingerEnabled(mContext)).isTrue();
}
@Test
@Config(shadows = {ShadowDeviceConfig.class})
public void isRampingRingerEnabled_settingsFlagOff_Disabled() {
Settings.System.putInt(
mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, OFF);
assertThat(AccessibilitySettings.isRampingRingerEnabled(mContext)).isFalse();
}
@Test
public void getServiceSummary_serviceCrash_showsStopped() {
mServiceInfo.crashed = true;

View File

@@ -18,42 +18,136 @@ package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
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;
@RunWith(RobolectricTestRunner.class)
public class HapticFeedbackIntensityPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
private static final int OFF = 0;
private static final int ON = 1;
@Mock
private PreferenceScreen mScreen;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
private Vibrator mVibrator;
private HapticFeedbackIntensityPreferenceController mController;
private SeekBarPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mContext = RuntimeEnvironment.application;
mController = new HapticFeedbackIntensityPreferenceController(mContext);
mContext = spy(ApplicationProvider.getApplicationContext());
mVibrator = mContext.getSystemService(Vibrator.class);
mController = new HapticFeedbackIntensityPreferenceController(mContext, PREFERENCE_KEY);
mLifecycle.addObserver(mController);
mPreference = new SeekBarPreference(mContext);
mPreference.setSummary("Test summary");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
showPreference();
}
@Test
public void verifyConstants() {
assertThat(mController.getPreferenceKey())
.isEqualTo(HapticFeedbackIntensityPreferenceController.PREF_KEY);
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
}
@Test
public void missingSetting_shouldReturnDefault() {
Settings.System.putString(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_INTENSITY, /* value= */ null);
mController.updateState(mPreference);
assertThat(mPreference.getProgress())
.isEqualTo(mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH));
}
@Test
public void updateState_shouldDisplayIntensityInSliderPosition() {
updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
}
@Test
public void setProgress_updatesIntensityAndDependentSettings() throws Exception {
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(OFF);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_LOW);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_MEDIUM);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_HIGH);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(OFF);
}
private void updateSetting(String key, int value) {
Settings.System.putInt(mContext.getContentResolver(), key, value);
}
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
private void showPreference() {
mController.displayPreference(mScreen);
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
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;
@RunWith(RobolectricTestRunner.class)
public class HapticFeedbackTogglePreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
private static final int OFF = 0;
private static final int ON = 1;
@Mock
private PreferenceScreen mScreen;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
private Vibrator mVibrator;
private HapticFeedbackTogglePreferenceController mController;
private SwitchPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mContext = spy(ApplicationProvider.getApplicationContext());
mVibrator = mContext.getSystemService(Vibrator.class);
mController = new HapticFeedbackTogglePreferenceController(mContext, PREFERENCE_KEY);
mLifecycle.addObserver(mController);
mPreference = new SwitchPreference(mContext);
mPreference.setSummary("Test summary");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
showPreference();
}
@Test
public void verifyConstants() {
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void missingSetting_shouldReturnDefault() {
Settings.System.putString(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_INTENSITY, /* value= */ null);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void updateState_shouldDisplayOnOffState() {
updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
mPreference.setChecked(true);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
.isEqualTo(mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH));
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
mPreference.setChecked(false);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(OFF);
}
private void updateSetting(String key, int value) {
Settings.System.putInt(mContext.getContentResolver(), key, value);
}
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
private void showPreference() {
mController.displayPreference(mScreen);
}
}

View File

@@ -16,24 +16,22 @@
package com.android.settings.accessibility;
import static android.provider.Settings.System.NOTIFICATION_VIBRATION_INTENSITY;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -42,115 +40,105 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class NotificationVibrationIntensityPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Mock
private PreferenceScreen mScreen;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
private Resources mResources;
private Vibrator mVibrator;
private NotificationVibrationIntensityPreferenceController mController;
private Preference mPreference;
private SeekBarPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mContext = spy(RuntimeEnvironment.application);
mResources = spy(mContext.getResources());
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
.thenReturn(true);
mController = new NotificationVibrationIntensityPreferenceController(mContext) {
@Override
protected int getDefaultIntensity() {
return 10;
}
};
mContext = spy(ApplicationProvider.getApplicationContext());
mVibrator = mContext.getSystemService(Vibrator.class);
mController = new NotificationVibrationIntensityPreferenceController(mContext,
PREFERENCE_KEY);
mLifecycle.addObserver(mController);
mPreference = new Preference(mContext);
mPreference.setSummary("Test");
when(mScreen.findPreference(mController.getPreferenceKey()))
.thenReturn(mPreference);
mPreference = new SeekBarPreference(mContext);
mPreference.setSummary("Test summary");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
showPreference();
}
@Test
public void verifyConstants() {
assertThat(mController.getPreferenceKey())
.isEqualTo(NotificationVibrationIntensityPreferenceController.PREF_KEY);
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
}
@Test
public void updateState_withMultipleIntensitySuport_shouldRefreshSummary() {
setSupportsMultipleIntensities(true);
showPreference();
Settings.System.putInt(mContext.getContentResolver(),
NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
public void missingSetting_shouldReturnDefault() {
Settings.System.putString(mContext.getContentResolver(),
Settings.System.NOTIFICATION_VIBRATION_INTENSITY, /* value= */ null);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_low));
Settings.System.putInt(mContext.getContentResolver(),
NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_high));
Settings.System.putInt(mContext.getContentResolver(),
NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_medium));
Settings.System.putInt(mContext.getContentResolver(),
NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_off));
assertThat(mPreference.getProgress()).isEqualTo(
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION));
}
@Test
public void updateState_withoutMultipleIntensitySupport_shouldRefreshSummary() {
setSupportsMultipleIntensities(false);
showPreference();
Settings.System.putInt(mContext.getContentResolver(),
NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
public void updateState_shouldDisplayIntensityInSliderPosition() {
updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.switch_on_text));
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
Settings.System.putInt(mContext.getContentResolver(),
NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.switch_on_text));
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
Settings.System.putInt(mContext.getContentResolver(),
NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.switch_on_text));
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
Settings.System.putInt(mContext.getContentResolver(),
NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mContext.getString(R.string.switch_off_text));
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
}
private void setSupportsMultipleIntensities(boolean hasSupport) {
when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
.thenReturn(hasSupport);
@Test
public void setProgress_updatesIntensitySetting() throws Exception {
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_LOW);
assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_MEDIUM);
assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_HIGH);
assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
}
private void updateSetting(String key, int value) {
Settings.System.putInt(mContext.getContentResolver(), key, value);
}
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
private void showPreference() {

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
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;
@RunWith(RobolectricTestRunner.class)
public class NotificationVibrationTogglePreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Mock
private PreferenceScreen mScreen;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
private Vibrator mVibrator;
private NotificationVibrationTogglePreferenceController mController;
private SwitchPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mContext = spy(ApplicationProvider.getApplicationContext());
mVibrator = mContext.getSystemService(Vibrator.class);
mController = new NotificationVibrationTogglePreferenceController(mContext, PREFERENCE_KEY);
mLifecycle.addObserver(mController);
mPreference = new SwitchPreference(mContext);
mPreference.setSummary("Test summary");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
showPreference();
}
@Test
public void verifyConstants() {
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void missingSetting_shouldReturnDefault() {
Settings.System.putString(mContext.getContentResolver(),
Settings.System.NOTIFICATION_VIBRATION_INTENSITY, /* value= */ null);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void updateState_shouldDisplayOnOffState() {
updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
mPreference.setChecked(true);
assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY)).isEqualTo(
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION));
mPreference.setChecked(false);
assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
}
private void updateSetting(String key, int value) {
Settings.System.putInt(mContext.getContentResolver(), key, value);
}
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
private void showPreference() {
mController.displayPreference(mScreen);
}
}

View File

@@ -16,20 +16,24 @@
package com.android.settings.accessibility;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -40,30 +44,112 @@ import org.robolectric.RobolectricTestRunner;
/** Tests for {@link RingVibrationIntensityPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class RingVibrationIntensityPreferenceControllerTest {
@Mock
private Vibrator mVibrator;
private static final String PREFERENCE_KEY = "preference_key";
private static final int OFF = 0;
private static final int ON = 1;
@Mock
private PreferenceScreen mScreen;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
private Vibrator mVibrator;
private RingVibrationIntensityPreferenceController mController;
private SeekBarPreference mPreference;
@Before
public void setUp() throws Exception {
public void setUp() {
MockitoAnnotations.initMocks(this);
final Context mContext = spy(ApplicationProvider.getApplicationContext());
doReturn(mVibrator).when(mContext).getSystemService(Vibrator.class);
mController = new RingVibrationIntensityPreferenceController(mContext);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mContext = spy(ApplicationProvider.getApplicationContext());
mVibrator = mContext.getSystemService(Vibrator.class);
mController = new RingVibrationIntensityPreferenceController(mContext, PREFERENCE_KEY);
mLifecycle.addObserver(mController);
mPreference = new SeekBarPreference(mContext);
mPreference.setSummary("Test summary");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
showPreference();
}
@Test
public void getAvailabilityStatus_available() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
public void verifyConstants() {
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
}
@Test
public void getDefaultIntensity_success() {
doReturn(/* toBeReturned= */ 5).when(mVibrator).getDefaultVibrationIntensity(
eq(VibrationAttributes.USAGE_RINGTONE));
public void missingSetting_shouldReturnDefault() {
Settings.System.putString(mContext.getContentResolver(),
Settings.System.RING_VIBRATION_INTENSITY, /* value= */ null);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
}
assertThat(mController.getDefaultIntensity()).isEqualTo(/* expected= */ 5);
@Test
public void updateState_shouldDisplayIntensityInSliderPosition() {
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
updateSetting(Settings.System.RING_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
}
@Test
public void setProgress_updatesIntensityAndDependentSettings() throws Exception {
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(OFF);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_LOW);
assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_MEDIUM);
assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_HIGH);
assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(OFF);
}
private void updateSetting(String key, int value) {
Settings.System.putInt(mContext.getContentResolver(), key, value);
}
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
private void showPreference() {
mController.displayPreference(mScreen);
}
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright (C) 2019 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.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
public class RingVibrationPreferenceFragmentTest {
private Context mContext;
private RingVibrationPreferenceFragment mFragment;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mFragment = spy(new RingVibrationPreferenceFragment());
doReturn(mContext).when(mFragment).getContext();
}
@Test
@Config(shadows = {ShadowDeviceConfig.class})
public void getVibrationEnabledSetting_rampingRingerEnabled_returnApplyRampingRinger() {
// Turn on both flags to enable ramping ringer.
Settings.System.putInt(
mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, 1 /* ON */);
assertThat(mFragment.getVibrationEnabledSetting()).isEqualTo(
Settings.System.APPLY_RAMPING_RINGER);
}
@Test
public void getVibrationEnabledSetting_rampingRingerDisabled_returnVibrationWhenRinging() {
// Turn off Settings.System.APPLY_RAMPING_RINGER to disable ramping ringer.
Settings.System.putInt(
mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, 0 /* OFF */);
assertThat(mFragment.getVibrationEnabledSetting()).isEqualTo(
Settings.System.VIBRATE_WHEN_RINGING);
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
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;
@RunWith(RobolectricTestRunner.class)
public class RingVibrationTogglePreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
private static final int OFF = 0;
private static final int ON = 1;
@Mock
private PreferenceScreen mScreen;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
private Vibrator mVibrator;
private RingVibrationTogglePreferenceController mController;
private SwitchPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mContext = spy(ApplicationProvider.getApplicationContext());
mVibrator = mContext.getSystemService(Vibrator.class);
mController = new RingVibrationTogglePreferenceController(mContext, PREFERENCE_KEY);
mLifecycle.addObserver(mController);
mPreference = new SwitchPreference(mContext);
mPreference.setSummary("Test summary");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
showPreference();
}
@Test
public void verifyConstants() {
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void missingSetting_shouldReturnDefault() {
Settings.System.putString(mContext.getContentResolver(),
Settings.System.RING_VIBRATION_INTENSITY, /* value= */ null);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void updateState_shouldDisplayOnOffState() {
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.RING_VIBRATION_INTENSITY,
Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
mPreference.setChecked(true);
assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY)).isEqualTo(
mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
mPreference.setChecked(false);
assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
.isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(OFF);
}
private void updateSetting(String key, int value) {
Settings.System.putInt(mContext.getContentResolver(), key, value);
}
private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
private void showPreference() {
mController.displayPreference(mScreen);
}
}

View File

@@ -1,87 +0,0 @@
/*
* Copyright (C) 2019 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.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.Vibrator;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class VibrationPreferenceControllerTest {
private static final String VIBRATION_ON = "On";
private static final String VIBRATION_OFF = "Off";
private Context mContext;
private VibrationPreferenceController mController;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new VibrationPreferenceController(mContext, "vibration_pref");
}
@Test
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getSummary_disabledVibration_shouldReturnOffSummary() {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
final String expectedResult = mContext.getString(R.string.switch_off_text);
assertThat(mController.getSummary()).isEqualTo(expectedResult);
}
@Test
public void getSummary_enabledSomeVibration_shouldReturnVibrationOnSummary() {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.VIBRATE_WHEN_RINGING, 1);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
final String expectedResult = mContext.getString(R.string.accessibility_vibration_summary,
VIBRATION_ON /* ring */,
VIBRATION_OFF /* notification */,
VIBRATION_ON /* touch */);
assertThat(mController.getSummary()).isEqualTo(expectedResult);
}
}

View File

@@ -1,178 +0,0 @@
/*
* Copyright (C) 2018 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.settings.accessibility;
import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_HIGH;
import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_LOW;
import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_MEDIUM;
import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_OFF;
import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_ON;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.accessibility.VibrationPreferenceFragment
.VibrationIntensityCandidateInfo;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.widget.CandidateInfo;
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;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RunWith(RobolectricTestRunner.class)
public class VibrationPreferenceFragmentTest {
private static final Map<Integer, String> INTENSITY_TO_KEY = new HashMap<>(4);
static {
INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_OFF, KEY_INTENSITY_OFF);
INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_LOW, KEY_INTENSITY_LOW);
INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_MEDIUM, KEY_INTENSITY_MEDIUM);
INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_HIGH, KEY_INTENSITY_HIGH);
}
@Mock
private UserManager mUserManager;
private Context mContext;
private Resources mResources;
private TestVibrationPreferenceFragment mFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest();
mContext = spy(RuntimeEnvironment.application);
mResources = spy(mContext.getResources());
when(mContext.getResources()).thenReturn(mResources);
mFragment = spy(new TestVibrationPreferenceFragment());
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
}
@Test
public void changeIntensitySetting_shouldResultInCorrespondingKey() {
setSupportsMultipleIntensities(true);
mFragment.onAttach(mContext);
for (Map.Entry<Integer, String> entry : INTENSITY_TO_KEY.entrySet()) {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_INTENSITY, entry.getKey());
assertThat(mFragment.getDefaultKey()).isEqualTo(entry.getValue());
}
}
@Test
public void changeIntensitySetting_WithoutMultipleIntensitySupport_shouldResultInOn() {
setSupportsMultipleIntensities(false);
mFragment.onAttach(mContext);
for (int intensity : INTENSITY_TO_KEY.keySet()) {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_INTENSITY, intensity);
final String expectedKey = intensity == Vibrator.VIBRATION_INTENSITY_OFF
? KEY_INTENSITY_OFF
: KEY_INTENSITY_ON;
assertThat(mFragment.getDefaultKey()).isEqualTo(expectedKey);
}
}
@Test
public void initialDefaultKey_shouldBeMedium() {
setSupportsMultipleIntensities(true);
mFragment.onAttach(mContext);
assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_MEDIUM);
}
@Test
public void initialDefaultKey_WithoutMultipleIntensitySupport_shouldBeOn() {
setSupportsMultipleIntensities(false);
mFragment.onAttach(mContext);
assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_ON);
}
@Test
public void candidates_shouldBeSortedByIntensity() {
setSupportsMultipleIntensities(true);
mFragment.onAttach(mContext);
final List<? extends CandidateInfo> candidates = mFragment.getCandidates();
assertThat(candidates.size()).isEqualTo(INTENSITY_TO_KEY.size());
VibrationIntensityCandidateInfo prevCandidate =
(VibrationIntensityCandidateInfo) candidates.get(0);
for (int i = 1; i < candidates.size(); i++) {
VibrationIntensityCandidateInfo candidate =
(VibrationIntensityCandidateInfo) candidates.get(i);
assertThat(candidate.getIntensity()).isLessThan(prevCandidate.getIntensity());
}
}
private void setSupportsMultipleIntensities(boolean hasSupport) {
when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
.thenReturn(hasSupport);
}
private class TestVibrationPreferenceFragment extends VibrationPreferenceFragment {
@Override
protected int getPreferenceScreenResId() {
return 0;
}
@Override
public int getMetricsCategory() {
return 0;
}
/**
* Get the setting string of the vibration intensity setting this preference is dealing with.
*/
@Override
protected String getVibrationIntensitySetting() {
return Settings.System.HAPTIC_FEEDBACK_INTENSITY;
}
@Override
protected String getVibrationEnabledSetting() {
return "";
}
@Override
protected int getDefaultVibrationIntensity() {
return Vibrator.VIBRATION_INTENSITY_MEDIUM;
}
@Override
public Context getContext() {
return mContext;
}
}
}

View File

@@ -0,0 +1,169 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.media.AudioManager;
import android.os.Vibrator;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
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;
@RunWith(RobolectricTestRunner.class)
public class VibrationRampingRingerTogglePreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@Mock
private PreferenceScreen mScreen;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private AudioManager mAudioManager;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
private VibrationRampingRingerTogglePreferenceController mController;
private SwitchPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mContext = spy(ApplicationProvider.getApplicationContext());
when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
mController = new VibrationRampingRingerTogglePreferenceController(mContext,
PREFERENCE_KEY);
mLifecycle.addObserver(mController);
mPreference = new SwitchPreference(mContext);
mPreference.setSummary("Test summary");
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
showPreference();
}
@Test
public void verifyConstants() {
assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
}
@Test
public void getAvailabilityStatus_notVoiceCapable_returnUnsupportedOnDevice() {
when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
VibrationRampingRingerTogglePreferenceController.DEVICE_CONFIG_KEY, "false", false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_rampingRingerEnabled_returnUnsupportedOnDevice() {
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
VibrationRampingRingerTogglePreferenceController.DEVICE_CONFIG_KEY, "true", false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_voiceCapableAndRampingRingerDisabled_returnAvailable() {
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
VibrationRampingRingerTogglePreferenceController.DEVICE_CONFIG_KEY, "false", false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void updateState_withRingDisabled_shouldReturnFalseForCheckedAndEnabled() {
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
when(mAudioManager.isRampingRingerEnabled()).thenReturn(true);
mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isFalse();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void updateState_withRingEnabled_shouldReturnTheSettingStateAndAlwaysEnabled() {
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
when(mAudioManager.isRampingRingerEnabled()).thenReturn(true, false);
mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isTrue();
assertThat(mPreference.isChecked()).isTrue();
mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isTrue();
assertThat(mPreference.isChecked()).isFalse();
}
@Test
public void setChecked_withRingDisabled_ignoresUpdates() {
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
mPreference.setChecked(true);
mPreference.setChecked(false);
verify(mAudioManager, never()).setRampingRingerEnabled(anyBoolean());
}
@Test
public void setChecked_withRingEnabled_updatesSetting() {
updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
mPreference.setChecked(true);
verify(mAudioManager).setRampingRingerEnabled(true);
mPreference.setChecked(false);
verify(mAudioManager).setRampingRingerEnabled(false);
}
private void updateSetting(String key, int value) {
Settings.System.putInt(mContext.getContentResolver(), key, value);
}
private void showPreference() {
mController.displayPreference(mScreen);
}
}

View File

@@ -1,120 +0,0 @@
/*
* Copyright (C) 2020 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.settings.sound;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import com.android.settings.R;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
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;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowDeviceConfig.class})
public class VibrateForCallsPreferenceControllerTest {
private static final int OFF = 0;
private static final int ON = 1;
private Context mContext;
private ContentResolver mContentResolver;
@Mock
private TelephonyManager mTelephonyManager;
private VibrateForCallsPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mContentResolver = mContext.getContentResolver();
when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
mController = new VibrateForCallsPreferenceController(
mContext, VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED);
}
@Test
public void getAvailabilityStatus_notVoiceCapable_returnUnsupportedOnDevice() {
when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED, "false", false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_rampingRingerEnabled_returnUnsupportedOnDevice() {
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED, "true", false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void getAvailabilityStatus_voiceCapableAndRampingRingerDisabled_returnAvailable() {
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED, "false", false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getSummary_applyRampingRinger_rampingRingerSummary() {
Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, ON);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.vibrate_when_ringing_option_ramping_ringer));
}
@Test
public void getSummary_enableVibrateWhenRinging_alwaysVibrateSummary() {
Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, ON);
Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.vibrate_when_ringing_option_always_vibrate));
}
@Test
public void getSummary_notApplyRampingRingerDisableVibrateWhenRinging_neverVibrateSummary() {
Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.vibrate_when_ringing_option_never_vibrate));
}
}

View File

@@ -1,108 +0,0 @@
/*
* Copyright (C) 2020 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.settings.sound;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class VibrateForCallsPreferenceFragmentTest {
private static final int OFF = 0;
private static final int ON = 1;
private Context mContext;
private ContentResolver mContentResolver;
private VibrateForCallsPreferenceFragment mFragment;
@Before
public void setUp() {
mContext = spy(RuntimeEnvironment.application);
mContentResolver = mContext.getContentResolver();
mFragment = spy(new VibrateForCallsPreferenceFragment());
doReturn(mContext).when(mFragment).getContext();
mFragment.onAttach(mContext);
}
@Test
public void getDefaultKey_applyRampingRinger_keyRampingRinger() {
Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, ON);
assertThat(mFragment.getDefaultKey()).isEqualTo(
VibrateForCallsPreferenceFragment.KEY_RAMPING_RINGER);
}
@Test
public void getDefaultKey_enableVibrateWhenRinging_keyAlwaysVibrate() {
Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, ON);
Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
assertThat(mFragment.getDefaultKey()).isEqualTo(
VibrateForCallsPreferenceFragment.KEY_ALWAYS_VIBRATE);
}
@Test
public void getDefaultKey_notApplyRampingRingerDisableVibrateWhenRinging_keyNeverVibrate() {
Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
assertThat(mFragment.getDefaultKey()).isEqualTo(
VibrateForCallsPreferenceFragment.KEY_NEVER_VIBRATE);
}
@Test
public void setDefaultKey_keyRampingRinger_applyRampingRingerDisableVibrateWhenRinging() {
mFragment.setDefaultKey(VibrateForCallsPreferenceFragment.KEY_RAMPING_RINGER);
assertThat(Settings.System.getInt(
mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF)).isEqualTo(ON);
assertThat(Settings.System.getInt(
mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF)).isEqualTo(OFF);
}
@Test
public void setDefaultKey_keyAlwaysVibrate_notApplyRampingRingerEnableVibrateWhenRinging() {
mFragment.setDefaultKey(VibrateForCallsPreferenceFragment.KEY_ALWAYS_VIBRATE);
assertThat(Settings.System.getInt(
mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF)).isEqualTo(OFF);
assertThat(Settings.System.getInt(
mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF)).isEqualTo(ON);
}
@Test
public void setDefaultKey_keyNeverVibrate_notApplyRampingRingerDisableVibrateWhenRinging() {
mFragment.setDefaultKey(VibrateForCallsPreferenceFragment.KEY_NEVER_VIBRATE);
assertThat(Settings.System.getInt(
mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF)).isEqualTo(OFF);
assertThat(Settings.System.getInt(
mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF)).isEqualTo(OFF);
}
}