Apply VIBRATE_ON settings in vibrator service

Apply main switch toggle from "Vibration & haptics" settings screeen to
disable all vibrations except for accessibility usage and the ones with
bypass flag (e.g. broadcasted alers from CellBroadcastAlertAudio.

Fix: 30028435
Test: VibrationSettingsTest
Change-Id: Ia8a0e5e952ce2e1055b6c63fc5801546b635d39a
This commit is contained in:
Lais Andrade
2022-01-15 13:31:54 +00:00
parent a01a1f6993
commit d5a21c1f94
3 changed files with 63 additions and 8 deletions

View File

@@ -97,7 +97,7 @@ message VibrationProto {
optional int32 status = 6;
}
// Next id: 24
// Next id: 25
message VibratorManagerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
repeated int32 vibrator_ids = 1;
@@ -106,6 +106,7 @@ message VibratorManagerServiceDumpProto {
optional VibrationProto current_external_vibration = 4;
optional bool vibrator_under_external_control = 5;
optional bool low_power_mode = 6;
optional bool vibrate_on = 24;
optional int32 alarm_intensity = 18;
optional int32 alarm_default_intensity = 19;
optional int32 haptic_feedback_intensity = 7;

View File

@@ -97,6 +97,15 @@ final class VibrationSettings {
USAGE_ALARM,
USAGE_COMMUNICATION_REQUEST));
/**
* Usage allowed for vibrations when {@link Settings.System#VIBRATE_ON} is disabled.
*
* <p>The only allowed usage is accessibility, which is applied when the user enables talkback.
* Other usages that must ignore this setting should use
* {@link VibrationAttributes#FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF}.
*/
private static final int VIBRATE_ON_DISABLED_USAGE_ALLOWED = USAGE_ACCESSIBILITY;
/** Listener for changes on vibration settings. */
interface OnVibratorSettingsChanged {
/** Callback triggered when any of the vibrator settings change. */
@@ -127,6 +136,8 @@ final class VibrationSettings {
private SparseIntArray mCurrentVibrationIntensities = new SparseIntArray();
@GuardedBy("mLock")
private boolean mBatterySaverMode;
@GuardedBy("mLock")
private boolean mVibrateOn;
VibrationSettings(Context context, Handler handler) {
this(context, handler, new VibrationConfig(context.getResources()));
@@ -199,6 +210,7 @@ final class VibrationSettings {
// Listen to all settings that might affect the result of Vibrator.getVibrationIntensity.
registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_ON));
registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING));
registerSettingsObserver(Settings.System.getUriFor(Settings.System.APPLY_RAMPING_RINGER));
registerSettingsObserver(Settings.System.getUriFor(
@@ -314,11 +326,14 @@ final class VibrationSettings {
return Vibration.Status.IGNORED_FOR_POWER;
}
int intensity = getCurrentIntensity(usage);
if ((intensity == Vibrator.VIBRATION_INTENSITY_OFF)
&& !attrs.isFlagSet(
VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)) {
return Vibration.Status.IGNORED_FOR_SETTINGS;
if (!attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)) {
if (!mVibrateOn && (VIBRATE_ON_DISABLED_USAGE_ALLOWED != usage)) {
return Vibration.Status.IGNORED_FOR_SETTINGS;
}
if (getCurrentIntensity(usage) == Vibrator.VIBRATION_INTENSITY_OFF) {
return Vibration.Status.IGNORED_FOR_SETTINGS;
}
}
if (!shouldVibrateForRingerModeLocked(usage)) {
@@ -357,6 +372,7 @@ final class VibrationSettings {
void updateSettings() {
synchronized (mLock) {
mVibrateInputDevices = loadSystemSetting(Settings.System.VIBRATE_INPUT_DEVICES, 0) > 0;
mVibrateOn = loadSystemSetting(Settings.System.VIBRATE_ON, 1) > 0;
int alarmIntensity = toIntensity(
loadSystemSetting(Settings.System.ALARM_VIBRATION_INTENSITY, -1),
@@ -437,8 +453,9 @@ final class VibrationSettings {
+ "mVibratorConfig=" + mVibrationConfig
+ ", mVibrateInputDevices=" + mVibrateInputDevices
+ ", mBatterySaverMode=" + mBatterySaverMode
+ ", mProcStatesCache=" + mUidObserver.mProcStatesCache
+ ", mVibrateOn=" + mVibrateOn
+ ", mVibrationIntensities=" + vibrationIntensitiesString
+ ", mProcStatesCache=" + mUidObserver.mProcStatesCache
+ '}';
}
}
@@ -446,6 +463,8 @@ final class VibrationSettings {
/** Write current settings into given {@link ProtoOutputStream}. */
public void dumpProto(ProtoOutputStream proto) {
synchronized (mLock) {
proto.write(VibratorManagerServiceDumpProto.VIBRATE_ON, mVibrateOn);
proto.write(VibratorManagerServiceDumpProto.LOW_POWER_MODE, mBatterySaverMode);
proto.write(VibratorManagerServiceDumpProto.ALARM_INTENSITY,
getCurrentIntensity(USAGE_ALARM));
proto.write(VibratorManagerServiceDumpProto.ALARM_DEFAULT_INTENSITY,

View File

@@ -319,6 +319,34 @@ public class VibrationSettingsTest {
}
}
@Test
public void shouldIgnoreVibration_vibrateOnDisabled_ignoresUsagesNotAccessibility() {
setUserSetting(Settings.System.VIBRATE_ON, 0);
for (int usage : ALL_USAGES) {
if (usage == USAGE_ACCESSIBILITY) {
assertVibrationNotIgnoredForUsage(usage);
} else {
assertVibrationIgnoredForUsage(usage, Vibration.Status.IGNORED_FOR_SETTINGS);
}
assertVibrationNotIgnoredForUsageAndFlags(usage,
VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF);
}
}
@Test
public void shouldIgnoreVibration_vibrateOnEnabledOrUnset_allowsAnyUsage() {
deleteUserSetting(Settings.System.VIBRATE_ON);
for (int usage : ALL_USAGES) {
assertVibrationNotIgnoredForUsage(usage);
}
setUserSetting(Settings.System.VIBRATE_ON, 1);
for (int usage : ALL_USAGES) {
assertVibrationNotIgnoredForUsage(usage);
}
}
@Test
public void shouldIgnoreVibration_withRingSettingsOff_disableRingtoneVibrations() {
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
@@ -560,10 +588,17 @@ public class VibrationSettingsTest {
when(mVibrationConfigMock.getDefaultVibrationIntensity(eq(usage))).thenReturn(intensity);
}
private void deleteUserSetting(String settingName) {
Settings.System.putStringForUser(
mContextSpy.getContentResolver(), settingName, null, UserHandle.USER_CURRENT);
// FakeSettingsProvider doesn't support testing triggering ContentObserver yet.
mVibrationSettings.updateSettings();
}
private void setUserSetting(String settingName, int value) {
Settings.System.putIntForUser(
mContextSpy.getContentResolver(), settingName, value, UserHandle.USER_CURRENT);
// FakeSettingsProvider don't support testing triggering ContentObserver yet.
// FakeSettingsProvider doesn't support testing triggering ContentObserver yet.
mVibrationSettings.updateSettings();
}