Add CallerInfo to Vibration class.
Bug: 265265232 Test: com.android.server.vibrator.VibratorSettingsTest Change-Id: I077ebf18e494ab0b913ebac64bab36bba4b7baca
This commit is contained in:
@@ -104,6 +104,10 @@ public class ExternalVibration implements Parcelable {
|
||||
return mAttrs;
|
||||
}
|
||||
|
||||
public IBinder getToken() {
|
||||
return mToken;
|
||||
}
|
||||
|
||||
public VibrationAttributes getVibrationAttributes() {
|
||||
return new VibrationAttributes.Builder(mAttrs).build();
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ abstract class AbstractVibratorStep extends Step {
|
||||
"Turning off vibrator " + getVibratorId());
|
||||
}
|
||||
controller.off();
|
||||
getVibration().stats().reportVibratorOff();
|
||||
getVibration().stats.reportVibratorOff();
|
||||
mPendingVibratorOffDeadline = 0;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ abstract class AbstractVibratorStep extends Step {
|
||||
"Amplitude changed on vibrator " + getVibratorId() + " to " + amplitude);
|
||||
}
|
||||
controller.setAmplitude(amplitude);
|
||||
getVibration().stats().reportSetAmplitude();
|
||||
getVibration().stats.reportSetAmplitude();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +170,7 @@ abstract class AbstractVibratorStep extends Step {
|
||||
// Count the loops that were played.
|
||||
int loopSize = effectSize - repeatIndex;
|
||||
int loopSegmentsPlayed = nextSegmentIndex - repeatIndex;
|
||||
getVibration().stats().reportRepetition(loopSegmentsPlayed / loopSize);
|
||||
getVibration().stats.reportRepetition(loopSegmentsPlayed / loopSize);
|
||||
nextSegmentIndex = repeatIndex + ((nextSegmentIndex - effectSize) % loopSize);
|
||||
}
|
||||
Step nextStep = conductor.nextVibrateStep(nextStartTime, controller, effect,
|
||||
|
||||
@@ -73,7 +73,7 @@ final class ComposePrimitivesVibratorStep extends AbstractVibratorStep {
|
||||
primitives.toArray(new PrimitiveSegment[primitives.size()]);
|
||||
long vibratorOnResult = controller.on(primitivesArray, getVibration().id);
|
||||
handleVibratorOnResult(vibratorOnResult);
|
||||
getVibration().stats().reportComposePrimitives(vibratorOnResult, primitivesArray);
|
||||
getVibration().stats.reportComposePrimitives(vibratorOnResult, primitivesArray);
|
||||
|
||||
// The next start and off times will be calculated from mVibratorOnResult.
|
||||
return nextSteps(/* segmentsPlayed= */ primitives.size());
|
||||
|
||||
@@ -72,7 +72,7 @@ final class ComposePwleVibratorStep extends AbstractVibratorStep {
|
||||
RampSegment[] pwlesArray = pwles.toArray(new RampSegment[pwles.size()]);
|
||||
long vibratorOnResult = controller.on(pwlesArray, getVibration().id);
|
||||
handleVibratorOnResult(vibratorOnResult);
|
||||
getVibration().stats().reportComposePwle(vibratorOnResult, pwlesArray);
|
||||
getVibration().stats.reportComposePwle(vibratorOnResult, pwlesArray);
|
||||
|
||||
// The next start and off times will be calculated from mVibratorOnResult.
|
||||
return nextSteps(/* segmentsPlayed= */ pwles.size());
|
||||
|
||||
@@ -51,7 +51,8 @@ final class FinishSequentialEffectStep extends Step {
|
||||
Slog.d(VibrationThread.TAG,
|
||||
"FinishSequentialEffectStep for effect #" + startedStep.currentIndex);
|
||||
}
|
||||
conductor.vibratorManagerHooks.noteVibratorOff(conductor.getVibration().uid);
|
||||
conductor.vibratorManagerHooks.noteVibratorOff(
|
||||
conductor.getVibration().callerInfo.uid);
|
||||
Step nextStep = startedStep.nextStep();
|
||||
return nextStep == null ? VibrationStepConductor.EMPTY_STEP_LIST
|
||||
: Arrays.asList(nextStep);
|
||||
@@ -68,6 +69,7 @@ final class FinishSequentialEffectStep extends Step {
|
||||
|
||||
@Override
|
||||
public void cancelImmediately() {
|
||||
conductor.vibratorManagerHooks.noteVibratorOff(conductor.getVibration().uid);
|
||||
conductor.vibratorManagerHooks.noteVibratorOff(
|
||||
conductor.getVibration().callerInfo.uid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.vibrator;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.CombinedVibration;
|
||||
import android.os.IBinder;
|
||||
@@ -35,13 +36,6 @@ import java.util.function.Function;
|
||||
*/
|
||||
final class HalVibration extends Vibration {
|
||||
|
||||
public final VibrationAttributes attrs;
|
||||
public final long id;
|
||||
public final int uid;
|
||||
public final int displayId;
|
||||
public final String opPkg;
|
||||
public final String reason;
|
||||
public final IBinder token;
|
||||
public final SparseArray<VibrationEffect> mFallbacks = new SparseArray<>();
|
||||
|
||||
/** The actual effect to be played. */
|
||||
@@ -58,29 +52,15 @@ final class HalVibration extends Vibration {
|
||||
/** Vibration status. */
|
||||
private Vibration.Status mStatus;
|
||||
|
||||
/** Vibration runtime stats. */
|
||||
private final VibrationStats mStats = new VibrationStats();
|
||||
|
||||
/** A {@link CountDownLatch} to enable waiting for completion. */
|
||||
private final CountDownLatch mCompletionLatch = new CountDownLatch(1);
|
||||
|
||||
HalVibration(IBinder token, int id, CombinedVibration effect,
|
||||
VibrationAttributes attrs, int uid, int displayId, String opPkg, String reason) {
|
||||
this.token = token;
|
||||
HalVibration(@NonNull IBinder token, CombinedVibration effect, @NonNull CallerInfo callerInfo) {
|
||||
super(token, callerInfo);
|
||||
this.mEffect = effect;
|
||||
this.id = id;
|
||||
this.attrs = attrs;
|
||||
this.uid = uid;
|
||||
this.displayId = displayId;
|
||||
this.opPkg = opPkg;
|
||||
this.reason = reason;
|
||||
mStatus = Vibration.Status.RUNNING;
|
||||
}
|
||||
|
||||
VibrationStats stats() {
|
||||
return mStats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link Status} of this vibration and reports the current system time as this
|
||||
* vibration end time, for debugging purposes.
|
||||
@@ -94,7 +74,7 @@ final class HalVibration extends Vibration {
|
||||
return;
|
||||
}
|
||||
mStatus = info.status;
|
||||
mStats.reportEnded(info.endedByUid, info.endedByUsage);
|
||||
stats.reportEnded(info.endedBy);
|
||||
mCompletionLatch.countDown();
|
||||
}
|
||||
|
||||
@@ -190,8 +170,8 @@ final class HalVibration extends Vibration {
|
||||
* Return {@link Vibration.DebugInfo} with read-only debug information about this vibration.
|
||||
*/
|
||||
public Vibration.DebugInfo getDebugInfo() {
|
||||
return new Vibration.DebugInfo(mStatus, mStats, mEffect, mOriginalEffect, /* scale= */ 0,
|
||||
attrs, uid, displayId, opPkg, reason);
|
||||
return new Vibration.DebugInfo(mStatus, stats, mEffect, mOriginalEffect, /* scale= */ 0,
|
||||
callerInfo);
|
||||
}
|
||||
|
||||
/** Return {@link VibrationStats.StatsInfo} with read-only metrics about this vibration. */
|
||||
@@ -200,7 +180,8 @@ final class HalVibration extends Vibration {
|
||||
? FrameworkStatsLog.VIBRATION_REPORTED__VIBRATION_TYPE__REPEATED
|
||||
: FrameworkStatsLog.VIBRATION_REPORTED__VIBRATION_TYPE__SINGLE;
|
||||
return new VibrationStats.StatsInfo(
|
||||
uid, vibrationType, attrs.getUsage(), mStatus, mStats, completionUptimeMillis);
|
||||
callerInfo.uid, vibrationType, callerInfo.attrs.getUsage(), mStatus,
|
||||
stats, completionUptimeMillis);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,8 +193,9 @@ final class HalVibration extends Vibration {
|
||||
* pipeline very short vibrations together, regardless of the flag.
|
||||
*/
|
||||
public boolean canPipelineWith(HalVibration vib) {
|
||||
return uid == vib.uid && attrs.isFlagSet(VibrationAttributes.FLAG_PIPELINED_EFFECT)
|
||||
&& vib.attrs.isFlagSet(VibrationAttributes.FLAG_PIPELINED_EFFECT)
|
||||
return callerInfo.uid == vib.callerInfo.uid && callerInfo.attrs.isFlagSet(
|
||||
VibrationAttributes.FLAG_PIPELINED_EFFECT)
|
||||
&& vib.callerInfo.attrs.isFlagSet(VibrationAttributes.FLAG_PIPELINED_EFFECT)
|
||||
&& !isRepeating();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.content.Context;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.os.CombinedVibration;
|
||||
import android.os.Handler;
|
||||
import android.os.VibrationAttributes;
|
||||
import android.os.VibratorManager;
|
||||
import android.util.SparseArray;
|
||||
import android.view.InputDevice;
|
||||
@@ -94,11 +93,11 @@ final class InputDeviceDelegate implements InputManager.InputDeviceListener {
|
||||
*
|
||||
* @return {@link #isAvailable()}
|
||||
*/
|
||||
public boolean vibrateIfAvailable(int uid, String opPkg, CombinedVibration effect,
|
||||
String reason, VibrationAttributes attrs) {
|
||||
public boolean vibrateIfAvailable(Vibration.CallerInfo callerInfo, CombinedVibration effect) {
|
||||
synchronized (mLock) {
|
||||
for (int i = 0; i < mInputDeviceVibrators.size(); i++) {
|
||||
mInputDeviceVibrators.valueAt(i).vibrate(uid, opPkg, effect, reason, attrs);
|
||||
mInputDeviceVibrators.valueAt(i).vibrate(callerInfo.uid, callerInfo.opPkg, effect,
|
||||
callerInfo.reason, callerInfo.attrs);
|
||||
}
|
||||
return mInputDeviceVibrators.size() > 0;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ final class PerformPrebakedVibratorStep extends AbstractVibratorStep {
|
||||
VibrationEffect fallback = getVibration().getFallback(prebaked.getEffectId());
|
||||
long vibratorOnResult = controller.on(prebaked, getVibration().id);
|
||||
handleVibratorOnResult(vibratorOnResult);
|
||||
getVibration().stats().reportPerformEffect(vibratorOnResult, prebaked);
|
||||
getVibration().stats.reportPerformEffect(vibratorOnResult, prebaked);
|
||||
|
||||
if (vibratorOnResult == 0 && prebaked.shouldFallback()
|
||||
&& (fallback instanceof VibrationEffect.Composed)) {
|
||||
|
||||
@@ -161,7 +161,7 @@ final class SetAmplitudeVibratorStep extends AbstractVibratorStep {
|
||||
}
|
||||
long vibratorOnResult = controller.on(duration, getVibration().id);
|
||||
handleVibratorOnResult(vibratorOnResult);
|
||||
getVibration().stats().reportVibratorOn(vibratorOnResult);
|
||||
getVibration().stats.reportVibratorOn(vibratorOnResult);
|
||||
return vibratorOnResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,8 +93,8 @@ final class StartSequentialEffectStep extends Step {
|
||||
}
|
||||
|
||||
mVibratorsOnMaxDuration = startVibrating(effectMapping, nextSteps);
|
||||
conductor.vibratorManagerHooks.noteVibratorOn(conductor.getVibration().uid,
|
||||
mVibratorsOnMaxDuration);
|
||||
conductor.vibratorManagerHooks.noteVibratorOn(
|
||||
conductor.getVibration().callerInfo.uid, mVibratorsOnMaxDuration);
|
||||
} finally {
|
||||
if (mVibratorsOnMaxDuration >= 0) {
|
||||
// It least one vibrator was started then add a finish step to wait for all
|
||||
@@ -211,7 +211,8 @@ final class StartSequentialEffectStep extends Step {
|
||||
// Check if sync was prepared and if any step was accepted by a vibrator,
|
||||
// otherwise there is nothing to trigger here.
|
||||
if (hasPrepared && !hasFailed && maxDuration > 0) {
|
||||
hasTriggered = conductor.vibratorManagerHooks.triggerSyncedVibration(getVibration().id);
|
||||
hasTriggered = conductor.vibratorManagerHooks.triggerSyncedVibration(
|
||||
getVibration().id);
|
||||
hasFailed &= hasTriggered;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.vibrator;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.CombinedVibration;
|
||||
import android.os.IBinder;
|
||||
import android.os.VibrationAttributes;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.vibrator.PrebakedSegment;
|
||||
@@ -31,6 +32,7 @@ import android.util.proto.ProtoOutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* The base class for all vibrations.
|
||||
@@ -38,6 +40,13 @@ import java.util.Objects;
|
||||
class Vibration {
|
||||
private static final SimpleDateFormat DEBUG_DATE_FORMAT =
|
||||
new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
|
||||
// Used to generate globally unique vibration ids.
|
||||
private static final AtomicInteger sNextVibrationId = new AtomicInteger(1); // 0 = no callback
|
||||
|
||||
public final long id;
|
||||
public final CallerInfo callerInfo;
|
||||
public final VibrationStats stats = new VibrationStats();
|
||||
public final IBinder callerToken;
|
||||
|
||||
/** Vibration status with reference to values from vibratormanagerservice.proto for logging. */
|
||||
enum Status {
|
||||
@@ -80,24 +89,82 @@ class Vibration {
|
||||
}
|
||||
}
|
||||
|
||||
Vibration(@NonNull IBinder token, @NonNull CallerInfo callerInfo) {
|
||||
Objects.requireNonNull(token);
|
||||
Objects.requireNonNull(callerInfo);
|
||||
this.id = sNextVibrationId.getAndIncrement();
|
||||
this.callerToken = token;
|
||||
this.callerInfo = callerInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds lightweight immutable info on the process that triggered the vibration. This data
|
||||
* could potentially be kept in memory for a long time for bugreport dumpsys operations.
|
||||
*
|
||||
* Since CallerInfo can be kept in memory for a long time, it shouldn't hold any references to
|
||||
* potentially expensive or resource-linked objects, such as {@link IBinder}.
|
||||
*/
|
||||
static final class CallerInfo {
|
||||
public final VibrationAttributes attrs;
|
||||
public final int uid;
|
||||
public final int displayId;
|
||||
public final String opPkg;
|
||||
public final String reason;
|
||||
|
||||
CallerInfo(@NonNull VibrationAttributes attrs, int uid, int displayId,
|
||||
String opPkg, String reason) {
|
||||
Objects.requireNonNull(attrs);
|
||||
this.attrs = attrs;
|
||||
this.uid = uid;
|
||||
this.displayId = displayId;
|
||||
this.opPkg = opPkg;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof CallerInfo)) return false;
|
||||
CallerInfo that = (CallerInfo) o;
|
||||
return Objects.equals(attrs, that.attrs)
|
||||
&& uid == that.uid
|
||||
&& displayId == that.displayId
|
||||
&& Objects.equals(opPkg, that.opPkg)
|
||||
&& Objects.equals(reason, that.reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(attrs, uid, displayId, opPkg, reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CallerInfo{"
|
||||
+ " attrs=" + attrs
|
||||
+ ", uid=" + uid
|
||||
+ ", displayId=" + displayId
|
||||
+ ", opPkg=" + opPkg
|
||||
+ ", reason=" + reason
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
/** Immutable info passed as a signal to end a vibration. */
|
||||
static final class EndInfo {
|
||||
/** The {@link Status} to be set to the vibration when it ends with this info. */
|
||||
@NonNull
|
||||
public final Status status;
|
||||
/** The UID that triggered the vibration that ended this, or -1 if undefined. */
|
||||
public final int endedByUid;
|
||||
/** The VibrationAttributes.USAGE_* of the vibration that ended this, or -1 if undefined. */
|
||||
public final int endedByUsage;
|
||||
/** Info about the process that ended the vibration. */
|
||||
public final CallerInfo endedBy;
|
||||
|
||||
EndInfo(@NonNull Vibration.Status status) {
|
||||
this(status, /* endedByUid= */ -1, /* endedByUsage= */ -1);
|
||||
this(status, null);
|
||||
}
|
||||
|
||||
EndInfo(@NonNull Vibration.Status status, int endedByUid, int endedByUsage) {
|
||||
EndInfo(@NonNull Vibration.Status status, @Nullable CallerInfo endedBy) {
|
||||
this.status = status;
|
||||
this.endedByUid = endedByUid;
|
||||
this.endedByUsage = endedByUsage;
|
||||
this.endedBy = endedBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,27 +172,31 @@ class Vibration {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof EndInfo)) return false;
|
||||
EndInfo that = (EndInfo) o;
|
||||
return endedByUid == that.endedByUid
|
||||
&& endedByUsage == that.endedByUsage
|
||||
return Objects.equals(endedBy, that.endedBy)
|
||||
&& status == that.status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(status, endedByUid, endedByUsage);
|
||||
return Objects.hash(status, endedBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EndInfo{"
|
||||
+ "status=" + status
|
||||
+ ", endedByUid=" + endedByUid
|
||||
+ ", endedByUsage=" + endedByUsage
|
||||
+ ", endedBy=" + endedBy
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
/** Debug information about vibrations. */
|
||||
/**
|
||||
* Holds lightweight debug information about the vibration that could potentially be kept in
|
||||
* memory for a long time for bugreport dumpsys operations.
|
||||
*
|
||||
* Since DebugInfo can be kept in memory for a long time, it shouldn't hold any references to
|
||||
* potentially expensive or resource-linked objects, such as {@link IBinder}.
|
||||
*/
|
||||
static final class DebugInfo {
|
||||
private final long mCreateTime;
|
||||
private final long mStartTime;
|
||||
@@ -134,16 +205,13 @@ class Vibration {
|
||||
private final CombinedVibration mEffect;
|
||||
private final CombinedVibration mOriginalEffect;
|
||||
private final float mScale;
|
||||
private final VibrationAttributes mAttrs;
|
||||
private final int mUid;
|
||||
private final int mDisplayId;
|
||||
private final String mOpPkg;
|
||||
private final String mReason;
|
||||
private final CallerInfo mCallerInfo;
|
||||
private final Status mStatus;
|
||||
|
||||
DebugInfo(Status status, VibrationStats stats, @Nullable CombinedVibration effect,
|
||||
@Nullable CombinedVibration originalEffect, float scale, VibrationAttributes attrs,
|
||||
int uid, int displayId, String opPkg, String reason) {
|
||||
@Nullable CombinedVibration originalEffect, float scale,
|
||||
@NonNull CallerInfo callerInfo) {
|
||||
Objects.requireNonNull(callerInfo);
|
||||
mCreateTime = stats.getCreateTimeDebug();
|
||||
mStartTime = stats.getStartTimeDebug();
|
||||
mEndTime = stats.getEndTimeDebug();
|
||||
@@ -151,11 +219,7 @@ class Vibration {
|
||||
mEffect = effect;
|
||||
mOriginalEffect = originalEffect;
|
||||
mScale = scale;
|
||||
mAttrs = attrs;
|
||||
mUid = uid;
|
||||
mDisplayId = displayId;
|
||||
mOpPkg = opPkg;
|
||||
mReason = reason;
|
||||
mCallerInfo = callerInfo;
|
||||
mStatus = status;
|
||||
}
|
||||
|
||||
@@ -179,16 +243,8 @@ class Vibration {
|
||||
.append(mOriginalEffect)
|
||||
.append(", scale: ")
|
||||
.append(String.format("%.2f", mScale))
|
||||
.append(", attrs: ")
|
||||
.append(mAttrs)
|
||||
.append(", uid: ")
|
||||
.append(mUid)
|
||||
.append(", displayId: ")
|
||||
.append(mDisplayId)
|
||||
.append(", opPkg: ")
|
||||
.append(mOpPkg)
|
||||
.append(", reason: ")
|
||||
.append(mReason)
|
||||
.append(", callerInfo: ")
|
||||
.append(mCallerInfo)
|
||||
.toString();
|
||||
}
|
||||
|
||||
@@ -201,9 +257,10 @@ class Vibration {
|
||||
proto.write(VibrationProto.STATUS, mStatus.ordinal());
|
||||
|
||||
final long attrsToken = proto.start(VibrationProto.ATTRIBUTES);
|
||||
proto.write(VibrationAttributesProto.USAGE, mAttrs.getUsage());
|
||||
proto.write(VibrationAttributesProto.AUDIO_USAGE, mAttrs.getAudioUsage());
|
||||
proto.write(VibrationAttributesProto.FLAGS, mAttrs.getFlags());
|
||||
final VibrationAttributes attrs = mCallerInfo.attrs;
|
||||
proto.write(VibrationAttributesProto.USAGE, attrs.getUsage());
|
||||
proto.write(VibrationAttributesProto.AUDIO_USAGE, attrs.getAudioUsage());
|
||||
proto.write(VibrationAttributesProto.FLAGS, attrs.getFlags());
|
||||
proto.end(attrsToken);
|
||||
|
||||
if (mEffect != null) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import static android.os.VibrationAttributes.USAGE_RINGTONE;
|
||||
import static android.os.VibrationAttributes.USAGE_TOUCH;
|
||||
import static android.os.VibrationAttributes.USAGE_UNKNOWN;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.IUidObserver;
|
||||
@@ -375,15 +376,15 @@ final class VibrationSettings {
|
||||
* null otherwise.
|
||||
*/
|
||||
@Nullable
|
||||
public Vibration.Status shouldIgnoreVibration(int uid, int displayId,
|
||||
VibrationAttributes attrs) {
|
||||
final int usage = attrs.getUsage();
|
||||
public Vibration.Status shouldIgnoreVibration(@NonNull Vibration.CallerInfo callerInfo) {
|
||||
final int usage = callerInfo.attrs.getUsage();
|
||||
synchronized (mLock) {
|
||||
if (!mUidObserver.isUidForeground(uid)
|
||||
if (!mUidObserver.isUidForeground(callerInfo.uid)
|
||||
&& !BACKGROUND_PROCESS_USAGE_ALLOWLIST.contains(usage)) {
|
||||
return Vibration.Status.IGNORED_BACKGROUND;
|
||||
}
|
||||
if (mVirtualDeviceListener.isAppOrDisplayOnAnyVirtualDevice(uid, displayId)) {
|
||||
if (mVirtualDeviceListener.isAppOrDisplayOnAnyVirtualDevice(callerInfo.uid,
|
||||
callerInfo.displayId)) {
|
||||
return Vibration.Status.IGNORED_FROM_VIRTUAL_DEVICE;
|
||||
}
|
||||
|
||||
@@ -391,7 +392,8 @@ final class VibrationSettings {
|
||||
return Vibration.Status.IGNORED_FOR_POWER;
|
||||
}
|
||||
|
||||
if (!attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)) {
|
||||
if (!callerInfo.attrs.isFlagSet(
|
||||
VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)) {
|
||||
if (!mVibrateOn && (VIBRATE_ON_DISABLED_USAGE_ALLOWED != usage)) {
|
||||
return Vibration.Status.IGNORED_FOR_SETTINGS;
|
||||
}
|
||||
@@ -401,7 +403,7 @@ final class VibrationSettings {
|
||||
}
|
||||
}
|
||||
|
||||
if (!attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)) {
|
||||
if (!callerInfo.attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)) {
|
||||
if (!shouldVibrateForRingerModeLocked(usage)) {
|
||||
return Vibration.Status.IGNORED_FOR_RINGER_MODE;
|
||||
}
|
||||
@@ -420,8 +422,8 @@ final class VibrationSettings {
|
||||
*
|
||||
* @return true if the vibration should be cancelled when the screen goes off, false otherwise.
|
||||
*/
|
||||
public boolean shouldCancelVibrationOnScreenOff(int uid, String opPkg,
|
||||
@VibrationAttributes.Usage int usage, long vibrationStartUptimeMillis) {
|
||||
public boolean shouldCancelVibrationOnScreenOff(@NonNull Vibration.CallerInfo callerInfo,
|
||||
long vibrationStartUptimeMillis) {
|
||||
PowerManagerInternal pm;
|
||||
synchronized (mLock) {
|
||||
pm = mPowerManagerInternal;
|
||||
@@ -442,12 +444,13 @@ final class VibrationSettings {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!SYSTEM_VIBRATION_SCREEN_OFF_USAGE_ALLOWLIST.contains(usage)) {
|
||||
if (!SYSTEM_VIBRATION_SCREEN_OFF_USAGE_ALLOWLIST.contains(callerInfo.attrs.getUsage())) {
|
||||
// Usages not allowed even for system vibrations should always be cancelled.
|
||||
return true;
|
||||
}
|
||||
// Only allow vibrations from System packages to continue vibrating when the screen goes off
|
||||
return uid != Process.SYSTEM_UID && uid != 0 && !mSystemUiPackage.equals(opPkg);
|
||||
return callerInfo.uid != Process.SYSTEM_UID && callerInfo.uid != 0
|
||||
&& !mSystemUiPackage.equals(callerInfo.opPkg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.vibrator;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.SystemClock;
|
||||
import android.os.vibrator.PrebakedSegment;
|
||||
import android.os.vibrator.PrimitiveSegment;
|
||||
@@ -159,15 +161,18 @@ final class VibrationStats {
|
||||
* @return true if the status was accepted. This method will only accept given values if
|
||||
* the end timestamp was never set.
|
||||
*/
|
||||
boolean reportEnded(int endedByUid, int endedByUsage) {
|
||||
boolean reportEnded(@Nullable Vibration.CallerInfo endedBy) {
|
||||
if (hasEnded()) {
|
||||
// Vibration already ended, keep first ending stats set and ignore this one.
|
||||
return false;
|
||||
}
|
||||
mEndedByUid = endedByUid;
|
||||
mEndedByUsage = endedByUsage;
|
||||
if (endedBy != null) {
|
||||
mEndedByUid = endedBy.uid;
|
||||
mEndedByUsage = endedBy.attrs.getUsage();
|
||||
}
|
||||
mEndUptimeMillis = SystemClock.uptimeMillis();
|
||||
mEndTimeDebug = System.currentTimeMillis();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -177,9 +182,9 @@ final class VibrationStats {
|
||||
* <p>This method will only accept the first value as the one that was interrupted by this
|
||||
* vibration, and will ignore all successive calls.
|
||||
*/
|
||||
void reportInterruptedAnotherVibration(int interruptedUsage) {
|
||||
void reportInterruptedAnotherVibration(@NonNull Vibration.CallerInfo callerInfo) {
|
||||
if (mInterruptedUsage < 0) {
|
||||
mInterruptedUsage = interruptedUsage;
|
||||
mInterruptedUsage = callerInfo.attrs.getUsage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
|
||||
mNextSteps.offer(new StartSequentialEffectStep(this, sequentialEffect));
|
||||
// Vibration will start playing in the Vibrator, following the effect timings and delays.
|
||||
// Report current time as the vibration start time, for debugging.
|
||||
mVibration.stats().reportStarted();
|
||||
mVibration.stats.reportStarted();
|
||||
}
|
||||
|
||||
public HalVibration getVibration() {
|
||||
|
||||
@@ -161,7 +161,8 @@ final class VibrationThread extends Thread {
|
||||
// for this thread.
|
||||
// No point doing this in finally, as if there's an exception, this thread will die
|
||||
// and be unusable anyway.
|
||||
mVibratorManagerHooks.onVibrationThreadReleased(mExecutingConductor.getVibration().id);
|
||||
mVibratorManagerHooks.onVibrationThreadReleased(
|
||||
mExecutingConductor.getVibration().id);
|
||||
synchronized (mLock) {
|
||||
mLock.notifyAll();
|
||||
}
|
||||
@@ -230,7 +231,8 @@ final class VibrationThread extends Thread {
|
||||
|
||||
/** Runs the VibrationThread ensuring that the wake lock is acquired and released. */
|
||||
private void runCurrentVibrationWithWakeLock() {
|
||||
WorkSource workSource = new WorkSource(mExecutingConductor.getVibration().uid);
|
||||
WorkSource workSource = new WorkSource(
|
||||
mExecutingConductor.getVibration().callerInfo.uid);
|
||||
mWakeLock.setWorkSource(workSource);
|
||||
mWakeLock.acquire();
|
||||
try {
|
||||
@@ -251,7 +253,7 @@ final class VibrationThread extends Thread {
|
||||
* Called from within runWithWakeLock.
|
||||
*/
|
||||
private void runCurrentVibrationWithWakeLockAndDeathLink() {
|
||||
IBinder vibrationBinderToken = mExecutingConductor.getVibration().token;
|
||||
IBinder vibrationBinderToken = mExecutingConductor.getVibration().callerToken;
|
||||
try {
|
||||
vibrationBinderToken.linkToDeath(mExecutingConductor, 0);
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -77,7 +77,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -123,9 +122,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
// Used to generate globally unique vibration ids.
|
||||
private final AtomicInteger mNextVibrationId = new AtomicInteger(1); // 0 = no callback
|
||||
|
||||
private final Object mLock = new Object();
|
||||
private final Context mContext;
|
||||
private final PowerManager.WakeLock mWakeLock;
|
||||
@@ -367,8 +363,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
// missing on individual vibrators.
|
||||
return false;
|
||||
}
|
||||
AlwaysOnVibration alwaysOnVibration = new AlwaysOnVibration(
|
||||
alwaysOnId, uid, opPkg, attrs, effects);
|
||||
AlwaysOnVibration alwaysOnVibration = new AlwaysOnVibration(alwaysOnId,
|
||||
new Vibration.CallerInfo(attrs, uid, Display.DEFAULT_DISPLAY, opPkg,
|
||||
null), effects);
|
||||
mAlwaysOnEffects.put(alwaysOnId, alwaysOnVibration);
|
||||
updateAlwaysOnLocked(alwaysOnVibration);
|
||||
}
|
||||
@@ -408,8 +405,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
attrs = fixupVibrationAttributes(attrs, effect);
|
||||
// Create Vibration.Stats as close to the received request as possible, for tracking.
|
||||
HalVibration vib = new HalVibration(token, mNextVibrationId.getAndIncrement(), effect,
|
||||
attrs, uid, displayId, opPkg, reason);
|
||||
HalVibration vib = new HalVibration(token, effect,
|
||||
new Vibration.CallerInfo(attrs, uid, displayId, opPkg, reason));
|
||||
fillVibrationFallbacks(vib, effect);
|
||||
|
||||
if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
|
||||
@@ -422,27 +419,23 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Starting vibrate for vibration " + vib.id);
|
||||
}
|
||||
int ignoredByUid = -1;
|
||||
int ignoredByUsage = -1;
|
||||
Vibration.Status status = null;
|
||||
Vibration.CallerInfo ignoredByCallerInfo = null;
|
||||
Vibration.Status status;
|
||||
|
||||
// Check if user settings or DnD is set to ignore this vibration.
|
||||
status = shouldIgnoreVibrationLocked(vib.uid, vib.displayId, vib.opPkg, vib.attrs);
|
||||
status = shouldIgnoreVibrationLocked(vib.callerInfo);
|
||||
|
||||
// Check if something has external control, assume it's more important.
|
||||
if ((status == null) && (mCurrentExternalVibration != null)) {
|
||||
status = Vibration.Status.IGNORED_FOR_EXTERNAL;
|
||||
ignoredByUid = mCurrentExternalVibration.externalVibration.getUid();
|
||||
ignoredByUsage = mCurrentExternalVibration.externalVibration
|
||||
.getVibrationAttributes().getUsage();
|
||||
ignoredByCallerInfo = mCurrentExternalVibration.callerInfo;
|
||||
}
|
||||
|
||||
// Check if ongoing vibration is more important than this vibration.
|
||||
if (status == null) {
|
||||
status = shouldIgnoreVibrationForOngoingLocked(vib);
|
||||
if (status != null) {
|
||||
ignoredByUid = mCurrentVibration.getVibration().uid;
|
||||
ignoredByUsage = mCurrentVibration.getVibration().attrs.getUsage();
|
||||
ignoredByCallerInfo = mCurrentVibration.getVibration().callerInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,12 +453,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
Slog.d(TAG, "Pipelining vibration " + vib.id);
|
||||
}
|
||||
} else {
|
||||
vib.stats().reportInterruptedAnotherVibration(
|
||||
mCurrentVibration.getVibration().attrs.getUsage());
|
||||
vib.stats.reportInterruptedAnotherVibration(
|
||||
mCurrentVibration.getVibration().callerInfo);
|
||||
mCurrentVibration.notifyCancelled(
|
||||
new Vibration.EndInfo(
|
||||
Vibration.Status.CANCELLED_SUPERSEDED, vib.uid,
|
||||
vib.attrs.getUsage()),
|
||||
new Vibration.EndInfo(Vibration.Status.CANCELLED_SUPERSEDED,
|
||||
vib.callerInfo),
|
||||
/* immediate= */ false);
|
||||
}
|
||||
}
|
||||
@@ -478,7 +470,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
// Ignored or failed to start the vibration, end it and report metrics right away.
|
||||
if (status != Vibration.Status.RUNNING) {
|
||||
endVibrationLocked(vib,
|
||||
new Vibration.EndInfo(status, ignoredByUid, ignoredByUsage),
|
||||
new Vibration.EndInfo(status, ignoredByCallerInfo),
|
||||
/* shouldWriteStats= */ true);
|
||||
}
|
||||
return vib;
|
||||
@@ -641,8 +633,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
|
||||
HalVibration vib = mCurrentVibration.getVibration();
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
||||
vib.uid, vib.displayId, vib.opPkg, vib.attrs);
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(vib.callerInfo);
|
||||
|
||||
if (inputDevicesChanged || (ignoreStatus != null)) {
|
||||
if (DEBUG) {
|
||||
@@ -671,10 +662,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
if (vibrator == null) {
|
||||
continue;
|
||||
}
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
||||
vib.uid, Display.DEFAULT_DISPLAY, vib.opPkg, vib.attrs);
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(vib.callerInfo);
|
||||
if (ignoreStatus == null) {
|
||||
effect = mVibrationScaler.scale(effect, vib.attrs.getUsage());
|
||||
effect = mVibrationScaler.scale(effect, vib.callerInfo.attrs.getUsage());
|
||||
} else {
|
||||
// Vibration should not run, use null effect to remove registered effect.
|
||||
effect = null;
|
||||
@@ -687,9 +677,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
private Vibration.Status startVibrationLocked(HalVibration vib) {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked");
|
||||
try {
|
||||
vib.updateEffects(effect -> mVibrationScaler.scale(effect, vib.attrs.getUsage()));
|
||||
vib.updateEffects(
|
||||
effect -> mVibrationScaler.scale(effect, vib.callerInfo.attrs.getUsage()));
|
||||
boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
|
||||
vib.uid, vib.opPkg, vib.getEffect(), vib.reason, vib.attrs);
|
||||
vib.callerInfo, vib.getEffect());
|
||||
if (inputDevicesAvailable) {
|
||||
return Vibration.Status.FORWARDED_TO_INPUT_DEVICES;
|
||||
}
|
||||
@@ -704,8 +695,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
// Note that we don't consider pipelining here, because new pipelined ones should
|
||||
// replace pending non-executing pipelined ones anyway.
|
||||
clearNextVibrationLocked(
|
||||
new Vibration.EndInfo(Vibration.Status.IGNORED_SUPERSEDED,
|
||||
vib.uid, vib.attrs.getUsage()));
|
||||
new Vibration.EndInfo(Vibration.Status.IGNORED_SUPERSEDED, vib.callerInfo));
|
||||
mNextVibration = conductor;
|
||||
return Vibration.Status.RUNNING;
|
||||
} finally {
|
||||
@@ -718,7 +708,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationThreadLocked");
|
||||
try {
|
||||
HalVibration vib = conductor.getVibration();
|
||||
int mode = startAppOpModeLocked(vib.uid, vib.opPkg, vib.attrs);
|
||||
int mode = startAppOpModeLocked(vib.callerInfo);
|
||||
switch (mode) {
|
||||
case AppOpsManager.MODE_ALLOWED:
|
||||
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
|
||||
@@ -731,7 +721,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
return Vibration.Status.RUNNING;
|
||||
case AppOpsManager.MODE_ERRORED:
|
||||
Slog.w(TAG, "Start AppOpsManager operation errored for uid " + vib.uid);
|
||||
Slog.w(TAG, "Start AppOpsManager operation errored for uid "
|
||||
+ vib.callerInfo.uid);
|
||||
return Vibration.Status.IGNORED_ERROR_APP_OPS;
|
||||
default:
|
||||
return Vibration.Status.IGNORED_APP_OPS;
|
||||
@@ -745,7 +736,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
private void endVibrationLocked(HalVibration vib, Vibration.EndInfo vibrationEndInfo,
|
||||
boolean shouldWriteStats) {
|
||||
vib.end(vibrationEndInfo);
|
||||
logVibrationStatus(vib.uid, vib.attrs, vibrationEndInfo.status);
|
||||
logVibrationStatus(vib.callerInfo.uid, vib.callerInfo.attrs,
|
||||
vibrationEndInfo.status);
|
||||
mVibratorManagerRecords.record(vib);
|
||||
if (shouldWriteStats) {
|
||||
mFrameworkStatsLogger.writeVibrationReportedAsync(
|
||||
@@ -817,12 +809,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
try {
|
||||
HalVibration vib = mCurrentVibration.getVibration();
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Reporting vibration " + vib.id + " finished with " + vibrationEndInfo);
|
||||
Slog.d(TAG, "Reporting vibration " + vib.id + " finished with "
|
||||
+ vibrationEndInfo);
|
||||
}
|
||||
// DO NOT write metrics at this point, wait for the VibrationThread to report the
|
||||
// vibration was released, after all cleanup. The metrics will be reported then.
|
||||
endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ false);
|
||||
finishAppOpModeLocked(vib.uid, vib.opPkg);
|
||||
finishAppOpModeLocked(vib.callerInfo);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
|
||||
}
|
||||
@@ -830,7 +823,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
|
||||
private void onSyncedVibrationComplete(long vibrationId) {
|
||||
synchronized (mLock) {
|
||||
if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) {
|
||||
if (mCurrentVibration != null
|
||||
&& mCurrentVibration.getVibration().id == vibrationId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Synced vibration " + vibrationId + " complete, notifying thread");
|
||||
}
|
||||
@@ -841,7 +835,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
|
||||
private void onVibrationComplete(int vibratorId, long vibrationId) {
|
||||
synchronized (mLock) {
|
||||
if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) {
|
||||
if (mCurrentVibration != null
|
||||
&& mCurrentVibration.getVibration().id == vibrationId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Vibration " + vibrationId + " on vibrator " + vibratorId
|
||||
+ " complete, notifying thread");
|
||||
@@ -871,8 +866,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
return null;
|
||||
}
|
||||
|
||||
int currentUsage = currentVibration.attrs.getUsage();
|
||||
int newUsage = vib.attrs.getUsage();
|
||||
int currentUsage = currentVibration.callerInfo.attrs.getUsage();
|
||||
int newUsage = vib.callerInfo.attrs.getUsage();
|
||||
if (getVibrationImportance(currentUsage) > getVibrationImportance(newUsage)) {
|
||||
// Current vibration has higher importance than this one and should not be cancelled.
|
||||
return Vibration.Status.IGNORED_FOR_HIGHER_IMPORTANCE;
|
||||
@@ -916,15 +911,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private Vibration.Status shouldIgnoreVibrationLocked(int uid, int displayId, String opPkg,
|
||||
VibrationAttributes attrs) {
|
||||
Vibration.Status statusFromSettings = mVibrationSettings.shouldIgnoreVibration(uid,
|
||||
displayId, attrs);
|
||||
private Vibration.Status shouldIgnoreVibrationLocked(Vibration.CallerInfo callerInfo) {
|
||||
Vibration.Status statusFromSettings = mVibrationSettings.shouldIgnoreVibration(callerInfo);
|
||||
if (statusFromSettings != null) {
|
||||
return statusFromSettings;
|
||||
}
|
||||
|
||||
int mode = checkAppOpModeLocked(uid, opPkg, attrs);
|
||||
int mode = checkAppOpModeLocked(callerInfo);
|
||||
if (mode != AppOpsManager.MODE_ALLOWED) {
|
||||
if (mode == AppOpsManager.MODE_ERRORED) {
|
||||
// We might be getting calls from within system_server, so we don't actually
|
||||
@@ -948,7 +941,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
* started with the same token can be cancelled with it.
|
||||
*/
|
||||
private boolean shouldCancelVibration(HalVibration vib, int usageFilter, IBinder token) {
|
||||
return (vib.token == token) && shouldCancelVibration(vib.attrs, usageFilter);
|
||||
return (vib.callerToken == token) && shouldCancelVibration(vib.callerInfo.attrs,
|
||||
usageFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -973,24 +967,25 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
* {@code attrs}. This will return one of the AppOpsManager.MODE_*.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private int checkAppOpModeLocked(int uid, String opPkg, VibrationAttributes attrs) {
|
||||
private int checkAppOpModeLocked(Vibration.CallerInfo callerInfo) {
|
||||
int mode = mAppOps.checkAudioOpNoThrow(AppOpsManager.OP_VIBRATE,
|
||||
attrs.getAudioUsage(), uid, opPkg);
|
||||
int fixedMode = fixupAppOpModeLocked(mode, attrs);
|
||||
callerInfo.attrs.getAudioUsage(), callerInfo.uid, callerInfo.opPkg);
|
||||
int fixedMode = fixupAppOpModeLocked(mode, callerInfo.attrs);
|
||||
if (mode != fixedMode && fixedMode == AppOpsManager.MODE_ALLOWED) {
|
||||
// If we're just ignoring the vibration op then this is set by DND and we should ignore
|
||||
// if we're asked to bypass. AppOps won't be able to record this operation, so make
|
||||
// sure we at least note it in the logs for debugging.
|
||||
Slog.d(TAG, "Bypassing DND for vibrate from uid " + uid);
|
||||
Slog.d(TAG, "Bypassing DND for vibrate from uid " + callerInfo.uid);
|
||||
}
|
||||
return fixedMode;
|
||||
}
|
||||
|
||||
/** Start an operation in {@link AppOpsManager}, if allowed. */
|
||||
@GuardedBy("mLock")
|
||||
private int startAppOpModeLocked(int uid, String opPkg, VibrationAttributes attrs) {
|
||||
private int startAppOpModeLocked(Vibration.CallerInfo callerInfo) {
|
||||
return fixupAppOpModeLocked(
|
||||
mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, uid, opPkg), attrs);
|
||||
mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg),
|
||||
callerInfo.attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -998,8 +993,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
* operation with same uid was previously started.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private void finishAppOpModeLocked(int uid, String opPkg) {
|
||||
mAppOps.finishOp(AppOpsManager.OP_VIBRATE, uid, opPkg);
|
||||
private void finishAppOpModeLocked(Vibration.CallerInfo callerInfo) {
|
||||
mAppOps.finishOp(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1186,8 +1181,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
return false;
|
||||
}
|
||||
HalVibration vib = conductor.getVibration();
|
||||
return mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
vib.uid, vib.opPkg, vib.attrs.getUsage(), vib.stats().getCreateUptimeMillis());
|
||||
return mVibrationSettings.shouldCancelVibrationOnScreenOff(vib.callerInfo,
|
||||
vib.stats.getCreateUptimeMillis());
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@@ -1385,31 +1380,33 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
*/
|
||||
private static final class AlwaysOnVibration {
|
||||
public final int alwaysOnId;
|
||||
public final int uid;
|
||||
public final String opPkg;
|
||||
public final VibrationAttributes attrs;
|
||||
public final Vibration.CallerInfo callerInfo;
|
||||
public final SparseArray<PrebakedSegment> effects;
|
||||
|
||||
AlwaysOnVibration(int alwaysOnId, int uid, String opPkg, VibrationAttributes attrs,
|
||||
AlwaysOnVibration(int alwaysOnId, Vibration.CallerInfo callerInfo,
|
||||
SparseArray<PrebakedSegment> effects) {
|
||||
this.alwaysOnId = alwaysOnId;
|
||||
this.uid = uid;
|
||||
this.opPkg = opPkg;
|
||||
this.attrs = attrs;
|
||||
this.callerInfo = callerInfo;
|
||||
this.effects = effects;
|
||||
}
|
||||
}
|
||||
|
||||
/** Holder for a {@link ExternalVibration}. */
|
||||
private final class ExternalVibrationHolder implements IBinder.DeathRecipient {
|
||||
private final class ExternalVibrationHolder extends Vibration implements
|
||||
IBinder.DeathRecipient {
|
||||
|
||||
public final ExternalVibration externalVibration;
|
||||
public final VibrationStats stats = new VibrationStats();
|
||||
public int scale;
|
||||
|
||||
private Vibration.Status mStatus;
|
||||
|
||||
private ExternalVibrationHolder(ExternalVibration externalVibration) {
|
||||
super(externalVibration.getToken(), new Vibration.CallerInfo(
|
||||
externalVibration.getVibrationAttributes(), externalVibration.getUid(),
|
||||
// TODO(b/243604888): propagating displayID from IExternalVibration instead of
|
||||
// using INVALID_DISPLAY for all external vibrations.
|
||||
Display.INVALID_DISPLAY,
|
||||
externalVibration.getPackage(), null));
|
||||
this.externalVibration = externalVibration;
|
||||
this.scale = IExternalVibratorService.SCALE_NONE;
|
||||
mStatus = Vibration.Status.RUNNING;
|
||||
@@ -1437,14 +1434,15 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
return;
|
||||
}
|
||||
mStatus = info.status;
|
||||
stats.reportEnded(info.endedByUid, info.endedByUsage);
|
||||
stats.reportEnded(info.endedBy);
|
||||
|
||||
if (stats.hasStarted()) {
|
||||
// External vibration doesn't have feedback from total time the vibrator was playing
|
||||
// with non-zero amplitude, so we use the duration between start and end times of
|
||||
// the vibration as the time the vibrator was ON, since the haptic channels are
|
||||
// open for this duration and can receive vibration waveform data.
|
||||
stats.reportVibratorOn(stats.getEndUptimeMillis() - stats.getStartUptimeMillis());
|
||||
stats.reportVibratorOn(
|
||||
stats.getEndUptimeMillis() - stats.getStartUptimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1462,13 +1460,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
|
||||
public Vibration.DebugInfo getDebugInfo() {
|
||||
return new Vibration.DebugInfo(
|
||||
mStatus, stats, /* effect= */ null, /* originalEffect= */ null, scale,
|
||||
externalVibration.getVibrationAttributes(), externalVibration.getUid(),
|
||||
// TODO(b/243604888): propagating displayID from IExternalVibration instead of
|
||||
// using INVALID_DISPLAY for all external vibrations.
|
||||
Display.INVALID_DISPLAY,
|
||||
externalVibration.getPackage(), /* reason= */ null);
|
||||
return new Vibration.DebugInfo(mStatus, stats, /* effect= */ null,
|
||||
/* originalEffect= */ null, scale, callerInfo);
|
||||
}
|
||||
|
||||
public VibrationStats.StatsInfo getStatsInfo(long completionUptimeMillis) {
|
||||
@@ -1538,7 +1531,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
}
|
||||
|
||||
synchronized void record(HalVibration vib) {
|
||||
int usage = vib.attrs.getUsage();
|
||||
int usage = vib.callerInfo.attrs.getUsage();
|
||||
if (!mPreviousVibrations.contains(usage)) {
|
||||
mPreviousVibrations.put(usage, new LinkedList<>());
|
||||
}
|
||||
@@ -1679,8 +1672,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
synchronized (mLock) {
|
||||
// TODO(b/243604888): propagating displayID from IExternalVibration instead of
|
||||
// using INVALID_DISPLAY for all external vibrations.
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
||||
vib.getUid(), Display.INVALID_DISPLAY, vib.getPackage(), attrs);
|
||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(vibHolder.callerInfo);
|
||||
if (ignoreStatus != null) {
|
||||
vibHolder.scale = IExternalVibratorService.SCALE_MUTE;
|
||||
// Failed to start the vibration, end it and report metrics right away.
|
||||
@@ -1698,13 +1690,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
// vibration that may be playing and ready the vibrator for external control.
|
||||
if (mCurrentVibration != null) {
|
||||
vibHolder.stats.reportInterruptedAnotherVibration(
|
||||
mCurrentVibration.getVibration().attrs.getUsage());
|
||||
mCurrentVibration.getVibration().callerInfo);
|
||||
clearNextVibrationLocked(
|
||||
new Vibration.EndInfo(Vibration.Status.IGNORED_FOR_EXTERNAL,
|
||||
vib.getUid(), attrs.getUsage()));
|
||||
vibHolder.callerInfo));
|
||||
mCurrentVibration.notifyCancelled(
|
||||
new Vibration.EndInfo(Vibration.Status.CANCELLED_SUPERSEDED,
|
||||
vib.getUid(), attrs.getUsage()),
|
||||
vibHolder.callerInfo),
|
||||
/* immediate= */ true);
|
||||
waitForCompletion = true;
|
||||
}
|
||||
@@ -1720,11 +1712,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
||||
alreadyUnderExternalControl = true;
|
||||
mCurrentExternalVibration.mute();
|
||||
vibHolder.stats.reportInterruptedAnotherVibration(
|
||||
mCurrentExternalVibration.externalVibration
|
||||
.getVibrationAttributes().getUsage());
|
||||
mCurrentExternalVibration.callerInfo);
|
||||
endExternalVibrateLocked(
|
||||
new Vibration.EndInfo(Vibration.Status.CANCELLED_SUPERSEDED,
|
||||
vib.getUid(), attrs.getUsage()),
|
||||
vibHolder.callerInfo),
|
||||
/* continueExternalControl= */ true);
|
||||
}
|
||||
mCurrentExternalVibration = vibHolder;
|
||||
|
||||
@@ -263,7 +263,8 @@ public class InputDeviceDelegateTest {
|
||||
public void vibrateIfAvailable_withNoInputDevice_returnsFalse() {
|
||||
assertFalse(mInputDeviceDelegate.isAvailable());
|
||||
assertFalse(mInputDeviceDelegate.vibrateIfAvailable(
|
||||
UID, PACKAGE_NAME, SYNCED_EFFECT, REASON, VIBRATION_ATTRIBUTES));
|
||||
new Vibration.CallerInfo(VIBRATION_ATTRIBUTES, UID, -1, PACKAGE_NAME, REASON),
|
||||
SYNCED_EFFECT));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -277,7 +278,8 @@ public class InputDeviceDelegateTest {
|
||||
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
|
||||
|
||||
assertTrue(mInputDeviceDelegate.vibrateIfAvailable(
|
||||
UID, PACKAGE_NAME, SYNCED_EFFECT, REASON, VIBRATION_ATTRIBUTES));
|
||||
new Vibration.CallerInfo(VIBRATION_ATTRIBUTES, UID, -1, PACKAGE_NAME, REASON),
|
||||
SYNCED_EFFECT));
|
||||
verify(mIInputManagerMock).vibrateCombined(eq(1), same(SYNCED_EFFECT), any());
|
||||
verify(mIInputManagerMock).vibrateCombined(eq(2), same(SYNCED_EFFECT), any());
|
||||
}
|
||||
|
||||
@@ -564,17 +564,17 @@ public class VibrationSettingsTest {
|
||||
|
||||
for (int usage : ALL_USAGES) {
|
||||
// Non-system vibration
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
UID, "some.app", usage, vibrateStartTime));
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(createCallerInfo(
|
||||
UID, "some.app", usage), vibrateStartTime));
|
||||
// Vibration with UID zero
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
/* uid= */ 0, "", usage, vibrateStartTime));
|
||||
createCallerInfo(/* uid= */ 0, "", usage), vibrateStartTime));
|
||||
// System vibration
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
Process.SYSTEM_UID, "", usage, vibrateStartTime));
|
||||
createCallerInfo(Process.SYSTEM_UID, "", usage), vibrateStartTime));
|
||||
// SysUI vibration
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
UID, SYSUI_PACKAGE_NAME, usage, vibrateStartTime));
|
||||
createCallerInfo(UID, SYSUI_PACKAGE_NAME, usage), vibrateStartTime));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,16 +592,16 @@ public class VibrationSettingsTest {
|
||||
for (int usage : ALL_USAGES) {
|
||||
// Non-system vibration
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
UID, "some.app", usage, vibrateStartTime));
|
||||
createCallerInfo(UID, "some.app", usage), vibrateStartTime));
|
||||
// Vibration with UID zero
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
/* uid= */ 0, "", usage, vibrateStartTime));
|
||||
createCallerInfo(/* uid= */ 0, "", usage), vibrateStartTime));
|
||||
// System vibration
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
Process.SYSTEM_UID, "", usage, vibrateStartTime));
|
||||
createCallerInfo(Process.SYSTEM_UID, "", usage), vibrateStartTime));
|
||||
// SysUI vibration
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
UID, SYSUI_PACKAGE_NAME, usage, vibrateStartTime));
|
||||
createCallerInfo(UID, SYSUI_PACKAGE_NAME, usage), vibrateStartTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -613,7 +613,7 @@ public class VibrationSettingsTest {
|
||||
|
||||
for (int usage : ALL_USAGES) {
|
||||
assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
UID, "some.app", usage, vibrateStartTime));
|
||||
createCallerInfo(UID, "some.app", usage), vibrateStartTime));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,10 +626,10 @@ public class VibrationSettingsTest {
|
||||
if (usage == USAGE_TOUCH || usage == USAGE_HARDWARE_FEEDBACK
|
||||
|| usage == USAGE_PHYSICAL_EMULATION) {
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
/* uid= */ 0, "", usage, vibrateStartTime));
|
||||
createCallerInfo(/* uid= */ 0, "", usage), vibrateStartTime));
|
||||
} else {
|
||||
assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
/* uid= */ 0, "", usage, vibrateStartTime));
|
||||
createCallerInfo(/* uid= */ 0, "", usage), vibrateStartTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -643,10 +643,10 @@ public class VibrationSettingsTest {
|
||||
if (usage == USAGE_TOUCH || usage == USAGE_HARDWARE_FEEDBACK
|
||||
|| usage == USAGE_PHYSICAL_EMULATION) {
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
Process.SYSTEM_UID, "", usage, vibrateStartTime));
|
||||
createCallerInfo(Process.SYSTEM_UID, "", usage), vibrateStartTime));
|
||||
} else {
|
||||
assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
Process.SYSTEM_UID, "", usage, vibrateStartTime));
|
||||
createCallerInfo(Process.SYSTEM_UID, "", usage), vibrateStartTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -660,10 +660,10 @@ public class VibrationSettingsTest {
|
||||
if (usage == USAGE_TOUCH || usage == USAGE_HARDWARE_FEEDBACK
|
||||
|| usage == USAGE_PHYSICAL_EMULATION) {
|
||||
assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
UID, SYSUI_PACKAGE_NAME, usage, vibrateStartTime));
|
||||
createCallerInfo(UID, SYSUI_PACKAGE_NAME, usage), vibrateStartTime));
|
||||
} else {
|
||||
assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
|
||||
UID, SYSUI_PACKAGE_NAME, usage, vibrateStartTime));
|
||||
createCallerInfo(UID, SYSUI_PACKAGE_NAME, usage), vibrateStartTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -755,10 +755,10 @@ public class VibrationSettingsTest {
|
||||
|
||||
private void assertVibrationIgnoredForUsageAndDisplay(@VibrationAttributes.Usage int usage,
|
||||
int displayId, Vibration.Status expectedStatus) {
|
||||
assertEquals(errorMessageForUsage(usage),
|
||||
expectedStatus,
|
||||
mVibrationSettings.shouldIgnoreVibration(UID, displayId,
|
||||
VibrationAttributes.createForUsage(usage)));
|
||||
Vibration.CallerInfo callerInfo = new Vibration.CallerInfo(
|
||||
VibrationAttributes.createForUsage(usage), UID, displayId, null, null);
|
||||
assertEquals(errorMessageForUsage(usage), expectedStatus,
|
||||
mVibrationSettings.shouldIgnoreVibration(callerInfo));
|
||||
}
|
||||
|
||||
private void assertVibrationNotIgnoredForUsage(@VibrationAttributes.Usage int usage) {
|
||||
@@ -767,24 +767,22 @@ public class VibrationSettingsTest {
|
||||
|
||||
private void assertVibrationNotIgnoredForUsageAndFlags(@VibrationAttributes.Usage int usage,
|
||||
@VibrationAttributes.Flag int flags) {
|
||||
assertVibrationNotIgnoredForUsageAndFlagsAndDidsplay(usage, Display.DEFAULT_DISPLAY, flags);
|
||||
assertVibrationNotIgnoredForUsageAndFlagsAndDisplay(usage, Display.DEFAULT_DISPLAY, flags);
|
||||
}
|
||||
|
||||
private void assertVibrationNotIgnoredForUsageAndDisplay(@VibrationAttributes.Usage int usage,
|
||||
int displayId) {
|
||||
assertVibrationNotIgnoredForUsageAndFlagsAndDidsplay(usage, displayId, /* flags= */ 0);
|
||||
assertVibrationNotIgnoredForUsageAndFlagsAndDisplay(usage, displayId, /* flags= */ 0);
|
||||
}
|
||||
|
||||
private void assertVibrationNotIgnoredForUsageAndFlagsAndDidsplay(
|
||||
private void assertVibrationNotIgnoredForUsageAndFlagsAndDisplay(
|
||||
@VibrationAttributes.Usage int usage, int displayId,
|
||||
@VibrationAttributes.Flag int flags) {
|
||||
Vibration.CallerInfo callerInfo = new Vibration.CallerInfo(
|
||||
new VibrationAttributes.Builder().setUsage(usage).setFlags(flags).build(), UID,
|
||||
displayId, null, null);
|
||||
assertNull(errorMessageForUsage(usage),
|
||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||
displayId,
|
||||
new VibrationAttributes.Builder()
|
||||
.setUsage(usage)
|
||||
.setFlags(flags)
|
||||
.build()));
|
||||
mVibrationSettings.shouldIgnoreVibration(callerInfo));
|
||||
}
|
||||
|
||||
|
||||
@@ -826,4 +824,10 @@ public class VibrationSettingsTest {
|
||||
when(mPowerManagerInternalMock.getLastGoToSleep()).thenReturn(
|
||||
new PowerManager.SleepData(sleepTime, reason));
|
||||
}
|
||||
|
||||
private Vibration.CallerInfo createCallerInfo(int uid, String opPkg,
|
||||
@VibrationAttributes.Usage int usage) {
|
||||
VibrationAttributes attrs = VibrationAttributes.createForUsage(usage);
|
||||
return new Vibration.CallerInfo(attrs, uid, VIRTUAL_DISPLAY_ID, opPkg, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,10 +154,10 @@ public class VibrationThreadTest {
|
||||
@Test
|
||||
public void vibrate_noVibrator_ignoresVibration() {
|
||||
mVibratorProviders.clear();
|
||||
long vibrationId = 1;
|
||||
CombinedVibration effect = CombinedVibration.createParallel(
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
|
||||
@@ -166,12 +166,12 @@ public class VibrationThreadTest {
|
||||
|
||||
@Test
|
||||
public void vibrate_missingVibrators_ignoresVibration() {
|
||||
long vibrationId = 1;
|
||||
CombinedVibration effect = CombinedVibration.startSequential()
|
||||
.addNext(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
|
||||
.addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
|
||||
.combine();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
|
||||
@@ -182,9 +182,9 @@ public class VibrationThreadTest {
|
||||
public void vibrate_singleVibratorOneShot_runsVibrationAndSetsAmplitude() throws Exception {
|
||||
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
|
||||
@@ -201,9 +201,9 @@ public class VibrationThreadTest {
|
||||
@Test
|
||||
public void vibrate_oneShotWithoutAmplitudeControl_runsVibrationWithDefaultAmplitude()
|
||||
throws Exception {
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
|
||||
@@ -222,10 +222,10 @@ public class VibrationThreadTest {
|
||||
throws Exception {
|
||||
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
new long[]{5, 5, 5}, new int[]{1, 2, 3}, -1);
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(15L));
|
||||
@@ -246,10 +246,10 @@ public class VibrationThreadTest {
|
||||
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
|
||||
fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
int[] amplitudes = new int[]{1, 2, 3};
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5, 5, 5}, amplitudes, 0);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(
|
||||
waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
|
||||
@@ -259,8 +259,9 @@ public class VibrationThreadTest {
|
||||
assertTrue(mControllers.get(VIBRATOR_ID).isVibrating());
|
||||
|
||||
Vibration.EndInfo cancelVibrationInfo = new Vibration.EndInfo(
|
||||
Vibration.Status.CANCELLED_SUPERSEDED, /* endedByUid= */ 1,
|
||||
/* endedByUsage= */ VibrationAttributes.USAGE_ALARM);
|
||||
Vibration.Status.CANCELLED_SUPERSEDED, new Vibration.CallerInfo(
|
||||
VibrationAttributes.createForUsage(VibrationAttributes.USAGE_ALARM), /* uid= */
|
||||
1, /* displayId= */ -1, /* opPkg= */ null, /* reason= */ null));
|
||||
conductor.notifyCancelled(
|
||||
cancelVibrationInfo,
|
||||
/* immediate= */ false);
|
||||
@@ -287,11 +288,11 @@ public class VibrationThreadTest {
|
||||
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
|
||||
fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
int[] amplitudes = new int[]{1, 2, 3};
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
new long[]{1, 10, 100}, amplitudes, 0);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
|
||||
conductor.notifyCancelled(
|
||||
@@ -315,7 +316,6 @@ public class VibrationThreadTest {
|
||||
fakeVibrator.setMaxAmplitudes(1, 1, 1);
|
||||
fakeVibrator.setPwleSizeMax(10);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
|
||||
// Very long segment so thread will be cancelled after first PWLE is triggered.
|
||||
.addTransition(Duration.ofMillis(100), targetFrequency(100))
|
||||
@@ -323,7 +323,8 @@ public class VibrationThreadTest {
|
||||
VibrationEffect repeatingEffect = VibrationEffect.startComposition()
|
||||
.repeatEffectIndefinitely(effect)
|
||||
.compose();
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, repeatingEffect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(repeatingEffect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
|
||||
TEST_TIMEOUT_MILLIS));
|
||||
@@ -346,7 +347,6 @@ public class VibrationThreadTest {
|
||||
fakeVibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK);
|
||||
fakeVibrator.setCompositionSizeMax(10);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
// Very long delay so thread will be cancelled after first PWLE is triggered.
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
|
||||
@@ -354,7 +354,8 @@ public class VibrationThreadTest {
|
||||
VibrationEffect repeatingEffect = VibrationEffect.startComposition()
|
||||
.repeatEffectIndefinitely(effect)
|
||||
.compose();
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, repeatingEffect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(repeatingEffect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
|
||||
TEST_TIMEOUT_MILLIS));
|
||||
@@ -375,11 +376,11 @@ public class VibrationThreadTest {
|
||||
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
|
||||
fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
int[] amplitudes = new int[]{1, 2, 3};
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
new long[]{5000, 500, 50}, amplitudes, 0);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
|
||||
conductor.notifyCancelled(
|
||||
@@ -400,11 +401,11 @@ public class VibrationThreadTest {
|
||||
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
|
||||
fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
int[] amplitudes = new int[]{1, 2};
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
new long[]{4900, 50}, amplitudes, 0);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> fakeVibrator.getEffectSegments(vibrationId).size() > 1,
|
||||
5000 + TEST_TIMEOUT_MILLIS));
|
||||
@@ -433,13 +434,13 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(VIBRATOR_ID).setSupportedPrimitives(
|
||||
VibrationEffect.Composition.PRIMITIVE_CLICK);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
|
||||
.compose();
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
|
||||
TEST_TIMEOUT_MILLIS));
|
||||
@@ -466,9 +467,9 @@ public class VibrationThreadTest {
|
||||
throws Exception {
|
||||
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{100}, new int[]{100}, 0);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
|
||||
TEST_TIMEOUT_MILLIS));
|
||||
@@ -494,9 +495,9 @@ public class VibrationThreadTest {
|
||||
public void vibrate_singleVibratorPrebaked_runsVibration() throws Exception {
|
||||
mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_THUD);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_THUD);
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
|
||||
@@ -514,12 +515,12 @@ public class VibrationThreadTest {
|
||||
throws Exception {
|
||||
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect fallback = VibrationEffect.createOneShot(10, 100);
|
||||
HalVibration vibration = createVibration(vibrationId, CombinedVibration.createParallel(
|
||||
HalVibration vibration = createVibration(CombinedVibration.createParallel(
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_CLICK)));
|
||||
vibration.addFallback(VibrationEffect.EFFECT_CLICK, fallback);
|
||||
startThreadAndDispatcher(vibration);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibration);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
|
||||
@@ -536,9 +537,9 @@ public class VibrationThreadTest {
|
||||
@Test
|
||||
public void vibrate_singleVibratorPrebakedAndUnsupportedEffect_ignoresVibration()
|
||||
throws Exception {
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(0L));
|
||||
@@ -555,12 +556,12 @@ public class VibrationThreadTest {
|
||||
fakeVibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK,
|
||||
VibrationEffect.Composition.PRIMITIVE_TICK);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
|
||||
.compose();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(40L));
|
||||
@@ -576,11 +577,11 @@ public class VibrationThreadTest {
|
||||
|
||||
@Test
|
||||
public void vibrate_singleVibratorComposedAndNoCapability_ignoresVibration() {
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
|
||||
.compose();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(0L));
|
||||
@@ -600,13 +601,13 @@ public class VibrationThreadTest {
|
||||
VibrationEffect.Composition.PRIMITIVE_SPIN);
|
||||
fakeVibrator.setCompositionSizeMax(2);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.8f)
|
||||
.compose();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
|
||||
@@ -630,7 +631,6 @@ public class VibrationThreadTest {
|
||||
fakeVibrator.setMaxAmplitudes(
|
||||
0.5f /* 100Hz*/, 1 /* 150Hz */, 0.6f /* 200Hz */);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addEffect(VibrationEffect.createOneShot(10, 100))
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
|
||||
@@ -643,7 +643,8 @@ public class VibrationThreadTest {
|
||||
.build())
|
||||
.addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
|
||||
.compose();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
// Use first duration the vibrator is turned on since we cannot estimate the clicks.
|
||||
@@ -675,7 +676,6 @@ public class VibrationThreadTest {
|
||||
VibrationEffect.Composition.PRIMITIVE_TICK);
|
||||
fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect fallback = VibrationEffect.createOneShot(10, 100);
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
|
||||
@@ -683,9 +683,10 @@ public class VibrationThreadTest {
|
||||
.addEffect(VibrationEffect.get(VibrationEffect.EFFECT_TICK))
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
|
||||
.compose();
|
||||
HalVibration vib = createVibration(vibrationId, CombinedVibration.createParallel(effect));
|
||||
HalVibration vib = createVibration(CombinedVibration.createParallel(effect));
|
||||
vib.addFallback(VibrationEffect.EFFECT_TICK, fallback);
|
||||
startThreadAndDispatcher(vib);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vib);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
// Use first duration the vibrator is turned on since we cannot estimate the clicks.
|
||||
@@ -718,7 +719,6 @@ public class VibrationThreadTest {
|
||||
fakeVibrator.setMaxAmplitudes(
|
||||
0.5f /* 100Hz*/, 1 /* 150Hz */, 0.6f /* 200Hz */);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
|
||||
.addSustain(Duration.ofMillis(10))
|
||||
.addTransition(Duration.ofMillis(20), targetAmplitude(0))
|
||||
@@ -726,7 +726,8 @@ public class VibrationThreadTest {
|
||||
.addSustain(Duration.ofMillis(30))
|
||||
.addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
|
||||
.build();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(100L));
|
||||
@@ -756,7 +757,6 @@ public class VibrationThreadTest {
|
||||
fakeVibrator.setMaxAmplitudes(1, 1, 1);
|
||||
fakeVibrator.setPwleSizeMax(3);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
|
||||
.addSustain(Duration.ofMillis(10))
|
||||
.addTransition(Duration.ofMillis(20), targetAmplitude(0))
|
||||
@@ -768,7 +768,8 @@ public class VibrationThreadTest {
|
||||
.addTransition(Duration.ofMillis(40), targetAmplitude(0.7f), targetFrequency(200))
|
||||
.addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
|
||||
.build();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
|
||||
@@ -784,9 +785,9 @@ public class VibrationThreadTest {
|
||||
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
|
||||
fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2, TEST_TIMEOUT_MILLIS));
|
||||
// Vibration still running after 2 cycles.
|
||||
@@ -804,9 +805,9 @@ public class VibrationThreadTest {
|
||||
public void vibrate_singleVibrator_skipsSyncedCallbacks() {
|
||||
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
startThreadAndDispatcher(vibrationId,
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(
|
||||
VibrationEffect.createOneShot(10, 100));
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
|
||||
@@ -820,12 +821,12 @@ public class VibrationThreadTest {
|
||||
throws Exception {
|
||||
mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_TICK);
|
||||
|
||||
long vibrationId = 1;
|
||||
CombinedVibration effect = CombinedVibration.startParallel()
|
||||
.addVibrator(VIBRATOR_ID, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
|
||||
.addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
|
||||
.combine();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
|
||||
@@ -846,10 +847,10 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(2).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
|
||||
mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
|
||||
|
||||
long vibrationId = 1;
|
||||
CombinedVibration effect = CombinedVibration.createParallel(
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
|
||||
@@ -881,7 +882,6 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(4).setSupportedPrimitives(
|
||||
VibrationEffect.Composition.PRIMITIVE_CLICK);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect composed = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
|
||||
.compose();
|
||||
@@ -892,7 +892,8 @@ public class VibrationThreadTest {
|
||||
new long[]{10, 10}, new int[]{1, 2}, -1))
|
||||
.addVibrator(4, composed)
|
||||
.combine();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
|
||||
@@ -929,7 +930,6 @@ public class VibrationThreadTest {
|
||||
VibrationEffect.Composition.PRIMITIVE_CLICK);
|
||||
mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect composed = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
|
||||
.compose();
|
||||
@@ -938,7 +938,8 @@ public class VibrationThreadTest {
|
||||
.addNext(1, VibrationEffect.createOneShot(10, 100), /* delay= */ 50)
|
||||
.addNext(2, composed, /* delay= */ 50)
|
||||
.combine();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
waitForCompletion();
|
||||
InOrder controllerVerifier = inOrder(mControllerCallbacks);
|
||||
@@ -972,7 +973,6 @@ public class VibrationThreadTest {
|
||||
@Test
|
||||
public void vibrate_multipleSyncedCallbackTriggered_finishSteps() throws Exception {
|
||||
int[] vibratorIds = new int[]{1, 2};
|
||||
long vibrationId = 1;
|
||||
mockVibrators(vibratorIds);
|
||||
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
|
||||
mVibratorProviders.get(1).setSupportedPrimitives(
|
||||
@@ -981,13 +981,15 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(2).setSupportedPrimitives(
|
||||
VibrationEffect.Composition.PRIMITIVE_CLICK);
|
||||
when(mManagerHooks.prepareSyncedVibration(anyLong(), eq(vibratorIds))).thenReturn(true);
|
||||
when(mManagerHooks.triggerSyncedVibration(eq(vibrationId))).thenReturn(true);
|
||||
|
||||
VibrationEffect composed = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100)
|
||||
.compose();
|
||||
CombinedVibration effect = CombinedVibration.createParallel(composed);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
when(mManagerHooks.triggerSyncedVibration(eq(vibrationId))).thenReturn(true);
|
||||
|
||||
assertTrue(waitUntil(
|
||||
() -> !mVibratorProviders.get(1).getEffectSegments(vibrationId).isEmpty()
|
||||
@@ -1021,7 +1023,6 @@ public class VibrationThreadTest {
|
||||
when(mManagerHooks.prepareSyncedVibration(anyLong(), any())).thenReturn(true);
|
||||
when(mManagerHooks.triggerSyncedVibration(anyLong())).thenReturn(true);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect composed = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
|
||||
.compose();
|
||||
@@ -1031,7 +1032,8 @@ public class VibrationThreadTest {
|
||||
.addVibrator(3, VibrationEffect.createWaveform(new long[]{10}, new int[]{100}, -1))
|
||||
.addVibrator(4, composed)
|
||||
.combine();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
long expectedCap = IVibratorManager.CAP_SYNC
|
||||
@@ -1055,12 +1057,12 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
when(mManagerHooks.prepareSyncedVibration(anyLong(), any())).thenReturn(false);
|
||||
|
||||
long vibrationId = 1;
|
||||
CombinedVibration effect = CombinedVibration.startParallel()
|
||||
.addVibrator(1, VibrationEffect.createOneShot(10, 100))
|
||||
.addVibrator(2, VibrationEffect.createWaveform(new long[]{5}, new int[]{200}, -1))
|
||||
.combine();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
long expectedCap = IVibratorManager.CAP_SYNC | IVibratorManager.CAP_PREPARE_ON;
|
||||
@@ -1084,12 +1086,12 @@ public class VibrationThreadTest {
|
||||
when(mManagerHooks.prepareSyncedVibration(anyLong(), any())).thenReturn(true);
|
||||
when(mManagerHooks.triggerSyncedVibration(anyLong())).thenReturn(false);
|
||||
|
||||
long vibrationId = 1;
|
||||
CombinedVibration effect = CombinedVibration.startParallel()
|
||||
.addVibrator(1, VibrationEffect.createOneShot(10, 100))
|
||||
.addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
|
||||
.combine();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
long expectedCap = IVibratorManager.CAP_SYNC
|
||||
@@ -1110,7 +1112,6 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
CombinedVibration effect = CombinedVibration.startParallel()
|
||||
.addVibrator(1, VibrationEffect.createWaveform(
|
||||
new long[]{5, 10, 10}, new int[]{1, 2, 3}, -1))
|
||||
@@ -1119,7 +1120,8 @@ public class VibrationThreadTest {
|
||||
.addVibrator(3, VibrationEffect.createWaveform(
|
||||
new long[]{60}, new int[]{6}, -1))
|
||||
.combine();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
// All vibrators are turned on in parallel.
|
||||
assertTrue(waitUntil(
|
||||
@@ -1169,8 +1171,7 @@ public class VibrationThreadTest {
|
||||
Arrays.fill(amplitudes, VibrationEffect.DEFAULT_AMPLITUDE);
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(timings, amplitudes, -1);
|
||||
|
||||
long vibrationId = 1;
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
startThreadAndDispatcher(effect);
|
||||
long startTime = SystemClock.elapsedRealtime();
|
||||
|
||||
waitForCompletion(totalDuration + TEST_TIMEOUT_MILLIS);
|
||||
@@ -1192,9 +1193,9 @@ public class VibrationThreadTest {
|
||||
long latency = 5_000; // 5s
|
||||
fakeVibrator.setOnLatency(latency);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
|
||||
TEST_TIMEOUT_MILLIS));
|
||||
@@ -1226,7 +1227,6 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(2).setSupportedPrimitives(
|
||||
VibrationEffect.Composition.PRIMITIVE_CLICK);
|
||||
|
||||
long vibrationId = 1;
|
||||
CombinedVibration effect = CombinedVibration.startParallel()
|
||||
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
|
||||
.addVibrator(2, VibrationEffect.startComposition()
|
||||
@@ -1235,7 +1235,8 @@ public class VibrationThreadTest {
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
|
||||
.compose())
|
||||
.combine();
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> mControllers.get(2).isVibrating(),
|
||||
TEST_TIMEOUT_MILLIS));
|
||||
@@ -1264,13 +1265,13 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
CombinedVibration effect = CombinedVibration.startParallel()
|
||||
.addVibrator(1, VibrationEffect.createWaveform(
|
||||
new long[]{100, 100}, new int[]{1, 2}, 0))
|
||||
.addVibrator(2, VibrationEffect.createOneShot(100, 100))
|
||||
.combine();
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> mControllers.get(1).isVibrating()
|
||||
&& mControllers.get(2).isVibrating(),
|
||||
@@ -1296,9 +1297,9 @@ public class VibrationThreadTest {
|
||||
|
||||
@Test
|
||||
public void vibrate_binderDied_cancelsVibration() throws Exception {
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
|
||||
TEST_TIMEOUT_MILLIS));
|
||||
@@ -1320,10 +1321,10 @@ public class VibrationThreadTest {
|
||||
mEffectAdapter = new DeviceVibrationEffectAdapter(mVibrationSettings);
|
||||
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
new long[]{5, 5, 5}, new int[]{60, 120, 240}, -1);
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
|
||||
@@ -1346,9 +1347,9 @@ public class VibrationThreadTest {
|
||||
mEffectAdapter = new DeviceVibrationEffectAdapter(mVibrationSettings);
|
||||
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.createOneShot(10, 200);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
|
||||
// Vibration completed but vibrator not yet released.
|
||||
verify(mManagerHooks, timeout(TEST_TIMEOUT_MILLIS)).onVibrationCompleted(eq(vibrationId),
|
||||
@@ -1381,9 +1382,9 @@ public class VibrationThreadTest {
|
||||
mEffectAdapter = new DeviceVibrationEffectAdapter(mVibrationSettings);
|
||||
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.createOneShot(10_000, 240);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
|
||||
TEST_TIMEOUT_MILLIS));
|
||||
conductor.notifyCancelled(
|
||||
@@ -1410,9 +1411,9 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
|
||||
mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
|
||||
@@ -1432,11 +1433,11 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(VIBRATOR_ID).setSupportedPrimitives(
|
||||
VibrationEffect.Composition.PRIMITIVE_CLICK);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
|
||||
.compose();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
|
||||
@@ -1461,11 +1462,11 @@ public class VibrationThreadTest {
|
||||
fakeVibrator.setMaxAmplitudes(1, 1, 1);
|
||||
fakeVibrator.setPwleSizeMax(2);
|
||||
|
||||
long vibrationId = 1;
|
||||
VibrationEffect effect = VibrationEffect.startWaveform()
|
||||
.addTransition(Duration.ofMillis(1), targetAmplitude(1))
|
||||
.build();
|
||||
startThreadAndDispatcher(vibrationId, effect);
|
||||
VibrationStepConductor conductor = startThreadAndDispatcher(effect);
|
||||
long vibrationId = conductor.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
|
||||
@@ -1485,12 +1486,6 @@ public class VibrationThreadTest {
|
||||
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL,
|
||||
IVibrator.CAP_COMPOSE_EFFECTS);
|
||||
|
||||
long vibrationId1 = 1;
|
||||
long vibrationId2 = 2;
|
||||
long vibrationId3 = 3;
|
||||
long vibrationId4 = 4;
|
||||
long vibrationId5 = 5;
|
||||
|
||||
// A simple effect, followed by a repeating effect that gets cancelled, followed by another
|
||||
// simple effect.
|
||||
VibrationEffect effect1 = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
|
||||
@@ -1503,12 +1498,14 @@ public class VibrationThreadTest {
|
||||
VibrationEffect effect4 = VibrationEffect.createOneShot(8000, 100);
|
||||
VibrationEffect effect5 = VibrationEffect.createOneShot(20, 222);
|
||||
|
||||
startThreadAndDispatcher(vibrationId1, effect1);
|
||||
VibrationStepConductor conductor1 = startThreadAndDispatcher(effect1);
|
||||
long vibrationId1 = conductor1.getVibration().id;
|
||||
waitForCompletion();
|
||||
verify(mControllerCallbacks).onComplete(VIBRATOR_ID, vibrationId1);
|
||||
verifyCallbacksTriggered(vibrationId1, Vibration.Status.FINISHED);
|
||||
|
||||
VibrationStepConductor conductor2 = startThreadAndDispatcher(vibrationId2, effect2);
|
||||
VibrationStepConductor conductor2 = startThreadAndDispatcher(effect2);
|
||||
long vibrationId2 = conductor2.getVibration().id;
|
||||
// Effect2 won't complete on its own. Cancel it after a couple of repeats.
|
||||
Thread.sleep(150); // More than two TICKs.
|
||||
conductor2.notifyCancelled(
|
||||
@@ -1516,12 +1513,14 @@ public class VibrationThreadTest {
|
||||
/* immediate= */ false);
|
||||
waitForCompletion();
|
||||
|
||||
startThreadAndDispatcher(vibrationId3, effect3);
|
||||
VibrationStepConductor conductor3 = startThreadAndDispatcher(effect3);
|
||||
long vibrationId3 = conductor3.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
// Effect4 is a long oneshot, but it gets cancelled as fast as possible.
|
||||
long start4 = System.currentTimeMillis();
|
||||
VibrationStepConductor conductor4 = startThreadAndDispatcher(vibrationId4, effect4);
|
||||
VibrationStepConductor conductor4 = startThreadAndDispatcher(effect4);
|
||||
long vibrationId4 = conductor4.getVibration().id;
|
||||
conductor4.notifyCancelled(
|
||||
new Vibration.EndInfo(Vibration.Status.CANCELLED_BY_SCREEN_OFF),
|
||||
/* immediate= */ true);
|
||||
@@ -1529,7 +1528,8 @@ public class VibrationThreadTest {
|
||||
long duration4 = System.currentTimeMillis() - start4;
|
||||
|
||||
// Effect5 is to show that things keep going after the immediate cancel.
|
||||
startThreadAndDispatcher(vibrationId5, effect5);
|
||||
VibrationStepConductor conductor5 = startThreadAndDispatcher(effect5);
|
||||
long vibrationId5 = conductor5.getVibration().id;
|
||||
waitForCompletion();
|
||||
|
||||
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
|
||||
@@ -1582,14 +1582,12 @@ public class VibrationThreadTest {
|
||||
}
|
||||
}
|
||||
|
||||
private VibrationStepConductor startThreadAndDispatcher(
|
||||
long vibrationId, VibrationEffect effect) {
|
||||
return startThreadAndDispatcher(vibrationId, CombinedVibration.createParallel(effect));
|
||||
private VibrationStepConductor startThreadAndDispatcher(VibrationEffect effect) {
|
||||
return startThreadAndDispatcher(CombinedVibration.createParallel(effect));
|
||||
}
|
||||
|
||||
private VibrationStepConductor startThreadAndDispatcher(long vibrationId,
|
||||
CombinedVibration effect) {
|
||||
return startThreadAndDispatcher(createVibration(vibrationId, effect));
|
||||
private VibrationStepConductor startThreadAndDispatcher(CombinedVibration effect) {
|
||||
return startThreadAndDispatcher(createVibration(effect));
|
||||
}
|
||||
|
||||
private VibrationStepConductor startThreadAndDispatcher(HalVibration vib) {
|
||||
@@ -1624,9 +1622,9 @@ public class VibrationThreadTest {
|
||||
mTestLooper.dispatchAll(); // Flush callbacks
|
||||
}
|
||||
|
||||
private HalVibration createVibration(long id, CombinedVibration effect) {
|
||||
return new HalVibration(mVibrationToken, (int) id, effect, ATTRS, UID, DISPLAY_ID,
|
||||
PACKAGE_NAME, "reason");
|
||||
private HalVibration createVibration(CombinedVibration effect) {
|
||||
return new HalVibration(mVibrationToken, effect,
|
||||
new Vibration.CallerInfo(ATTRS, UID, DISPLAY_ID, PACKAGE_NAME, "reason"));
|
||||
}
|
||||
|
||||
private SparseArray<VibratorController> createVibratorControllers() {
|
||||
|
||||
Reference in New Issue
Block a user