Clean up after VibratorManager feature introduced

- Move VibratorManagerService to com.android.server.vibrator and make
all other classes there package-private;
- Add some missing haptics-related files to OWNERS files;
- Remove some unused methods;
- Delegate CombinedVibrationEffect to input devices, instead of only
delegating VibrationEffect effects;
- Move vibratorservice.proto to vibrator folder and add missing fields;
- Mark large VibrationThread tests with @LargeTest;

Fix: 131311651
Fix: 177805090
Test: VibratorManagerServiceTest
Change-Id: Ic747190b70b2f45ac7671eb01f8f05cf66d3a96c
This commit is contained in:
Lais Andrade
2021-02-10 16:35:22 +00:00
parent 55a0aebe7f
commit 43bf46112c
24 changed files with 216 additions and 203 deletions

View File

@@ -1,4 +1,6 @@
# Haptics
per-file CombinedVibrationEffect.aidl = michaelwr@google.com
per-file CombinedVibrationEffect.java = michaelwr@google.com
per-file ExternalVibration.aidl = michaelwr@google.com
per-file ExternalVibration.java = michaelwr@google.com
per-file IExternalVibrationController.aidl = michaelwr@google.com
@@ -6,9 +8,11 @@ per-file IExternalVibratorService.aidl = michaelwr@google.com
per-file IVibratorManagerService.aidl = michaelwr@google.com
per-file NullVibrator.java = michaelwr@google.com
per-file SystemVibrator.java = michaelwr@google.com
per-file SystemVibratorManager.java = michaelwr@google.com
per-file VibrationEffect.aidl = michaelwr@google.com
per-file VibrationEffect.java = michaelwr@google.com
per-file Vibrator.java = michaelwr@google.com
per-file VibratorManager.java = michaelwr@google.com
# PowerManager
per-file IPowerManager.aidl = michaelwr@google.com, santoscordon@google.com

View File

@@ -15,7 +15,7 @@
*/
syntax = "proto2";
package com.android.server;
package com.android.server.vibrator;
option java_multiple_files = true;
@@ -51,12 +51,25 @@ message ComposedProto {
// A com.android.os.VibrationEffect object.
message VibrationEffectProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional OneShotProto oneshot = 3;
optional WaveformProto waveform = 1;
optional PrebakedProto prebaked = 2;
optional OneShotProto oneshot = 1;
optional WaveformProto waveform = 2;
optional PrebakedProto prebaked = 3;
optional ComposedProto composed = 4;
}
message SyncVibrationEffectProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
repeated VibrationEffectProto effects = 1;
repeated int32 vibrator_ids = 2;
}
// A com.android.os.CombinedVibrationEffect object.
message CombinedVibrationEffectProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
repeated SyncVibrationEffectProto effects = 1;
repeated int32 delays = 2;
}
message VibrationAttributesProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional int32 usage = 1;
@@ -68,30 +81,31 @@ message VibrationAttributesProto {
message VibrationProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional int64 start_time = 1;
optional int64 end_time = 4;
optional VibrationEffectProto effect = 2;
optional VibrationEffectProto original_effect = 3;
optional int64 end_time = 2;
optional CombinedVibrationEffectProto effect = 3;
optional CombinedVibrationEffectProto original_effect = 4;
optional VibrationAttributesProto attributes = 5;
optional int32 status = 6;
}
// Next id: 17
message VibratorServiceDumpProto {
// Next id: 18
message VibratorManagerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional VibrationProto current_vibration = 1;
optional bool is_vibrating = 2;
optional VibrationProto current_external_vibration = 3;
optional bool vibrator_under_external_control = 4;
optional bool low_power_mode = 5;
optional int32 haptic_feedback_intensity = 6;
optional int32 haptic_feedback_default_intensity = 14;
optional int32 notification_intensity = 7;
optional int32 notification_default_intensity = 15;
optional int32 ring_intensity = 8;
optional int32 ring_default_intensity = 16;
repeated VibrationProto previous_ring_vibrations = 9;
repeated VibrationProto previous_notification_vibrations = 10;
repeated VibrationProto previous_alarm_vibrations = 11;
repeated VibrationProto previous_vibrations = 12;
repeated VibrationProto previous_external_vibrations = 13;
repeated int32 vibrator_ids = 1;
optional VibrationProto current_vibration = 2;
optional bool is_vibrating = 3;
optional VibrationProto current_external_vibration = 4;
optional bool vibrator_under_external_control = 5;
optional bool low_power_mode = 6;
optional int32 haptic_feedback_intensity = 7;
optional int32 haptic_feedback_default_intensity = 8;
optional int32 notification_intensity = 9;
optional int32 notification_default_intensity = 10;
optional int32 ring_intensity = 11;
optional int32 ring_default_intensity = 12;
repeated VibrationProto previous_ring_vibrations = 13;
repeated VibrationProto previous_notification_vibrations = 14;
repeated VibrationProto previous_alarm_vibrations = 15;
repeated VibrationProto previous_vibrations = 16;
repeated VibrationProto previous_external_vibrations = 17;
}

View File

@@ -2,8 +2,11 @@
per-file BrightnessLimit.java = michaelwr@google.com, santoscordon@google.com
# Haptics
per-file CombinedVibrationEffectTest.java = michaelwr@google.com
per-file ExternalVibrationTest.java = michaelwr@google.com
per-file VibrationEffectTest.java = michaelwr@google.com
per-file VibratorInfoTest.java = michaelwr@google.com
per-file VibratorTest.java = michaelwr@google.com
# Power
per-file PowerManager*.java = michaelwr@google.com, santoscordon@google.com

View File

@@ -1,8 +1,8 @@
# Connectivity / Networking
per-file ConnectivityService.java,ConnectivityServiceInitializer.java,NetworkManagementService.java,NsdService.java = file:/services/core/java/com/android/server/net/OWNERS
# Vibrator / Threads
per-file VibratorManagerService.java, DisplayThread.java = michaelwr@google.com, ogunwale@google.com
# Threads
per-file DisplayThread.java = michaelwr@google.com, ogunwale@google.com
# Zram writeback
per-file ZramWriteback.java = minchan@google.com, rajekumar@google.com

View File

@@ -21,16 +21,14 @@ import android.hardware.input.InputManager;
import android.os.CombinedVibrationEffect;
import android.os.Handler;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.os.VibratorManager;
import android.util.SparseArray;
import android.view.InputDevice;
import com.android.internal.annotations.GuardedBy;
/** Delegates vibrations to all connected {@link InputDevice} with available {@link Vibrator}. */
// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
public final class InputDeviceDelegate implements InputManager.InputDeviceListener {
/** Delegates vibrations to all connected {@link InputDevice} with one or more vibrators. */
final class InputDeviceDelegate implements InputManager.InputDeviceListener {
private static final String TAG = "InputDeviceDelegate";
private final Object mLock = new Object();
@@ -38,7 +36,7 @@ public final class InputDeviceDelegate implements InputManager.InputDeviceListen
private final InputManager mInputManager;
@GuardedBy("mLock")
private final SparseArray<Vibrator> mInputDeviceVibrators = new SparseArray<>();
private final SparseArray<VibratorManager> mInputDeviceVibrators = new SparseArray<>();
/**
* Flag updated via {@link #updateInputDeviceVibrators(boolean)}, holding the value of {@link
@@ -47,7 +45,7 @@ public final class InputDeviceDelegate implements InputManager.InputDeviceListen
@GuardedBy("mLock")
private boolean mShouldVibrateInputDevices;
public InputDeviceDelegate(Context context, Handler handler) {
InputDeviceDelegate(Context context, Handler handler) {
mHandler = handler;
mInputManager = context.getSystemService(InputManager.class);
}
@@ -81,32 +79,22 @@ public final class InputDeviceDelegate implements InputManager.InputDeviceListen
}
/**
* Vibrate all {@link InputDevice} with {@link Vibrator} available using given effect.
* Vibrate all {@link InputDevice} with vibrators using given effect.
*
* @return {@link #isAvailable()}
*/
public boolean vibrateIfAvailable(int uid, String opPkg, CombinedVibrationEffect effect,
String reason, VibrationAttributes attrs) {
synchronized (mLock) {
// TODO(b/159207608): Pass on the combined vibration once InputManager is merged
if (effect instanceof CombinedVibrationEffect.Mono) {
VibrationEffect e = ((CombinedVibrationEffect.Mono) effect).getEffect();
if (e instanceof VibrationEffect.Prebaked) {
VibrationEffect fallback = ((VibrationEffect.Prebaked) e).getFallbackEffect();
if (fallback != null) {
e = fallback;
}
}
for (int i = 0; i < mInputDeviceVibrators.size(); i++) {
mInputDeviceVibrators.valueAt(i).vibrate(uid, opPkg, e, reason, attrs);
}
for (int i = 0; i < mInputDeviceVibrators.size(); i++) {
mInputDeviceVibrators.valueAt(i).vibrate(uid, opPkg, effect, reason, attrs);
}
return mInputDeviceVibrators.size() > 0;
}
}
/**
* Cancel vibration on all {@link InputDevice} with {@link Vibrator} available.
* Cancel vibration on all {@link InputDevice} with vibrators.
*
* @return {@link #isAvailable()}
*/
@@ -147,9 +135,9 @@ public final class InputDeviceDelegate implements InputManager.InputDeviceListen
if (device == null) {
continue;
}
Vibrator vibrator = device.getVibrator();
if (vibrator.hasVibrator()) {
mInputDeviceVibrators.put(device.getId(), vibrator);
VibratorManager vibratorManager = device.getVibratorManager();
if (vibratorManager.getVibratorIds().length > 0) {
mInputDeviceVibrators.put(device.getId(), vibratorManager);
}
}
} else {
@@ -171,9 +159,9 @@ public final class InputDeviceDelegate implements InputManager.InputDeviceListen
mInputDeviceVibrators.remove(deviceId);
return;
}
Vibrator vibrator = device.getVibrator();
if (vibrator.hasVibrator()) {
mInputDeviceVibrators.put(deviceId, vibrator);
VibratorManager vibratorManager = device.getVibratorManager();
if (vibratorManager.getVibratorIds().length > 0) {
mInputDeviceVibrators.put(device.getId(), vibratorManager);
} else {
mInputDeviceVibrators.remove(deviceId);
}

View File

@@ -25,25 +25,16 @@ import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.util.proto.ProtoOutputStream;
import com.android.server.ComposedProto;
import com.android.server.OneShotProto;
import com.android.server.PrebakedProto;
import com.android.server.VibrationAttributesProto;
import com.android.server.VibrationEffectProto;
import com.android.server.VibrationProto;
import com.android.server.WaveformProto;
import java.text.SimpleDateFormat;
import java.util.Date;
/** Represents a vibration request to the vibrator service. */
// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
public class Vibration {
final class Vibration {
private static final String TAG = "Vibration";
private static final SimpleDateFormat DEBUG_DATE_FORMAT =
new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
public enum Status {
enum Status {
RUNNING,
FINISHED,
FORWARDED_TO_INPUT_DEVICES,
@@ -91,7 +82,7 @@ public class Vibration {
private long mEndTimeDebug;
private Status mStatus;
public Vibration(IBinder token, int id, CombinedVibrationEffect effect,
Vibration(IBinder token, int id, CombinedVibrationEffect effect,
VibrationAttributes attrs, int uid, String opPkg, String reason) {
this.token = token;
this.mEffect = effect;
@@ -157,7 +148,7 @@ public class Vibration {
}
/** Debug information about vibrations. */
public static final class DebugInfo {
static final class DebugInfo {
private final long mStartTimeDebug;
private final long mEndTimeDebug;
private final CombinedVibrationEffect mEffect;
@@ -169,7 +160,7 @@ public class Vibration {
private final String mReason;
private final Status mStatus;
public DebugInfo(long startTimeDebug, long endTimeDebug, CombinedVibrationEffect effect,
DebugInfo(long startTimeDebug, long endTimeDebug, CombinedVibrationEffect effect,
CombinedVibrationEffect originalEffect, float scale, VibrationAttributes attrs,
int uid, String opPkg, String reason, Status status) {
mStartTimeDebug = startTimeDebug;
@@ -235,21 +226,49 @@ public class Vibration {
}
private void dumpEffect(
ProtoOutputStream proto, long fieldId, CombinedVibrationEffect combinedEffect) {
VibrationEffect effect;
// TODO(b/177805090): add proper support for dumping combined effects to proto
if (combinedEffect instanceof CombinedVibrationEffect.Mono) {
effect = ((CombinedVibrationEffect.Mono) combinedEffect).getEffect();
} else if (combinedEffect instanceof CombinedVibrationEffect.Stereo) {
effect = ((CombinedVibrationEffect.Stereo) combinedEffect).getEffects().valueAt(0);
} else if (combinedEffect instanceof CombinedVibrationEffect.Sequential) {
dumpEffect(proto, fieldId,
((CombinedVibrationEffect.Sequential) combinedEffect).getEffects().get(0));
return;
} else {
// Unknown combined effect, skip dump.
return;
ProtoOutputStream proto, long fieldId, CombinedVibrationEffect effect) {
dumpEffect(proto, fieldId,
(CombinedVibrationEffect.Sequential) CombinedVibrationEffect.startSequential()
.addNext(effect)
.combine());
}
private void dumpEffect(
ProtoOutputStream proto, long fieldId, CombinedVibrationEffect.Sequential effect) {
final long token = proto.start(fieldId);
for (int i = 0; i < effect.getEffects().size(); i++) {
CombinedVibrationEffect nestedEffect = effect.getEffects().get(i);
if (nestedEffect instanceof CombinedVibrationEffect.Mono) {
dumpEffect(proto, CombinedVibrationEffectProto.EFFECTS,
(CombinedVibrationEffect.Mono) nestedEffect);
} else if (nestedEffect instanceof CombinedVibrationEffect.Stereo) {
dumpEffect(proto, CombinedVibrationEffectProto.EFFECTS,
(CombinedVibrationEffect.Stereo) nestedEffect);
}
proto.write(CombinedVibrationEffectProto.DELAYS, effect.getDelays().get(i));
}
proto.end(token);
}
private void dumpEffect(
ProtoOutputStream proto, long fieldId, CombinedVibrationEffect.Mono effect) {
final long token = proto.start(fieldId);
dumpEffect(proto, SyncVibrationEffectProto.EFFECTS, effect.getEffect());
proto.end(token);
}
private void dumpEffect(
ProtoOutputStream proto, long fieldId, CombinedVibrationEffect.Stereo effect) {
final long token = proto.start(fieldId);
for (int i = 0; i < effect.getEffects().size(); i++) {
proto.write(SyncVibrationEffectProto.VIBRATOR_IDS, effect.getEffects().keyAt(i));
dumpEffect(proto, SyncVibrationEffectProto.EFFECTS, effect.getEffects().valueAt(i));
}
proto.end(token);
}
private void dumpEffect(
ProtoOutputStream proto, long fieldId, VibrationEffect effect) {
final long token = proto.start(fieldId);
if (effect instanceof VibrationEffect.OneShot) {
dumpEffect(proto, VibrationEffectProto.ONESHOT, (VibrationEffect.OneShot) effect);

View File

@@ -29,8 +29,7 @@ import java.util.List;
import java.util.Objects;
/** Controls vibration scaling. */
// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
public final class VibrationScaler {
final class VibrationScaler {
private static final String TAG = "VibrationScaler";
// Scale levels. Each level, except MUTE, is defined as the delta between the current setting
@@ -56,7 +55,7 @@ public final class VibrationScaler {
private final VibrationSettings mSettingsController;
private final int mDefaultVibrationAmplitude;
public VibrationScaler(Context context, VibrationSettings settingsController) {
VibrationScaler(Context context, VibrationSettings settingsController) {
mSettingsController = settingsController;
mDefaultVibrationAmplitude = context.getResources().getInteger(
com.android.internal.R.integer.config_defaultVibrationAmplitude);

View File

@@ -39,20 +39,18 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.VibratorServiceDumpProto;
import java.util.ArrayList;
import java.util.List;
/** Controls all the system settings related to vibration. */
// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
public final class VibrationSettings {
final class VibrationSettings {
private static final String TAG = "VibrationSettings";
private static final long[] DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS = {0, 30, 100, 30};
/** Listener for changes on vibration settings. */
public interface OnVibratorSettingsChanged {
interface OnVibratorSettingsChanged {
/** Callback triggered when any of the vibrator settings change. */
void onChange();
}
@@ -86,7 +84,7 @@ public final class VibrationSettings {
@GuardedBy("mLock")
private boolean mLowPowerMode;
public VibrationSettings(Context context, Handler handler) {
VibrationSettings(Context context, Handler handler) {
mContext = context;
mVibrator = context.getSystemService(Vibrator.class);
mAudioManager = context.getSystemService(AudioManager.class);
@@ -345,17 +343,17 @@ public final class VibrationSettings {
/** Write current settings into given {@link ProtoOutputStream}. */
public void dumpProto(ProtoOutputStream proto) {
synchronized (mLock) {
proto.write(VibratorServiceDumpProto.HAPTIC_FEEDBACK_INTENSITY,
proto.write(VibratorManagerServiceDumpProto.HAPTIC_FEEDBACK_INTENSITY,
mHapticFeedbackIntensity);
proto.write(VibratorServiceDumpProto.HAPTIC_FEEDBACK_DEFAULT_INTENSITY,
proto.write(VibratorManagerServiceDumpProto.HAPTIC_FEEDBACK_DEFAULT_INTENSITY,
mVibrator.getDefaultHapticFeedbackIntensity());
proto.write(VibratorServiceDumpProto.NOTIFICATION_INTENSITY,
proto.write(VibratorManagerServiceDumpProto.NOTIFICATION_INTENSITY,
mNotificationIntensity);
proto.write(VibratorServiceDumpProto.NOTIFICATION_DEFAULT_INTENSITY,
proto.write(VibratorManagerServiceDumpProto.NOTIFICATION_DEFAULT_INTENSITY,
mVibrator.getDefaultNotificationVibrationIntensity());
proto.write(VibratorServiceDumpProto.RING_INTENSITY,
proto.write(VibratorManagerServiceDumpProto.RING_INTENSITY,
mRingIntensity);
proto.write(VibratorServiceDumpProto.RING_DEFAULT_INTENSITY,
proto.write(VibratorManagerServiceDumpProto.RING_DEFAULT_INTENSITY,
mVibrator.getDefaultRingVibrationIntensity());
}
}

View File

@@ -42,8 +42,7 @@ import java.util.List;
import java.util.PriorityQueue;
/** Plays a {@link Vibration} in dedicated thread. */
// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
public final class VibrationThread extends Thread implements IBinder.DeathRecipient {
final class VibrationThread extends Thread implements IBinder.DeathRecipient {
private static final String TAG = "VibrationThread";
private static final boolean DEBUG = false;
@@ -54,7 +53,7 @@ public final class VibrationThread extends Thread implements IBinder.DeathRecipi
private static final long CALLBACKS_EXTRA_TIMEOUT = 100;
/** Callbacks for playing a {@link Vibration}. */
public interface VibrationCallbacks {
interface VibrationCallbacks {
/**
* Callback triggered before starting a synchronized vibration step. This will be called
@@ -92,7 +91,7 @@ public final class VibrationThread extends Thread implements IBinder.DeathRecipi
@GuardedBy("mLock")
private boolean mForceStop;
public VibrationThread(Vibration vib, SparseArray<VibratorController> availableVibrators,
VibrationThread(Vibration vib, SparseArray<VibratorController> availableVibrators,
PowerManager.WakeLock wakeLock, IBatteryStats batteryStatsService,
VibrationCallbacks callbacks) {
mVibration = vib;
@@ -169,7 +168,7 @@ public final class VibrationThread extends Thread implements IBinder.DeathRecipi
}
}
public Vibration getVibration() {
Vibration getVibration() {
return mVibration;
}

View File

@@ -32,8 +32,7 @@ import com.android.internal.annotations.VisibleForTesting;
import libcore.util.NativeAllocationRegistry;
/** Controls a single vibrator. */
// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
public final class VibratorController {
final class VibratorController {
private static final String TAG = "VibratorController";
private final Object mLock = new Object();
@@ -99,12 +98,12 @@ public final class VibratorController {
static native void vibratorAlwaysOnDisable(long nativePtr, long id);
public VibratorController(int vibratorId, OnVibrationCompleteListener listener) {
VibratorController(int vibratorId, OnVibrationCompleteListener listener) {
this(vibratorId, listener, new NativeWrapper());
}
@VisibleForTesting
public VibratorController(int vibratorId, OnVibrationCompleteListener listener,
VibratorController(int vibratorId, OnVibrationCompleteListener listener,
NativeWrapper nativeWrapper) {
mNativeWrapper = nativeWrapper;
mNativeWrapper.init(vibratorId, listener);
@@ -142,11 +141,6 @@ public final class VibratorController {
}
}
@VisibleForTesting
public NativeWrapper getNativeWrapper() {
return mNativeWrapper;
}
/** Return the {@link VibratorInfo} representing the vibrator controlled by this instance. */
public VibratorInfo getVibratorInfo() {
return mVibratorInfo;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 The Android Open Source Project
* Copyright (C) 2021 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.server;
package com.android.server.vibrator;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -56,12 +56,8 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.DumpUtils;
import com.android.server.vibrator.InputDeviceDelegate;
import com.android.server.vibrator.Vibration;
import com.android.server.vibrator.VibrationScaler;
import com.android.server.vibrator.VibrationSettings;
import com.android.server.vibrator.VibrationThread;
import com.android.server.vibrator.VibratorController;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import libcore.util.NativeAllocationRegistry;
@@ -967,7 +963,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
/** Listener for synced vibration completion callbacks from native. */
@VisibleForTesting
public interface OnSyncedVibrationCompleteListener {
interface OnSyncedVibrationCompleteListener {
/** Callback triggered when synced vibration is complete. */
void onComplete(long vibrationId);
@@ -1167,6 +1163,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
}
}
pw.println();
pw.println(" Previous external vibrations:");
for (Vibration.DebugInfo info : mPreviousExternalVibrations) {
pw.println(" " + info);
@@ -1181,46 +1178,48 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
mVibrationSettings.dumpProto(proto);
if (mCurrentVibration != null) {
mCurrentVibration.getVibration().getDebugInfo().dumpProto(proto,
VibratorServiceDumpProto.CURRENT_VIBRATION);
VibratorManagerServiceDumpProto.CURRENT_VIBRATION);
}
if (mCurrentExternalVibration != null) {
mCurrentExternalVibration.getDebugInfo().dumpProto(proto,
VibratorServiceDumpProto.CURRENT_EXTERNAL_VIBRATION);
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(VibratorServiceDumpProto.IS_VIBRATING, isVibrating);
proto.write(VibratorServiceDumpProto.VIBRATOR_UNDER_EXTERNAL_CONTROL,
proto.write(VibratorManagerServiceDumpProto.IS_VIBRATING, isVibrating);
proto.write(VibratorManagerServiceDumpProto.VIBRATOR_UNDER_EXTERNAL_CONTROL,
isUnderExternalControl);
for (Vibration.DebugInfo info : mPreviousVibrations.get(
VibrationAttributes.USAGE_RINGTONE)) {
info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_RING_VIBRATIONS);
}
for (Vibration.DebugInfo info : mPreviousVibrations.get(
VibrationAttributes.USAGE_NOTIFICATION)) {
info.dumpProto(proto,
VibratorServiceDumpProto.PREVIOUS_NOTIFICATION_VIBRATIONS);
}
for (Vibration.DebugInfo info : mPreviousVibrations.get(
VibrationAttributes.USAGE_ALARM)) {
info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_ALARM_VIBRATIONS);
}
for (Vibration.DebugInfo info : mPreviousVibrations.get(
VibrationAttributes.USAGE_UNKNOWN)) {
info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_VIBRATIONS);
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, VibratorServiceDumpProto.PREVIOUS_EXTERNAL_VIBRATIONS);
info.dumpProto(proto,
VibratorManagerServiceDumpProto.PREVIOUS_EXTERNAL_VIBRATIONS);
}
}
proto.flush();
@@ -1300,7 +1299,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
cancelingVibration.join();
} catch (InterruptedException e) {
Slog.w("Interrupted while waiting for vibration to finish before starting "
+ "external control", e);
+ "external control", e);
}
}
if (DEBUG) {

View File

@@ -54,7 +54,7 @@ cc_library_static {
"com_android_server_UsbMidiDevice.cpp",
"com_android_server_UsbHostManager.cpp",
"com_android_server_vibrator_VibratorController.cpp",
"com_android_server_VibratorManagerService.cpp",
"com_android_server_vibrator_VibratorManagerService.cpp",
"com_android_server_PersistentDataBlockService.cpp",
"com_android_server_am_CachedAppOptimizer.cpp",
"com_android_server_am_LowMemDetector.cpp",

View File

@@ -1,10 +1,6 @@
# Display
per-file com_android_server_lights_LightsService.cpp = michaelwr@google.com, santoscordon@google.com
# Haptics
per-file com_android_server_vibrator_VibratorController.cpp = michaelwr@google.com
per-file com_android_server_VibratorManagerService.cpp = michaelwr@google.com
# Input
per-file com_android_server_input_InputManagerService.cpp = michaelwr@google.com, svv@google.com

View File

@@ -29,7 +29,7 @@
#include <vibratorservice/VibratorHalController.h>
#include "com_android_server_VibratorManagerService.h"
#include "com_android_server_vibrator_VibratorManagerService.h"
namespace V1_0 = android::hardware::vibrator::V1_0;
namespace V1_1 = android::hardware::vibrator::V1_1;
@@ -73,7 +73,8 @@ static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) ==
static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
static std::shared_ptr<vibrator::HalController> findVibrator(int32_t vibratorId) {
vibrator::ManagerHalController* manager = android_server_VibratorManagerService_getManager();
vibrator::ManagerHalController* manager =
android_server_vibrator_VibratorManagerService_getManager();
if (manager == nullptr) {
return nullptr;
}

View File

@@ -26,7 +26,7 @@
#include <vibratorservice/VibratorManagerHalController.h>
#include "com_android_server_VibratorManagerService.h"
#include "com_android_server_vibrator_VibratorManagerService.h"
namespace android {
@@ -64,7 +64,7 @@ private:
const jobject mCallbackListener;
};
vibrator::ManagerHalController* android_server_VibratorManagerService_getManager() {
vibrator::ManagerHalController* android_server_vibrator_VibratorManagerService_getManager() {
std::lock_guard<std::mutex> lock(gManagerMutex);
return gManager;
}
@@ -156,10 +156,11 @@ static void nativeCancelSynced(JNIEnv* env, jclass /* clazz */, jlong servicePtr
service->hal()->cancelSynced();
}
inline static constexpr auto sNativeInitMethodSignature =
"(Lcom/android/server/vibrator/VibratorManagerService$OnSyncedVibrationCompleteListener;)J";
static const JNINativeMethod method_table[] = {
{"nativeInit",
"(Lcom/android/server/VibratorManagerService$OnSyncedVibrationCompleteListener;)J",
(void*)nativeInit},
{"nativeInit", sNativeInitMethodSignature, (void*)nativeInit},
{"nativeGetFinalizer", "()J", (void*)nativeGetFinalizer},
{"nativeGetCapabilities", "(J)J", (void*)nativeGetCapabilities},
{"nativeGetVibratorIds", "(J)[I", (void*)nativeGetVibratorIds},
@@ -168,15 +169,15 @@ static const JNINativeMethod method_table[] = {
{"nativeCancelSynced", "(J)V", (void*)nativeCancelSynced},
};
int register_android_server_VibratorManagerService(JavaVM* jvm, JNIEnv* env) {
int register_android_server_vibrator_VibratorManagerService(JavaVM* jvm, JNIEnv* env) {
sJvm = jvm;
auto listenerClassName =
"com/android/server/VibratorManagerService$OnSyncedVibrationCompleteListener";
"com/android/server/vibrator/VibratorManagerService$OnSyncedVibrationCompleteListener";
jclass listenerClass = FindClassOrDie(env, listenerClassName);
sMethodIdOnComplete = GetMethodIDOrDie(env, listenerClass, "onComplete", "(J)V");
return jniRegisterNativeMethods(env, "com/android/server/VibratorManagerService", method_table,
NELEM(method_table));
return jniRegisterNativeMethods(env, "com/android/server/vibrator/VibratorManagerService",
method_table, NELEM(method_table));
}
}; // namespace android

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2021 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.
@@ -21,7 +21,7 @@
namespace android {
extern vibrator::ManagerHalController* android_server_VibratorManagerService_getManager();
extern vibrator::ManagerHalController* android_server_vibrator_VibratorManagerService_getManager();
} // namespace android

View File

@@ -39,7 +39,7 @@ int register_android_server_UsbMidiDevice(JNIEnv* env);
int register_android_server_UsbHostManager(JNIEnv* env);
int register_android_server_vr_VrManagerService(JNIEnv* env);
int register_android_server_vibrator_VibratorController(JavaVM* vm, JNIEnv* env);
int register_android_server_VibratorManagerService(JavaVM* vm, JNIEnv* env);
int register_android_server_vibrator_VibratorManagerService(JavaVM* vm, JNIEnv* env);
int register_android_server_location_GnssLocationProvider(JNIEnv* env);
int register_android_server_devicepolicy_CryptoTestHelper(JNIEnv*);
int register_android_server_tv_TvUinputBridge(JNIEnv* env);
@@ -54,10 +54,8 @@ int register_android_server_net_NetworkStatsService(JNIEnv* env);
int register_android_server_security_VerityUtils(JNIEnv* env);
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
int register_android_server_am_LowMemDetector(JNIEnv* env);
int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(
JNIEnv* env);
int register_com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker(
JNIEnv* env);
int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(JNIEnv* env);
int register_com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker(JNIEnv* env);
int register_android_server_com_android_server_pm_PackageManagerShellCommandDataLoader(JNIEnv* env);
int register_android_server_AdbDebuggingManager(JNIEnv* env);
int register_android_server_FaceService(JNIEnv* env);
@@ -90,7 +88,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_UsbHostManager(env);
register_android_server_vr_VrManagerService(env);
register_android_server_vibrator_VibratorController(vm, env);
register_android_server_VibratorManagerService(vm, env);
register_android_server_vibrator_VibratorManagerService(vm, env);
register_android_server_SystemServer(env);
register_android_server_location_GnssLocationProvider(env);
register_android_server_devicepolicy_CryptoTestHelper(env);
@@ -109,10 +107,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_security_VerityUtils(env);
register_android_server_am_CachedAppOptimizer(env);
register_android_server_am_LowMemDetector(env);
register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(
env);
register_com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker(
env);
register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(env);
register_com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker(env);
register_android_server_com_android_server_pm_PackageManagerShellCommandDataLoader(env);
register_android_server_AdbDebuggingManager(env);
register_android_server_FaceService(env);

View File

@@ -195,6 +195,7 @@ import com.android.server.twilight.TwilightService;
import com.android.server.uri.UriGrantsManagerService;
import com.android.server.usage.UsageStatsService;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.vibrator.VibratorManagerService;
import com.android.server.vr.VrManagerService;
import com.android.server.webkit.WebViewUpdateService;
import com.android.server.wm.ActivityTaskManagerService;

View File

@@ -3,5 +3,4 @@ per-file *AppOp* = file:/core/java/android/permission/OWNERS
per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS
per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS
per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
per-file *Vibrator* = file:/services/core/java/com/android/server/vibrator/OWNERS
per-file GestureLauncherServiceTest.java = file:platform/packages/apps/EmergencyInfo:/OWNERS

View File

@@ -23,7 +23,7 @@ import android.os.Vibrator;
import androidx.annotation.NonNull;
/** Fake implementation of {@link Vibrator} for service tests. */
public final class FakeVibrator extends Vibrator {
final class FakeVibrator extends Vibrator {
private int mDefaultHapticFeedbackIntensity = Vibrator.VIBRATION_INTENSITY_MEDIUM;
private int mDefaultNotificationIntensity = Vibrator.VIBRATION_INTENSITY_MEDIUM;

View File

@@ -33,7 +33,7 @@ import java.util.Map;
* Provides {@link VibratorController} with controlled vibrator hardware capabilities and
* interactions.
*/
public final class FakeVibratorControllerProvider {
final class FakeVibratorControllerProvider {
private static final int EFFECT_DURATION = 20;

View File

@@ -67,9 +67,8 @@ public class InputDeviceDelegateTest {
private static final String REASON = "some reason";
private static final VibrationAttributes VIBRATION_ATTRIBUTES =
new VibrationAttributes.Builder().setUsage(VibrationAttributes.USAGE_ALARM).build();
private static final VibrationEffect EFFECT = VibrationEffect.createOneShot(100, 255);
private static final CombinedVibrationEffect SYNCED_EFFECT =
CombinedVibrationEffect.createSynced(EFFECT);
CombinedVibrationEffect.createSynced(VibrationEffect.createOneShot(100, 255));
@Rule public MockitoRule rule = MockitoJUnit.rule();
@@ -105,6 +104,7 @@ public class InputDeviceDelegateTest {
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ false);
assertFalse(mInputDeviceDelegate.isAvailable());
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
mInputDeviceDelegate.onInputDeviceAdded(1);
@@ -118,6 +118,7 @@ public class InputDeviceDelegateTest {
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
assertFalse(mInputDeviceDelegate.isAvailable());
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[0]);
when(mIInputManagerMock.getInputDevice(eq(1)))
.thenReturn(createInputDeviceWithoutVibrator(1));
updateInputDevices(new int[]{1});
@@ -132,6 +133,7 @@ public class InputDeviceDelegateTest {
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
assertFalse(mInputDeviceDelegate.isAvailable());
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
updateInputDevices(new int[]{1});
@@ -142,6 +144,7 @@ public class InputDeviceDelegateTest {
@Test
public void onInputDeviceChanged_withSettingsDisabled_ignoresDevice() throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ false);
@@ -153,6 +156,7 @@ public class InputDeviceDelegateTest {
@Test
public void onInputDeviceChanged_deviceLosesVibrator_removesDevice() throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1}, new int[0]);
when(mIInputManagerMock.getInputDevice(eq(1)))
.thenReturn(createInputDeviceWithVibrator(1), createInputDeviceWithoutVibrator(1));
@@ -167,6 +171,7 @@ public class InputDeviceDelegateTest {
@Test
public void onInputDeviceChanged_deviceLost_removesDevice() throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1}, new int[0]);
when(mIInputManagerMock.getInputDevice(eq(1)))
.thenReturn(createInputDeviceWithVibrator(1), (InputDevice) null);
@@ -181,6 +186,7 @@ public class InputDeviceDelegateTest {
@Test
public void onInputDeviceChanged_deviceAddsVibrator_addsDevice() throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[0], new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(1)))
.thenReturn(createInputDeviceWithoutVibrator(1), createInputDeviceWithVibrator(1));
@@ -195,8 +201,10 @@ public class InputDeviceDelegateTest {
@Test
public void onInputDeviceRemoved_removesDevice() throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[0]);
when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(
createInputDeviceWithoutVibrator(1));
when(mIInputManagerMock.getVibratorIds(eq(2))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2));
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
@@ -209,7 +217,9 @@ public class InputDeviceDelegateTest {
@Test
public void updateInputDeviceVibrators_usesFlagToLoadDeviceList() throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
when(mIInputManagerMock.getVibratorIds(eq(2))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2));
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
@@ -223,6 +233,7 @@ public class InputDeviceDelegateTest {
public void updateInputDeviceVibrators_withDeviceWithoutVibrator_deviceIsIgnored()
throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[0]);
when(mIInputManagerMock.getInputDevice(eq(1)))
.thenReturn(createInputDeviceWithoutVibrator(1));
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
@@ -240,14 +251,16 @@ public class InputDeviceDelegateTest {
public void vibrateIfAvailable_withInputDevices_returnsTrueAndVibratesAllDevices()
throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
when(mIInputManagerMock.getVibratorIds(eq(2))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2));
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
assertTrue(mInputDeviceDelegate.vibrateIfAvailable(
UID, PACKAGE_NAME, SYNCED_EFFECT, REASON, VIBRATION_ATTRIBUTES));
verify(mIInputManagerMock).vibrate(eq(1), same(EFFECT), any());
verify(mIInputManagerMock).vibrate(eq(2), same(EFFECT), any());
verify(mIInputManagerMock).vibrateCombined(eq(1), same(SYNCED_EFFECT), any());
verify(mIInputManagerMock).vibrateCombined(eq(2), same(SYNCED_EFFECT), any());
}
@Test
@@ -261,7 +274,9 @@ public class InputDeviceDelegateTest {
public void cancelVibrateIfAvailable_withInputDevices_returnsTrueAndStopsAllDevices()
throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
when(mIInputManagerMock.getVibratorIds(eq(2))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2));
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);

View File

@@ -40,6 +40,7 @@ import android.os.SystemClock;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.os.test.TestLooper;
import android.platform.test.annotations.LargeTest;
import android.platform.test.annotations.Presubmit;
import android.util.SparseArray;
@@ -709,6 +710,7 @@ public class VibrationThreadTest {
assertEquals(Arrays.asList(6), mVibratorProviders.get(3).getAmplitudes());
}
@LargeTest
@Test
public void vibrate_withWaveform_totalVibrationTimeRespected() {
int totalDuration = 10_000; // 10s

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 The Android Open Source Project
* Copyright (C) 2021 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.server;
package com.android.server.vibrator;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -73,9 +73,7 @@ import androidx.test.InstrumentationRegistry;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
import com.android.server.vibrator.FakeVibrator;
import com.android.server.vibrator.FakeVibratorControllerProvider;
import com.android.server.vibrator.VibratorController;
import com.android.server.LocalServices;
import org.junit.After;
import org.junit.Before;
@@ -533,28 +531,15 @@ public class VibratorManagerServiceTest {
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
VibratorManagerService service = createService();
// Prebaked vibration will play fallback waveform on input device.
ArgumentCaptor<VibrationEffect> captor = ArgumentCaptor.forClass(VibrationEffect.class);
vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS);
verify(mIInputManagerMock).vibrate(eq(1), captor.capture(), any());
assertTrue(captor.getValue() instanceof VibrationEffect.Waveform);
VibrationEffect[] effects = new VibrationEffect[]{
VibrationEffect.createOneShot(100, 128),
VibrationEffect.createWaveform(new long[]{10}, new int[]{100}, -1),
VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
.compose(),
};
for (VibrationEffect effect : effects) {
vibrate(service, effect, ALARM_ATTRS);
verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any());
}
CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
VibrationEffect.createOneShot(10, 10));
vibrate(service, effect, ALARM_ATTRS);
verify(mIInputManagerMock).vibrateCombined(eq(1), eq(effect), any());
// VibrationThread will start this vibration async, so wait before checking it never played.
assertFalse(waitUntil(s -> !mVibratorProviders.get(1).getEffects().isEmpty(),