Merge "Enable hardware feedback in background and disable touch feedback in silent mode"
This commit is contained in:
@@ -136,7 +136,7 @@ public final class VibrationAttributes implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef(prefix = { "FLAG_" }, value = {
|
||||
@IntDef(prefix = { "FLAG_" }, flag = true, value = {
|
||||
FLAG_BYPASS_INTERRUPTION_POLICY,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@@ -162,7 +162,8 @@ public final class VibrationAttributes implements Parcelable {
|
||||
private final int mFlags;
|
||||
private final int mOriginalAudioUsage;
|
||||
|
||||
private VibrationAttributes(int usage, int audioUsage, int flags) {
|
||||
private VibrationAttributes(@Usage int usage, @AudioAttributes.AttributeUsage int audioUsage,
|
||||
@Flag int flags) {
|
||||
mUsage = usage;
|
||||
mOriginalAudioUsage = audioUsage;
|
||||
mFlags = flags & FLAG_ALL_SUPPORTED;
|
||||
@@ -172,6 +173,7 @@ public final class VibrationAttributes implements Parcelable {
|
||||
* Return the vibration usage class.
|
||||
* @return USAGE_CLASS_ALARM, USAGE_CLASS_FEEDBACK or USAGE_CLASS_UNKNOWN
|
||||
*/
|
||||
@UsageClass
|
||||
public int getUsageClass() {
|
||||
return mUsage & USAGE_CLASS_MASK;
|
||||
}
|
||||
@@ -180,6 +182,7 @@ public final class VibrationAttributes implements Parcelable {
|
||||
* Return the vibration usage.
|
||||
* @return one of the values that can be set in {@link Builder#setUsage(int)}
|
||||
*/
|
||||
@Usage
|
||||
public int getUsage() {
|
||||
return mUsage;
|
||||
}
|
||||
@@ -188,6 +191,7 @@ public final class VibrationAttributes implements Parcelable {
|
||||
* Return the flags.
|
||||
* @return a combined mask of all flags
|
||||
*/
|
||||
@Flag
|
||||
public int getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
@@ -196,7 +200,7 @@ public final class VibrationAttributes implements Parcelable {
|
||||
* Check whether a flag is set
|
||||
* @return true if a flag is set and false otherwise
|
||||
*/
|
||||
public boolean isFlagSet(int flag) {
|
||||
public boolean isFlagSet(@Flag int flag) {
|
||||
return (mFlags & flag) > 0;
|
||||
}
|
||||
|
||||
@@ -206,6 +210,7 @@ public final class VibrationAttributes implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@AudioAttributes.AttributeUsage
|
||||
public int getAudioUsage() {
|
||||
if (mOriginalAudioUsage != AudioAttributes.USAGE_UNKNOWN) {
|
||||
// Return same audio usage set in the Builder.
|
||||
@@ -292,7 +297,7 @@ public final class VibrationAttributes implements Parcelable {
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static String usageToString(int usage) {
|
||||
public static String usageToString(@Usage int usage) {
|
||||
switch (usage) {
|
||||
case USAGE_UNKNOWN:
|
||||
return "UNKNOWN";
|
||||
@@ -419,7 +424,7 @@ public final class VibrationAttributes implements Parcelable {
|
||||
* {@link VibrationAttributes#USAGE_MEDIA}.
|
||||
* @return the same Builder instance.
|
||||
*/
|
||||
public @NonNull Builder setUsage(int usage) {
|
||||
public @NonNull Builder setUsage(@Usage int usage) {
|
||||
mOriginalAudioUsage = AudioAttributes.USAGE_UNKNOWN;
|
||||
mUsage = usage;
|
||||
return this;
|
||||
@@ -431,7 +436,7 @@ public final class VibrationAttributes implements Parcelable {
|
||||
* @param mask Bit range that should be changed.
|
||||
* @return the same Builder instance.
|
||||
*/
|
||||
public @NonNull Builder setFlags(int flags, int mask) {
|
||||
public @NonNull Builder setFlags(@Flag int flags, int mask) {
|
||||
mask &= FLAG_ALL_SUPPORTED;
|
||||
mFlags = (mFlags & ~mask) | (flags & mask);
|
||||
return this;
|
||||
|
||||
@@ -53,13 +53,13 @@ final class Vibration {
|
||||
IGNORED,
|
||||
IGNORED_APP_OPS,
|
||||
IGNORED_BACKGROUND,
|
||||
IGNORED_RINGTONE,
|
||||
IGNORED_UNKNOWN_VIBRATION,
|
||||
IGNORED_UNSUPPORTED,
|
||||
IGNORED_FOR_ALARM,
|
||||
IGNORED_FOR_EXTERNAL,
|
||||
IGNORED_FOR_ONGOING,
|
||||
IGNORED_FOR_POWER,
|
||||
IGNORED_FOR_RINGER_MODE,
|
||||
IGNORED_FOR_SETTINGS,
|
||||
IGNORED_SUPERSEDED,
|
||||
}
|
||||
|
||||
@@ -53,12 +53,44 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** Controls all the system settings related to vibration. */
|
||||
final class VibrationSettings {
|
||||
private static final String TAG = "VibrationSettings";
|
||||
|
||||
/**
|
||||
* Set of usages allowed for vibrations from background processes.
|
||||
*
|
||||
* <p>Some examples are notification, ringtone or alarm vibrations, that are allowed to vibrate
|
||||
* unexpectedly as they are meant to grab the user's attention. Hardware feedback and physical
|
||||
* emulation are also supported, as the trigger process might still be in the background when
|
||||
* the user interaction wakes the device.
|
||||
*/
|
||||
private static final Set<Integer> BACKGROUND_PROCESS_USAGE_ALLOWLIST = new HashSet<>(
|
||||
Arrays.asList(
|
||||
USAGE_RINGTONE,
|
||||
USAGE_ALARM,
|
||||
USAGE_NOTIFICATION,
|
||||
USAGE_COMMUNICATION_REQUEST,
|
||||
USAGE_HARDWARE_FEEDBACK,
|
||||
USAGE_PHYSICAL_EMULATION));
|
||||
|
||||
/**
|
||||
* Set of usages allowed for vibrations in battery saver mode (low power).
|
||||
*
|
||||
* <p>Some examples are ringtone or alarm vibrations, that have high priority and should vibrate
|
||||
* even when the device is saving battery.
|
||||
*/
|
||||
private static final Set<Integer> BATTERY_SAVER_USAGE_ALLOWLIST = new HashSet<>(
|
||||
Arrays.asList(
|
||||
USAGE_RINGTONE,
|
||||
USAGE_ALARM,
|
||||
USAGE_COMMUNICATION_REQUEST));
|
||||
|
||||
/** Listener for changes on vibration settings. */
|
||||
interface OnVibratorSettingsChanged {
|
||||
/** Callback triggered when any of the vibrator settings change. */
|
||||
@@ -94,8 +126,6 @@ final class VibrationSettings {
|
||||
@GuardedBy("mLock")
|
||||
private boolean mApplyRampingRinger;
|
||||
@GuardedBy("mLock")
|
||||
private int mZenMode;
|
||||
@GuardedBy("mLock")
|
||||
private int mHapticFeedbackIntensity;
|
||||
@GuardedBy("mLock")
|
||||
private int mHardwareFeedbackIntensity;
|
||||
@@ -104,7 +134,7 @@ final class VibrationSettings {
|
||||
@GuardedBy("mLock")
|
||||
private int mRingIntensity;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mLowPowerMode;
|
||||
private boolean mBatterySaverMode;
|
||||
|
||||
VibrationSettings(Context context, Handler handler) {
|
||||
this(context, handler,
|
||||
@@ -172,8 +202,8 @@ final class VibrationSettings {
|
||||
public void onLowPowerModeChanged(PowerSaveState result) {
|
||||
boolean shouldNotifyListeners;
|
||||
synchronized (mLock) {
|
||||
shouldNotifyListeners = result.batterySaverEnabled != mLowPowerMode;
|
||||
mLowPowerMode = result.batterySaverEnabled;
|
||||
shouldNotifyListeners = result.batterySaverEnabled != mBatterySaverMode;
|
||||
mBatterySaverMode = result.batterySaverEnabled;
|
||||
}
|
||||
if (shouldNotifyListeners) {
|
||||
notifyListeners();
|
||||
@@ -187,7 +217,6 @@ final class VibrationSettings {
|
||||
registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
|
||||
registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING));
|
||||
registerSettingsObserver(Settings.System.getUriFor(Settings.System.APPLY_RAMPING_RINGER));
|
||||
registerSettingsObserver(Settings.Global.getUriFor(Settings.Global.ZEN_MODE));
|
||||
registerSettingsObserver(
|
||||
Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_INTENSITY));
|
||||
registerSettingsObserver(
|
||||
@@ -299,71 +328,78 @@ final class VibrationSettings {
|
||||
return mFallbackEffects.get(effectId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the device should vibrate for current ringer mode.
|
||||
*
|
||||
* <p>This checks the current {@link AudioManager#getRingerModeInternal()} against user settings
|
||||
* for ringtone usage only. All other usages are allowed independently of ringer mode.
|
||||
*/
|
||||
public boolean shouldVibrateForRingerMode(int usageHint) {
|
||||
if (usageHint != USAGE_RINGTONE) {
|
||||
return true;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
if (mAudioManager == null) {
|
||||
return false;
|
||||
}
|
||||
int ringerMode = mAudioManager.getRingerModeInternal();
|
||||
if (mVibrateWhenRinging) {
|
||||
return ringerMode != AudioManager.RINGER_MODE_SILENT;
|
||||
} else if (mApplyRampingRinger) {
|
||||
return ringerMode != AudioManager.RINGER_MODE_SILENT;
|
||||
} else {
|
||||
return ringerMode == AudioManager.RINGER_MODE_VIBRATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this vibration is allowed for given {@code uid}.
|
||||
*
|
||||
* <p>This checks if the user is aware of this foreground process, or if the vibration usage is
|
||||
* allowed to play in the background (i.e. it's a notification, ringtone or alarm vibration).
|
||||
*/
|
||||
public boolean shouldVibrateForUid(int uid, int usageHint) {
|
||||
return mUidObserver.isUidForeground(uid) || isClassAlarm(usageHint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this vibration is allowed for current power mode state.
|
||||
*
|
||||
* <p>This checks if the device is in battery saver mode, in which case only alarm, ringtone and
|
||||
* {@link VibrationAttributes#USAGE_COMMUNICATION_REQUEST} usages are allowed to vibrate.
|
||||
*/
|
||||
public boolean shouldVibrateForPowerMode(int usageHint) {
|
||||
synchronized (mLock) {
|
||||
return !mLowPowerMode || usageHint == USAGE_RINGTONE || usageHint == USAGE_ALARM
|
||||
|| usageHint == USAGE_COMMUNICATION_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return {@code true} if input devices should vibrate instead of this device. */
|
||||
public boolean shouldVibrateInputDevices() {
|
||||
return mVibrateInputDevices;
|
||||
}
|
||||
|
||||
/** Return {@code true} if setting for {@link Settings.Global#ZEN_MODE} is not OFF. */
|
||||
public boolean isInZenMode() {
|
||||
return mZenMode != Settings.Global.ZEN_MODE_OFF;
|
||||
/**
|
||||
* Check if given vibration should be ignored by the service.
|
||||
*
|
||||
* @return One of Vibration.Status.IGNORED_* values if the vibration should be ignored,
|
||||
* null otherwise.
|
||||
*/
|
||||
@Nullable
|
||||
public Vibration.Status shouldIgnoreVibration(int uid, VibrationAttributes attrs) {
|
||||
final int usage = attrs.getUsage();
|
||||
synchronized (mLock) {
|
||||
if (!mUidObserver.isUidForeground(uid)
|
||||
&& !BACKGROUND_PROCESS_USAGE_ALLOWLIST.contains(usage)) {
|
||||
return Vibration.Status.IGNORED_BACKGROUND;
|
||||
}
|
||||
|
||||
if (mBatterySaverMode && !BATTERY_SAVER_USAGE_ALLOWLIST.contains(usage)) {
|
||||
return Vibration.Status.IGNORED_FOR_POWER;
|
||||
}
|
||||
|
||||
int intensity = getCurrentIntensity(usage);
|
||||
if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) {
|
||||
return Vibration.Status.IGNORED_FOR_SETTINGS;
|
||||
}
|
||||
|
||||
if (!shouldVibrateForRingerModeLocked(usage)) {
|
||||
return Vibration.Status.IGNORED_FOR_RINGER_MODE;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isClassAlarm(int usageHint) {
|
||||
return (usageHint & VibrationAttributes.USAGE_CLASS_MASK)
|
||||
== VibrationAttributes.USAGE_CLASS_ALARM;
|
||||
/**
|
||||
* Return {@code true} if the device should vibrate for current ringer mode.
|
||||
*
|
||||
* <p>This checks the current {@link AudioManager#getRingerModeInternal()} against user settings
|
||||
* for touch and ringtone usages only. All other usages are allowed by this method.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private boolean shouldVibrateForRingerModeLocked(int usageHint) {
|
||||
// If audio manager was not loaded yet then assume most restrictive mode.
|
||||
int ringerMode = (mAudioManager == null)
|
||||
? AudioManager.RINGER_MODE_SILENT
|
||||
: mAudioManager.getRingerModeInternal();
|
||||
|
||||
switch (usageHint) {
|
||||
case USAGE_TOUCH:
|
||||
// Touch feedback disabled when phone is on silent mode.
|
||||
return ringerMode != AudioManager.RINGER_MODE_SILENT;
|
||||
case USAGE_RINGTONE:
|
||||
switch (ringerMode) {
|
||||
case AudioManager.RINGER_MODE_SILENT:
|
||||
return false;
|
||||
case AudioManager.RINGER_MODE_VIBRATE:
|
||||
return true;
|
||||
default:
|
||||
// Ringtone vibrations also depend on 2 other settings:
|
||||
return mVibrateWhenRinging || mApplyRampingRinger;
|
||||
}
|
||||
default:
|
||||
// All other usages ignore ringer mode settings.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates all vibration settings and triggers registered listeners. */
|
||||
public void updateSettings() {
|
||||
@VisibleForTesting
|
||||
void updateSettings() {
|
||||
synchronized (mLock) {
|
||||
mVibrateWhenRinging = getSystemSetting(Settings.System.VIBRATE_WHEN_RINGING, 0) != 0;
|
||||
mApplyRampingRinger = getSystemSetting(Settings.System.APPLY_RAMPING_RINGER, 0) != 0;
|
||||
@@ -378,7 +414,6 @@ final class VibrationSettings {
|
||||
mRingIntensity = getSystemSetting(Settings.System.RING_VIBRATION_INTENSITY,
|
||||
getDefaultIntensity(USAGE_RINGTONE));
|
||||
mVibrateInputDevices = getSystemSetting(Settings.System.VIBRATE_INPUT_DEVICES, 0) > 0;
|
||||
mZenMode = getGlobalSetting(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
@@ -399,31 +434,33 @@ final class VibrationSettings {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VibrationSettings{"
|
||||
+ "mVibrateInputDevices=" + mVibrateInputDevices
|
||||
+ ", mVibrateWhenRinging=" + mVibrateWhenRinging
|
||||
+ ", mApplyRampingRinger=" + mApplyRampingRinger
|
||||
+ ", mLowPowerMode=" + mLowPowerMode
|
||||
+ ", mZenMode=" + Settings.Global.zenModeToString(mZenMode)
|
||||
+ ", mProcStatesCache=" + mUidObserver.mProcStatesCache
|
||||
+ ", mHapticChannelMaxVibrationAmplitude=" + getHapticChannelMaxVibrationAmplitude()
|
||||
+ ", mRampStepDuration=" + mRampStepDuration
|
||||
+ ", mRampDownDuration=" + mRampDownDuration
|
||||
+ ", mHardwareHapticFeedbackIntensity="
|
||||
+ intensityToString(getCurrentIntensity(USAGE_HARDWARE_FEEDBACK))
|
||||
+ ", mHapticFeedbackIntensity="
|
||||
+ intensityToString(getCurrentIntensity(USAGE_TOUCH))
|
||||
+ ", mHapticFeedbackDefaultIntensity="
|
||||
+ intensityToString(getDefaultIntensity(USAGE_TOUCH))
|
||||
+ ", mNotificationIntensity="
|
||||
+ intensityToString(getCurrentIntensity(USAGE_NOTIFICATION))
|
||||
+ ", mNotificationDefaultIntensity="
|
||||
+ intensityToString(getDefaultIntensity(USAGE_NOTIFICATION))
|
||||
+ ", mRingIntensity="
|
||||
+ intensityToString(getCurrentIntensity(USAGE_RINGTONE))
|
||||
+ ", mRingDefaultIntensity="
|
||||
+ intensityToString(getDefaultIntensity(USAGE_RINGTONE))
|
||||
+ '}';
|
||||
synchronized (mLock) {
|
||||
return "VibrationSettings{"
|
||||
+ "mVibrateInputDevices=" + mVibrateInputDevices
|
||||
+ ", mVibrateWhenRinging=" + mVibrateWhenRinging
|
||||
+ ", mApplyRampingRinger=" + mApplyRampingRinger
|
||||
+ ", mBatterySaverMode=" + mBatterySaverMode
|
||||
+ ", mProcStatesCache=" + mUidObserver.mProcStatesCache
|
||||
+ ", mHapticChannelMaxVibrationAmplitude="
|
||||
+ getHapticChannelMaxVibrationAmplitude()
|
||||
+ ", mRampStepDuration=" + mRampStepDuration
|
||||
+ ", mRampDownDuration=" + mRampDownDuration
|
||||
+ ", mHardwareHapticFeedbackIntensity="
|
||||
+ intensityToString(getCurrentIntensity(USAGE_HARDWARE_FEEDBACK))
|
||||
+ ", mHapticFeedbackIntensity="
|
||||
+ intensityToString(getCurrentIntensity(USAGE_TOUCH))
|
||||
+ ", mHapticFeedbackDefaultIntensity="
|
||||
+ intensityToString(getDefaultIntensity(USAGE_TOUCH))
|
||||
+ ", mNotificationIntensity="
|
||||
+ intensityToString(getCurrentIntensity(USAGE_NOTIFICATION))
|
||||
+ ", mNotificationDefaultIntensity="
|
||||
+ intensityToString(getDefaultIntensity(USAGE_NOTIFICATION))
|
||||
+ ", mRingIntensity="
|
||||
+ intensityToString(getCurrentIntensity(USAGE_RINGTONE))
|
||||
+ ", mRingDefaultIntensity="
|
||||
+ intensityToString(getDefaultIntensity(USAGE_RINGTONE))
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
/** Write current settings into given {@link ProtoOutputStream}. */
|
||||
@@ -480,10 +517,6 @@ final class VibrationSettings {
|
||||
settingName, defaultValue, UserHandle.USER_CURRENT);
|
||||
}
|
||||
|
||||
private int getGlobalSetting(String settingName, int defaultValue) {
|
||||
return Settings.Global.getInt(mContext.getContentResolver(), settingName, defaultValue);
|
||||
}
|
||||
|
||||
private void registerSettingsObserver(Uri settingUri) {
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
settingUri, /* notifyForDescendants= */ true, mSettingObserver,
|
||||
|
||||
@@ -46,7 +46,6 @@ import android.os.ShellCommand;
|
||||
import android.os.Trace;
|
||||
import android.os.VibrationAttributes;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.os.VibratorInfo;
|
||||
import android.os.vibrator.PrebakedSegment;
|
||||
import android.os.vibrator.VibrationEffectSegment;
|
||||
@@ -394,13 +393,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Starting vibrate for vibration " + vib.id);
|
||||
}
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(vib);
|
||||
if (ignoreStatus != null) {
|
||||
endVibrationLocked(vib, ignoreStatus);
|
||||
return vib;
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
||||
vib.uid, vib.opPkg, vib.attrs);
|
||||
|
||||
if (ignoreStatus == null) {
|
||||
ignoreStatus = shouldIgnoreVibrationForOngoingLocked(vib);
|
||||
}
|
||||
|
||||
ignoreStatus = shouldIgnoreVibrationForCurrentLocked(vib);
|
||||
if (ignoreStatus != null) {
|
||||
endVibrationLocked(vib, ignoreStatus);
|
||||
return vib;
|
||||
@@ -453,8 +452,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
&& shouldCancelVibration(
|
||||
mCurrentExternalVibration.externalVibration.getVibrationAttributes(),
|
||||
usageFilter)) {
|
||||
mCurrentExternalVibration.end(Vibration.Status.CANCELLED);
|
||||
mVibratorManagerRecords.record(mCurrentExternalVibration);
|
||||
endVibrationLocked(mCurrentExternalVibration, Vibration.Status.CANCELLED);
|
||||
mCurrentExternalVibration.externalVibration.mute();
|
||||
mCurrentExternalVibration = null;
|
||||
setExternalControl(false);
|
||||
@@ -482,15 +480,76 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
try {
|
||||
if (isDumpProto) {
|
||||
mVibratorManagerRecords.dumpProto(fd);
|
||||
dumpProto(fd);
|
||||
} else {
|
||||
mVibratorManagerRecords.dumpText(pw);
|
||||
dumpText(pw);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpText(PrintWriter pw) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Dumping vibrator manager service to text...");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
pw.println("Vibrator Manager Service:");
|
||||
pw.println(" mVibrationSettings:");
|
||||
pw.println(" " + mVibrationSettings);
|
||||
pw.println();
|
||||
pw.println(" mVibratorControllers:");
|
||||
for (int i = 0; i < mVibrators.size(); i++) {
|
||||
pw.println(" " + mVibrators.valueAt(i));
|
||||
}
|
||||
pw.println();
|
||||
pw.println(" mCurrentVibration:");
|
||||
pw.println(" " + (mCurrentVibration == null
|
||||
? null : mCurrentVibration.getVibration().getDebugInfo()));
|
||||
pw.println();
|
||||
pw.println(" mNextVibration:");
|
||||
pw.println(" " + (mNextVibration == null
|
||||
? null : mNextVibration.getVibration().getDebugInfo()));
|
||||
pw.println();
|
||||
pw.println(" mCurrentExternalVibration:");
|
||||
pw.println(" " + (mCurrentExternalVibration == null
|
||||
? null : mCurrentExternalVibration.getDebugInfo()));
|
||||
pw.println();
|
||||
}
|
||||
mVibratorManagerRecords.dumpText(pw);
|
||||
}
|
||||
|
||||
synchronized void dumpProto(FileDescriptor fd) {
|
||||
final ProtoOutputStream proto = new ProtoOutputStream(fd);
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Dumping vibrator manager service to proto...");
|
||||
}
|
||||
synchronized (mLock) {
|
||||
mVibrationSettings.dumpProto(proto);
|
||||
if (mCurrentVibration != null) {
|
||||
mCurrentVibration.getVibration().getDebugInfo().dumpProto(proto,
|
||||
VibratorManagerServiceDumpProto.CURRENT_VIBRATION);
|
||||
}
|
||||
if (mCurrentExternalVibration != null) {
|
||||
mCurrentExternalVibration.getDebugInfo().dumpProto(proto,
|
||||
VibratorManagerServiceDumpProto.CURRENT_EXTERNAL_VIBRATION);
|
||||
}
|
||||
|
||||
boolean isVibrating = false;
|
||||
boolean isUnderExternalControl = false;
|
||||
for (int i = 0; i < mVibrators.size(); i++) {
|
||||
proto.write(VibratorManagerServiceDumpProto.VIBRATOR_IDS, mVibrators.keyAt(i));
|
||||
isVibrating |= mVibrators.valueAt(i).isVibrating();
|
||||
isUnderExternalControl |= mVibrators.valueAt(i).isUnderExternalControl();
|
||||
}
|
||||
proto.write(VibratorManagerServiceDumpProto.IS_VIBRATING, isVibrating);
|
||||
proto.write(VibratorManagerServiceDumpProto.VIBRATOR_UNDER_EXTERNAL_CONTROL,
|
||||
isUnderExternalControl);
|
||||
}
|
||||
mVibratorManagerRecords.dumpProto(proto);
|
||||
proto.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
|
||||
String[] args, ShellCallback cb, ResultReceiver resultReceiver) {
|
||||
@@ -515,8 +574,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputDevicesChanged || !mVibrationSettings.shouldVibrateForPowerMode(
|
||||
mCurrentVibration.getVibration().attrs.getUsage())) {
|
||||
Vibration vib = mCurrentVibration.getVibration();
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
||||
vib.uid, vib.opPkg, vib.attrs);
|
||||
|
||||
if (inputDevicesChanged || (ignoreStatus != null)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Canceling vibration because settings changed: "
|
||||
+ (inputDevicesChanged ? "input devices changed" : ignoreStatus));
|
||||
}
|
||||
mCurrentVibration.cancel();
|
||||
}
|
||||
}
|
||||
@@ -602,15 +668,56 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
@GuardedBy("mLock")
|
||||
private void endVibrationLocked(Vibration vib, Vibration.Status status) {
|
||||
vib.end(status);
|
||||
logVibrationStatus(vib.uid, vib.attrs, status);
|
||||
mVibratorManagerRecords.record(vib);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void endVibrationLocked(ExternalVibrationHolder vib, Vibration.Status status) {
|
||||
vib.end(status);
|
||||
logVibrationStatus(vib.externalVibration.getUid(),
|
||||
vib.externalVibration.getVibrationAttributes(), status);
|
||||
mVibratorManagerRecords.record(vib);
|
||||
}
|
||||
|
||||
private void logVibrationStatus(int uid, VibrationAttributes attrs, Vibration.Status status) {
|
||||
switch (status) {
|
||||
case IGNORED_BACKGROUND:
|
||||
Slog.e(TAG, "Ignoring incoming vibration as process with"
|
||||
+ " uid= " + uid + " is background," + " attrs= " + attrs);
|
||||
break;
|
||||
case IGNORED_ERROR_APP_OPS:
|
||||
Slog.w(TAG, "Would be an error: vibrate from uid " + uid);
|
||||
break;
|
||||
case IGNORED_FOR_ALARM:
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Ignoring incoming vibration in favor of alarm vibration");
|
||||
}
|
||||
break;
|
||||
case IGNORED_FOR_EXTERNAL:
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Ignoring incoming vibration for current external vibration");
|
||||
}
|
||||
break;
|
||||
case IGNORED_FOR_ONGOING:
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Ignoring incoming vibration in favor of repeating vibration");
|
||||
}
|
||||
break;
|
||||
case IGNORED_FOR_RINGER_MODE:
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Ignoring incoming vibration because of ringer mode, attrs="
|
||||
+ attrs);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Vibration for uid=" + uid + " and with attrs=" + attrs
|
||||
+ " ended with status " + status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void reportFinishedVibrationLocked(Vibration.Status status) {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked");
|
||||
@@ -651,32 +758,36 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given vibration should be ignored in favour of one of the vibrations currently
|
||||
* running on the same vibrators.
|
||||
* Check if given vibration should be ignored by this service because of the ongoing vibration.
|
||||
*
|
||||
* @return One of Vibration.Status.IGNORED_* values if the vibration should be ignored.
|
||||
* @return One of Vibration.Status.IGNORED_* values if the vibration should be ignored, null
|
||||
* otherwise.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private Vibration.Status shouldIgnoreVibrationForCurrentLocked(Vibration vibration) {
|
||||
if (vibration.isRepeating()) {
|
||||
// Repeating vibrations always take precedence.
|
||||
private Vibration.Status shouldIgnoreVibrationForOngoingLocked(Vibration vib) {
|
||||
if (mCurrentExternalVibration != null) {
|
||||
// If something has external control of the vibrator, assume that it's more important.
|
||||
return Vibration.Status.IGNORED_FOR_EXTERNAL;
|
||||
}
|
||||
|
||||
if (mCurrentVibration == null || vib.isRepeating()) {
|
||||
// Incoming repeating vibrations always take precedence over ongoing vibrations.
|
||||
return null;
|
||||
}
|
||||
if (mCurrentVibration != null && !mCurrentVibration.getVibration().hasEnded()) {
|
||||
if (mCurrentVibration.getVibration().attrs.getUsage()
|
||||
== VibrationAttributes.USAGE_ALARM) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Ignoring incoming vibration in favor of alarm vibration");
|
||||
}
|
||||
return Vibration.Status.IGNORED_FOR_ALARM;
|
||||
}
|
||||
if (mCurrentVibration.getVibration().isRepeating()) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Ignoring incoming vibration in favor of repeating vibration");
|
||||
}
|
||||
return Vibration.Status.IGNORED_FOR_ONGOING;
|
||||
}
|
||||
|
||||
Vibration currentVibration = mCurrentVibration.getVibration();
|
||||
if (currentVibration.hasEnded()) {
|
||||
// Current vibration is finishing up, it should not block incoming vibrations.
|
||||
return null;
|
||||
}
|
||||
|
||||
if (currentVibration.attrs.getUsage() == VibrationAttributes.USAGE_ALARM) {
|
||||
return Vibration.Status.IGNORED_FOR_ALARM;
|
||||
}
|
||||
|
||||
if (currentVibration.isRepeating()) {
|
||||
return Vibration.Status.IGNORED_FOR_ONGOING;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -684,57 +795,16 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
/**
|
||||
* Check if given vibration should be ignored by this service.
|
||||
*
|
||||
* @return One of Vibration.Status.IGNORED_* values if the vibration should be ignored.
|
||||
* @see #shouldIgnoreVibrationLocked(int, String, VibrationAttributes)
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private Vibration.Status shouldIgnoreVibrationLocked(Vibration vib) {
|
||||
// If something has external control of the vibrator, assume that it's more important.
|
||||
if (mCurrentExternalVibration != null) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Ignoring incoming vibration for current external vibration");
|
||||
}
|
||||
return Vibration.Status.IGNORED_FOR_EXTERNAL;
|
||||
}
|
||||
|
||||
if (!mVibrationSettings.shouldVibrateForUid(vib.uid, vib.attrs.getUsage())) {
|
||||
Slog.e(TAG, "Ignoring incoming vibration as process with"
|
||||
+ " uid= " + vib.uid + " is background,"
|
||||
+ " attrs= " + vib.attrs);
|
||||
return Vibration.Status.IGNORED_BACKGROUND;
|
||||
}
|
||||
|
||||
return shouldIgnoreVibrationLocked(vib.uid, vib.opPkg, vib.attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a vibration with given {@code uid}, {@code opPkg} and {@code attrs} should be
|
||||
* ignored by this service.
|
||||
*
|
||||
* @param uid The user id of this vibration
|
||||
* @param opPkg The package name of this vibration
|
||||
* @param attrs The attributes of this vibration
|
||||
* @return One of Vibration.Status.IGNORED_* values if the vibration should be ignored.
|
||||
* @return One of Vibration.Status.IGNORED_* values if the vibration should be ignored, null
|
||||
* otherwise.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private Vibration.Status shouldIgnoreVibrationLocked(int uid, String opPkg,
|
||||
VibrationAttributes attrs) {
|
||||
if (!mVibrationSettings.shouldVibrateForPowerMode(attrs.getUsage())) {
|
||||
return Vibration.Status.IGNORED_FOR_POWER;
|
||||
}
|
||||
|
||||
int intensity = mVibrationSettings.getCurrentIntensity(attrs.getUsage());
|
||||
if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) {
|
||||
return Vibration.Status.IGNORED_FOR_SETTINGS;
|
||||
}
|
||||
|
||||
if (!mVibrationSettings.shouldVibrateForRingerMode(attrs.getUsage())) {
|
||||
if (DEBUG) {
|
||||
Slog.e(TAG, "Vibrate ignored, not vibrating for ringtones");
|
||||
}
|
||||
return Vibration.Status.IGNORED_RINGTONE;
|
||||
Vibration.Status statusFromSettings = mVibrationSettings.shouldIgnoreVibration(uid, attrs);
|
||||
if (statusFromSettings != null) {
|
||||
return statusFromSettings;
|
||||
}
|
||||
|
||||
int mode = checkAppOpModeLocked(uid, opPkg, attrs);
|
||||
@@ -742,7 +812,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
if (mode == AppOpsManager.MODE_ERRORED) {
|
||||
// We might be getting calls from within system_server, so we don't actually
|
||||
// want to throw a SecurityException here.
|
||||
Slog.w(TAG, "Would be an error: vibrate from uid " + uid);
|
||||
return Vibration.Status.IGNORED_ERROR_APP_OPS;
|
||||
} else {
|
||||
return Vibration.Status.IGNORED_APP_OPS;
|
||||
@@ -1236,21 +1305,18 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
|
||||
/** Keep records of vibrations played and provide debug information for this service. */
|
||||
private final class VibratorManagerRecords {
|
||||
@GuardedBy("mLock")
|
||||
private static final class VibratorManagerRecords {
|
||||
private final SparseArray<LinkedList<Vibration.DebugInfo>> mPreviousVibrations =
|
||||
new SparseArray<>();
|
||||
@GuardedBy("mLock")
|
||||
private final LinkedList<Vibration.DebugInfo> mPreviousExternalVibrations =
|
||||
new LinkedList<>();
|
||||
private final int mPreviousVibrationsLimit;
|
||||
|
||||
private VibratorManagerRecords(int limit) {
|
||||
VibratorManagerRecords(int limit) {
|
||||
mPreviousVibrationsLimit = limit;
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
void record(Vibration vib) {
|
||||
synchronized void record(Vibration vib) {
|
||||
int usage = vib.attrs.getUsage();
|
||||
if (!mPreviousVibrations.contains(usage)) {
|
||||
mPreviousVibrations.put(usage, new LinkedList<>());
|
||||
@@ -1258,122 +1324,67 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
record(mPreviousVibrations.get(usage), vib.getDebugInfo());
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
void record(ExternalVibrationHolder vib) {
|
||||
synchronized void record(ExternalVibrationHolder vib) {
|
||||
record(mPreviousExternalVibrations, vib.getDebugInfo());
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
void record(LinkedList<Vibration.DebugInfo> records, Vibration.DebugInfo info) {
|
||||
synchronized void record(LinkedList<Vibration.DebugInfo> records,
|
||||
Vibration.DebugInfo info) {
|
||||
if (records.size() > mPreviousVibrationsLimit) {
|
||||
records.removeFirst();
|
||||
}
|
||||
records.addLast(info);
|
||||
}
|
||||
|
||||
void dumpText(PrintWriter pw) {
|
||||
pw.println("Vibrator Manager Service:");
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Dumping vibrator manager service to text...");
|
||||
}
|
||||
pw.println(" mVibrationSettings:");
|
||||
pw.println(" " + mVibrationSettings);
|
||||
synchronized void dumpText(PrintWriter pw) {
|
||||
for (int i = 0; i < mPreviousVibrations.size(); i++) {
|
||||
pw.println();
|
||||
pw.println(" mVibratorControllers:");
|
||||
for (int i = 0; i < mVibrators.size(); i++) {
|
||||
pw.println(" " + mVibrators.valueAt(i));
|
||||
}
|
||||
pw.println();
|
||||
pw.println(" mCurrentVibration:");
|
||||
pw.println(" " + (mCurrentVibration == null
|
||||
? null : mCurrentVibration.getVibration().getDebugInfo()));
|
||||
pw.println();
|
||||
pw.println(" mNextVibration:");
|
||||
pw.println(" " + (mNextVibration == null
|
||||
? null : mNextVibration.getVibration().getDebugInfo()));
|
||||
pw.println();
|
||||
pw.println(" mCurrentExternalVibration:");
|
||||
pw.println(" " + (mCurrentExternalVibration == null
|
||||
? null : mCurrentExternalVibration.getDebugInfo()));
|
||||
pw.println();
|
||||
for (int i = 0; i < mPreviousVibrations.size(); i++) {
|
||||
pw.println();
|
||||
pw.print(" Previous vibrations for usage ");
|
||||
pw.print(VibrationAttributes.usageToString(mPreviousVibrations.keyAt(i)));
|
||||
pw.println(":");
|
||||
for (Vibration.DebugInfo info : mPreviousVibrations.valueAt(i)) {
|
||||
pw.println(" " + info);
|
||||
}
|
||||
}
|
||||
|
||||
pw.println();
|
||||
pw.println(" Previous external vibrations:");
|
||||
for (Vibration.DebugInfo info : mPreviousExternalVibrations) {
|
||||
pw.print(" Previous vibrations for usage ");
|
||||
pw.print(VibrationAttributes.usageToString(mPreviousVibrations.keyAt(i)));
|
||||
pw.println(":");
|
||||
for (Vibration.DebugInfo info : mPreviousVibrations.valueAt(i)) {
|
||||
pw.println(" " + info);
|
||||
}
|
||||
}
|
||||
|
||||
pw.println();
|
||||
pw.println(" Previous external vibrations:");
|
||||
for (Vibration.DebugInfo info : mPreviousExternalVibrations) {
|
||||
pw.println(" " + info);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void dumpProto(FileDescriptor fd) {
|
||||
final ProtoOutputStream proto = new ProtoOutputStream(fd);
|
||||
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Dumping vibrator manager service to proto...");
|
||||
synchronized void dumpProto(ProtoOutputStream proto) {
|
||||
for (int i = 0; i < mPreviousVibrations.size(); i++) {
|
||||
long fieldId;
|
||||
switch (mPreviousVibrations.keyAt(i)) {
|
||||
case VibrationAttributes.USAGE_RINGTONE:
|
||||
fieldId = VibratorManagerServiceDumpProto.PREVIOUS_RING_VIBRATIONS;
|
||||
break;
|
||||
case VibrationAttributes.USAGE_NOTIFICATION:
|
||||
fieldId = VibratorManagerServiceDumpProto
|
||||
.PREVIOUS_NOTIFICATION_VIBRATIONS;
|
||||
break;
|
||||
case VibrationAttributes.USAGE_ALARM:
|
||||
fieldId = VibratorManagerServiceDumpProto.PREVIOUS_ALARM_VIBRATIONS;
|
||||
break;
|
||||
default:
|
||||
fieldId = VibratorManagerServiceDumpProto.PREVIOUS_VIBRATIONS;
|
||||
}
|
||||
mVibrationSettings.dumpProto(proto);
|
||||
if (mCurrentVibration != null) {
|
||||
mCurrentVibration.getVibration().getDebugInfo().dumpProto(proto,
|
||||
VibratorManagerServiceDumpProto.CURRENT_VIBRATION);
|
||||
}
|
||||
if (mCurrentExternalVibration != null) {
|
||||
mCurrentExternalVibration.getDebugInfo().dumpProto(proto,
|
||||
VibratorManagerServiceDumpProto.CURRENT_EXTERNAL_VIBRATION);
|
||||
}
|
||||
|
||||
boolean isVibrating = false;
|
||||
boolean isUnderExternalControl = false;
|
||||
for (int i = 0; i < mVibrators.size(); i++) {
|
||||
proto.write(VibratorManagerServiceDumpProto.VIBRATOR_IDS, mVibrators.keyAt(i));
|
||||
isVibrating |= mVibrators.valueAt(i).isVibrating();
|
||||
isUnderExternalControl |= mVibrators.valueAt(i).isUnderExternalControl();
|
||||
}
|
||||
proto.write(VibratorManagerServiceDumpProto.IS_VIBRATING, isVibrating);
|
||||
proto.write(VibratorManagerServiceDumpProto.VIBRATOR_UNDER_EXTERNAL_CONTROL,
|
||||
isUnderExternalControl);
|
||||
|
||||
for (int i = 0; i < mPreviousVibrations.size(); i++) {
|
||||
long fieldId;
|
||||
switch (mPreviousVibrations.keyAt(i)) {
|
||||
case VibrationAttributes.USAGE_RINGTONE:
|
||||
fieldId = VibratorManagerServiceDumpProto.PREVIOUS_RING_VIBRATIONS;
|
||||
break;
|
||||
case VibrationAttributes.USAGE_NOTIFICATION:
|
||||
fieldId = VibratorManagerServiceDumpProto
|
||||
.PREVIOUS_NOTIFICATION_VIBRATIONS;
|
||||
break;
|
||||
case VibrationAttributes.USAGE_ALARM:
|
||||
fieldId = VibratorManagerServiceDumpProto.PREVIOUS_ALARM_VIBRATIONS;
|
||||
break;
|
||||
default:
|
||||
fieldId = VibratorManagerServiceDumpProto.PREVIOUS_VIBRATIONS;
|
||||
}
|
||||
for (Vibration.DebugInfo info : mPreviousVibrations.valueAt(i)) {
|
||||
info.dumpProto(proto, fieldId);
|
||||
}
|
||||
}
|
||||
|
||||
for (Vibration.DebugInfo info : mPreviousExternalVibrations) {
|
||||
info.dumpProto(proto,
|
||||
VibratorManagerServiceDumpProto.PREVIOUS_EXTERNAL_VIBRATIONS);
|
||||
for (Vibration.DebugInfo info : mPreviousVibrations.valueAt(i)) {
|
||||
info.dumpProto(proto, fieldId);
|
||||
}
|
||||
}
|
||||
proto.flush();
|
||||
|
||||
for (Vibration.DebugInfo info : mPreviousExternalVibrations) {
|
||||
info.dumpProto(proto,
|
||||
VibratorManagerServiceDumpProto.PREVIOUS_EXTERNAL_VIBRATIONS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears mNextVibration if set, ending it cleanly */
|
||||
@GuardedBy("mLock")
|
||||
private void clearNextVibrationLocked(Vibration.Status endStatus) {
|
||||
if (mNextVibration != null) {
|
||||
endVibrationLocked(mNextVibration.getVibration(), endStatus);
|
||||
@@ -1482,6 +1493,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void stopExternalVibrateLocked(Vibration.Status status) {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "stopExternalVibrateLocked");
|
||||
try {
|
||||
|
||||
@@ -32,6 +32,7 @@ import static android.os.Vibrator.VIBRATION_INTENSITY_OFF;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -52,6 +53,7 @@ import android.os.Handler;
|
||||
import android.os.PowerManagerInternal;
|
||||
import android.os.PowerSaveState;
|
||||
import android.os.UserHandle;
|
||||
import android.os.VibrationAttributes;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.test.TestLooper;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
@@ -124,10 +126,11 @@ public class VibrationSettingsTest {
|
||||
new Handler(mTestLooper.getLooper()));
|
||||
mVibrationSettings.onSystemReady();
|
||||
|
||||
// Simulate System defaults.
|
||||
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 0);
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
|
||||
setGlobalSetting(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
|
||||
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -142,13 +145,12 @@ public class VibrationSettingsTest {
|
||||
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
|
||||
setGlobalSetting(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_ALARMS);
|
||||
setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, VIBRATION_INTENSITY_OFF);
|
||||
setUserSetting(Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_OFF);
|
||||
setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
|
||||
setUserSetting(Settings.System.HARDWARE_HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
|
||||
|
||||
verify(mListenerMock, times(8)).onChange();
|
||||
verify(mListenerMock, times(7)).onChange();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -173,126 +175,242 @@ public class VibrationSettingsTest {
|
||||
|
||||
verifyNoMoreInteractions(mListenerMock);
|
||||
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
|
||||
setGlobalSetting(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_ALARMS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateForRingerMode_beforeSystemReady_returnsFalseOnlyForRingtone() {
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
|
||||
setRingerMode(AudioManager.RINGER_MODE_MAX);
|
||||
VibrationSettings vibrationSettings = new VibrationSettings(mContextSpy,
|
||||
new Handler(mTestLooper.getLooper()));
|
||||
|
||||
assertFalse(vibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_ALARM));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_TOUCH));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_NOTIFICATION));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_COMMUNICATION_REQUEST));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_HARDWARE_FEEDBACK));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateForRingerMode_withoutRingtoneUsage_returnsTrue() {
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_ALARM));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_TOUCH));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_NOTIFICATION));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_COMMUNICATION_REQUEST));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_HARDWARE_FEEDBACK));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateForRingerMode_withVibrateWhenRinging_ignoreSettingsForSilentMode() {
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_SILENT);
|
||||
assertFalse(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_MAX);
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateForRingerMode_withApplyRampingRinger_ignoreSettingsForSilentMode() {
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_SILENT);
|
||||
assertFalse(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_MAX);
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateForRingerMode_withAllSettingsOff_onlyVibratesForVibrateMode() {
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
|
||||
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_SILENT);
|
||||
assertFalse(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_MAX);
|
||||
assertFalse(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
|
||||
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
|
||||
assertFalse(mVibrationSettings.shouldVibrateForRingerMode(USAGE_RINGTONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateForUid_withForegroundOnlyUsage_returnsTrueWhInForeground() {
|
||||
assertTrue(mVibrationSettings.shouldVibrateForUid(UID, USAGE_TOUCH));
|
||||
public void shouldIgnoreVibration_fromBackground_doesNotIgnoreUsagesFromAllowlist() {
|
||||
int[] expectedAllowedVibrations = new int[] {
|
||||
USAGE_RINGTONE,
|
||||
USAGE_ALARM,
|
||||
USAGE_NOTIFICATION,
|
||||
USAGE_COMMUNICATION_REQUEST,
|
||||
USAGE_HARDWARE_FEEDBACK,
|
||||
USAGE_PHYSICAL_EMULATION,
|
||||
};
|
||||
|
||||
mVibrationSettings.mUidObserver.onUidStateChanged(
|
||||
UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND, 0, 0);
|
||||
assertFalse(mVibrationSettings.shouldVibrateForUid(UID, USAGE_TOUCH));
|
||||
|
||||
for (int usage : expectedAllowedVibrations) {
|
||||
assertNull("Error for usage " + VibrationAttributes.usageToString(usage),
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(usage)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateForUid_withBackgroundAllowedUsage_returnTrue() {
|
||||
public void shouldIgnoreVibration_fromBackground_ignoresUsagesNotInAllowlist() {
|
||||
int[] expectedIgnoredVibrations = new int[] {
|
||||
USAGE_TOUCH,
|
||||
USAGE_UNKNOWN,
|
||||
};
|
||||
|
||||
mVibrationSettings.mUidObserver.onUidStateChanged(
|
||||
UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND, 0, 0);
|
||||
|
||||
assertTrue(mVibrationSettings.shouldVibrateForUid(UID, USAGE_ALARM));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForUid(UID, USAGE_COMMUNICATION_REQUEST));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForUid(UID, USAGE_NOTIFICATION));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForUid(UID, USAGE_RINGTONE));
|
||||
for (int usage : expectedIgnoredVibrations) {
|
||||
assertEquals("Error for usage " + VibrationAttributes.usageToString(usage),
|
||||
Vibration.Status.IGNORED_BACKGROUND,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(usage)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateForPowerMode_withLowPowerAndAllowedUsage_returnTrue() {
|
||||
public void shouldIgnoreVibration_fromForeground_allowsAnyUsage() {
|
||||
mVibrationSettings.mUidObserver.onUidStateChanged(
|
||||
UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0, 0);
|
||||
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_ALARM)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_inBatterySaverMode_doesNotIgnoreUsagesFromAllowlist() {
|
||||
int[] expectedAllowedVibrations = new int[] {
|
||||
USAGE_RINGTONE,
|
||||
USAGE_ALARM,
|
||||
USAGE_COMMUNICATION_REQUEST,
|
||||
};
|
||||
|
||||
mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
|
||||
|
||||
assertTrue(mVibrationSettings.shouldVibrateForPowerMode(USAGE_ALARM));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForPowerMode(USAGE_RINGTONE));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForPowerMode(USAGE_COMMUNICATION_REQUEST));
|
||||
for (int usage : expectedAllowedVibrations) {
|
||||
assertNull("Error for usage " + VibrationAttributes.usageToString(usage),
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(usage)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrateForPowerMode_withRestrictedUsage_returnsFalseWhileInLowPowerMode() {
|
||||
public void shouldIgnoreVibration_inBatterySaverMode_ignoresUsagesNotInAllowlist() {
|
||||
int[] expectedIgnoredVibrations = new int[] {
|
||||
USAGE_NOTIFICATION,
|
||||
USAGE_HARDWARE_FEEDBACK,
|
||||
USAGE_PHYSICAL_EMULATION,
|
||||
USAGE_TOUCH,
|
||||
USAGE_UNKNOWN,
|
||||
};
|
||||
|
||||
mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
|
||||
|
||||
for (int usage : expectedIgnoredVibrations) {
|
||||
assertEquals("Error for usage " + VibrationAttributes.usageToString(usage),
|
||||
Vibration.Status.IGNORED_FOR_POWER,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(usage)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_notInBatterySaverMode_allowsAnyUsage() {
|
||||
mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
|
||||
|
||||
assertTrue(mVibrationSettings.shouldVibrateForPowerMode(USAGE_TOUCH));
|
||||
assertTrue(mVibrationSettings.shouldVibrateForPowerMode(USAGE_NOTIFICATION));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_COMMUNICATION_REQUEST)));
|
||||
}
|
||||
|
||||
mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
|
||||
@Test
|
||||
public void shouldIgnoreVibration_withRingerModeSilent_ignoresRingtoneAndTouch() {
|
||||
// Vibrating settings on are overruled by ringer mode.
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
|
||||
setRingerMode(AudioManager.RINGER_MODE_SILENT);
|
||||
|
||||
assertFalse(mVibrationSettings.shouldVibrateForPowerMode(USAGE_TOUCH));
|
||||
assertFalse(mVibrationSettings.shouldVibrateForPowerMode(USAGE_NOTIFICATION));
|
||||
assertEquals(Vibration.Status.IGNORED_FOR_RINGER_MODE,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_RINGTONE)));
|
||||
assertEquals(Vibration.Status.IGNORED_FOR_RINGER_MODE,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_COMMUNICATION_REQUEST)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_HARDWARE_FEEDBACK)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_withRingerModeVibrate_allowsAllVibrations() {
|
||||
// Vibrating settings off are overruled by ringer mode.
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
|
||||
setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
|
||||
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_PHYSICAL_EMULATION)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_RINGTONE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_withRingerModeNormalAndRingSettingsOff_ignoresRingtoneOnly() {
|
||||
// Vibrating settings off are respected for normal ringer mode.
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
|
||||
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
|
||||
|
||||
assertEquals(Vibration.Status.IGNORED_FOR_RINGER_MODE,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_RINGTONE)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_NOTIFICATION)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_withRingerModeNormalAndRingSettingsOn_allowsAllVibrations() {
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
|
||||
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
|
||||
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_RINGTONE)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_ALARM)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_withRingerModeNormalAndRampingRingerOn_allowsAllVibrations() {
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
|
||||
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
|
||||
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_RINGTONE)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_COMMUNICATION_REQUEST)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_withHapticFeedbackSettingsOff_ignoresTouchVibration() {
|
||||
setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
|
||||
|
||||
assertEquals(Vibration.Status.IGNORED_FOR_SETTINGS,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_RINGTONE)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_HARDWARE_FEEDBACK)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_withHardwareFeedbackSettingsOff_ignoresHardwareVibrations() {
|
||||
setUserSetting(Settings.System.HARDWARE_HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
|
||||
|
||||
assertEquals(Vibration.Status.IGNORED_FOR_SETTINGS,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_HARDWARE_FEEDBACK)));
|
||||
assertEquals(Vibration.Status.IGNORED_FOR_SETTINGS,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_PHYSICAL_EMULATION)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_NOTIFICATION)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_withNotificationSettingsOff_ignoresNotificationVibrations() {
|
||||
setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, VIBRATION_INTENSITY_OFF);
|
||||
|
||||
assertEquals(Vibration.Status.IGNORED_FOR_SETTINGS,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_NOTIFICATION)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_ALARM)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_RINGTONE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldIgnoreVibration_withRingSettingsOff_ignoresRingtoneVibrations() {
|
||||
// Vibrating settings on are overruled by ring intensity setting.
|
||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
|
||||
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
|
||||
setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
|
||||
setUserSetting(Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_OFF);
|
||||
|
||||
assertEquals(Vibration.Status.IGNORED_FOR_SETTINGS,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_RINGTONE)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_NOTIFICATION)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_ALARM)));
|
||||
assertNull(mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
VibrationAttributes.createForUsage(USAGE_TOUCH)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -304,24 +422,6 @@ public class VibrationSettingsTest {
|
||||
assertFalse(mVibrationSettings.shouldVibrateInputDevices());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isInZenMode_returnsSettingsValue() {
|
||||
setGlobalSetting(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
|
||||
assertFalse(mVibrationSettings.isInZenMode());
|
||||
|
||||
setGlobalSetting(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_NO_INTERRUPTIONS);
|
||||
assertTrue(mVibrationSettings.isInZenMode());
|
||||
setGlobalSetting(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_ALARMS);
|
||||
assertTrue(mVibrationSettings.isInZenMode());
|
||||
|
||||
setGlobalSetting(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
|
||||
assertFalse(mVibrationSettings.isInZenMode());
|
||||
|
||||
setGlobalSetting(Settings.Global.ZEN_MODE,
|
||||
Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
|
||||
assertTrue(mVibrationSettings.isInZenMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDefaultIntensity_beforeSystemReady_returnsMediumToAllExceptAlarm() {
|
||||
mFakeVibrator.setDefaultHapticFeedbackIntensity(VIBRATION_INTENSITY_HIGH);
|
||||
@@ -464,12 +564,6 @@ public class VibrationSettingsTest {
|
||||
mVibrationSettings.updateSettings();
|
||||
}
|
||||
|
||||
private void setGlobalSetting(String settingName, int value) {
|
||||
Settings.Global.putInt(mContextSpy.getContentResolver(), settingName, value);
|
||||
// FakeSettingsProvider don't support testing triggering ContentObserver yet.
|
||||
mVibrationSettings.updateSettings();
|
||||
}
|
||||
|
||||
private void setRingerMode(int ringerMode) {
|
||||
mAudioManager.setRingerModeInternal(ringerMode);
|
||||
assertEquals(ringerMode, mAudioManager.getRingerModeInternal());
|
||||
|
||||
Reference in New Issue
Block a user