Merge "Register VibrationSettings as a listener to: 1) virtual displays creation and removal. 2) App Uids running on virtual displays. These will be used in combination to ignore vibration initiated from a virtual display." into tm-qpr-dev
This commit is contained in:
@@ -30,7 +30,7 @@ interface IVibratorManagerService {
|
|||||||
boolean unregisterVibratorStateListener(int vibratorId, in IVibratorStateListener listener);
|
boolean unregisterVibratorStateListener(int vibratorId, in IVibratorStateListener listener);
|
||||||
boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
|
boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
|
||||||
in CombinedVibration vibration, in VibrationAttributes attributes);
|
in CombinedVibration vibration, in VibrationAttributes attributes);
|
||||||
void vibrate(int uid, String opPkg, in CombinedVibration vibration,
|
void vibrate(int uid, int displayId, String opPkg, in CombinedVibration vibration,
|
||||||
in VibrationAttributes attributes, String reason, IBinder token);
|
in VibrationAttributes attributes, String reason, IBinder token);
|
||||||
void cancelVibrate(int usageFilter, IBinder token);
|
void cancelVibrate(int usageFilter, IBinder token);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,8 @@ public class SystemVibratorManager extends VibratorManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mService.vibrate(uid, opPkg, effect, attributes, reason, mToken);
|
mService.vibrate(uid, mContext.getAssociatedDisplayId(), opPkg, effect, attributes,
|
||||||
|
reason, mToken);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "Failed to vibrate.", e);
|
Log.w(TAG, "Failed to vibrate.", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ message VibrationProto {
|
|||||||
IGNORED_FOR_RINGER_MODE = 23;
|
IGNORED_FOR_RINGER_MODE = 23;
|
||||||
IGNORED_FOR_SETTINGS = 24;
|
IGNORED_FOR_SETTINGS = 24;
|
||||||
IGNORED_SUPERSEDED = 25;
|
IGNORED_SUPERSEDED = 25;
|
||||||
|
IGNORED_FROM_VIRTUAL_DEVICE = 26;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ final class Vibration {
|
|||||||
IGNORED_FOR_POWER(VibrationProto.IGNORED_FOR_POWER),
|
IGNORED_FOR_POWER(VibrationProto.IGNORED_FOR_POWER),
|
||||||
IGNORED_FOR_RINGER_MODE(VibrationProto.IGNORED_FOR_RINGER_MODE),
|
IGNORED_FOR_RINGER_MODE(VibrationProto.IGNORED_FOR_RINGER_MODE),
|
||||||
IGNORED_FOR_SETTINGS(VibrationProto.IGNORED_FOR_SETTINGS),
|
IGNORED_FOR_SETTINGS(VibrationProto.IGNORED_FOR_SETTINGS),
|
||||||
IGNORED_SUPERSEDED(VibrationProto.IGNORED_SUPERSEDED);
|
IGNORED_SUPERSEDED(VibrationProto.IGNORED_SUPERSEDED),
|
||||||
|
IGNORED_FROM_VIRTUAL_DEVICE(VibrationProto.IGNORED_FROM_VIRTUAL_DEVICE);
|
||||||
|
|
||||||
private final int mProtoEnumValue;
|
private final int mProtoEnumValue;
|
||||||
|
|
||||||
@@ -87,6 +88,7 @@ final class Vibration {
|
|||||||
public final VibrationAttributes attrs;
|
public final VibrationAttributes attrs;
|
||||||
public final long id;
|
public final long id;
|
||||||
public final int uid;
|
public final int uid;
|
||||||
|
public final int displayId;
|
||||||
public final String opPkg;
|
public final String opPkg;
|
||||||
public final String reason;
|
public final String reason;
|
||||||
public final IBinder token;
|
public final IBinder token;
|
||||||
@@ -113,12 +115,13 @@ final class Vibration {
|
|||||||
private final CountDownLatch mCompletionLatch = new CountDownLatch(1);
|
private final CountDownLatch mCompletionLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
Vibration(IBinder token, int id, CombinedVibration effect,
|
Vibration(IBinder token, int id, CombinedVibration effect,
|
||||||
VibrationAttributes attrs, int uid, String opPkg, String reason) {
|
VibrationAttributes attrs, int uid, int displayId, String opPkg, String reason) {
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.mEffect = effect;
|
this.mEffect = effect;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.attrs = attrs;
|
this.attrs = attrs;
|
||||||
this.uid = uid;
|
this.uid = uid;
|
||||||
|
this.displayId = displayId;
|
||||||
this.opPkg = opPkg;
|
this.opPkg = opPkg;
|
||||||
this.reason = reason;
|
this.reason = reason;
|
||||||
mStatus = Vibration.Status.RUNNING;
|
mStatus = Vibration.Status.RUNNING;
|
||||||
@@ -236,7 +239,7 @@ final class Vibration {
|
|||||||
/** Return {@link Vibration.DebugInfo} with read-only debug information about this vibration. */
|
/** Return {@link Vibration.DebugInfo} with read-only debug information about this vibration. */
|
||||||
public Vibration.DebugInfo getDebugInfo() {
|
public Vibration.DebugInfo getDebugInfo() {
|
||||||
return new Vibration.DebugInfo(mStatus, mStats, mEffect, mOriginalEffect, /* scale= */ 0,
|
return new Vibration.DebugInfo(mStatus, mStats, mEffect, mOriginalEffect, /* scale= */ 0,
|
||||||
attrs, uid, opPkg, reason);
|
attrs, uid, displayId, opPkg, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return {@link VibrationStats.StatsInfo} with read-only metrics about this vibration. */
|
/** Return {@link VibrationStats.StatsInfo} with read-only metrics about this vibration. */
|
||||||
@@ -304,13 +307,14 @@ final class Vibration {
|
|||||||
private final float mScale;
|
private final float mScale;
|
||||||
private final VibrationAttributes mAttrs;
|
private final VibrationAttributes mAttrs;
|
||||||
private final int mUid;
|
private final int mUid;
|
||||||
|
private final int mDisplayId;
|
||||||
private final String mOpPkg;
|
private final String mOpPkg;
|
||||||
private final String mReason;
|
private final String mReason;
|
||||||
private final Status mStatus;
|
private final Status mStatus;
|
||||||
|
|
||||||
DebugInfo(Status status, VibrationStats stats, @Nullable CombinedVibration effect,
|
DebugInfo(Status status, VibrationStats stats, @Nullable CombinedVibration effect,
|
||||||
@Nullable CombinedVibration originalEffect, float scale, VibrationAttributes attrs,
|
@Nullable CombinedVibration originalEffect, float scale, VibrationAttributes attrs,
|
||||||
int uid, String opPkg, String reason) {
|
int uid, int displayId, String opPkg, String reason) {
|
||||||
mCreateTime = stats.getCreateTimeDebug();
|
mCreateTime = stats.getCreateTimeDebug();
|
||||||
mStartTime = stats.getStartTimeDebug();
|
mStartTime = stats.getStartTimeDebug();
|
||||||
mEndTime = stats.getEndTimeDebug();
|
mEndTime = stats.getEndTimeDebug();
|
||||||
@@ -320,6 +324,7 @@ final class Vibration {
|
|||||||
mScale = scale;
|
mScale = scale;
|
||||||
mAttrs = attrs;
|
mAttrs = attrs;
|
||||||
mUid = uid;
|
mUid = uid;
|
||||||
|
mDisplayId = displayId;
|
||||||
mOpPkg = opPkg;
|
mOpPkg = opPkg;
|
||||||
mReason = reason;
|
mReason = reason;
|
||||||
mStatus = status;
|
mStatus = status;
|
||||||
@@ -349,6 +354,8 @@ final class Vibration {
|
|||||||
.append(mAttrs)
|
.append(mAttrs)
|
||||||
.append(", uid: ")
|
.append(", uid: ")
|
||||||
.append(mUid)
|
.append(mUid)
|
||||||
|
.append(", displayId: ")
|
||||||
|
.append(mDisplayId)
|
||||||
.append(", opPkg: ")
|
.append(", opPkg: ")
|
||||||
.append(mOpPkg)
|
.append(mOpPkg)
|
||||||
.append(", reason: ")
|
.append(", reason: ")
|
||||||
|
|||||||
@@ -56,10 +56,12 @@ import android.util.Slog;
|
|||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
import android.view.Display;
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
|
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -157,6 +159,7 @@ final class VibrationSettings {
|
|||||||
final UidObserver mUidObserver;
|
final UidObserver mUidObserver;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final SettingsBroadcastReceiver mSettingChangeReceiver;
|
final SettingsBroadcastReceiver mSettingChangeReceiver;
|
||||||
|
final VirtualDeviceListener mVirtualDeviceListener;
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
|
private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
|
||||||
@@ -193,6 +196,7 @@ final class VibrationSettings {
|
|||||||
mSettingObserver = new SettingsContentObserver(handler);
|
mSettingObserver = new SettingsContentObserver(handler);
|
||||||
mUidObserver = new UidObserver();
|
mUidObserver = new UidObserver();
|
||||||
mSettingChangeReceiver = new SettingsBroadcastReceiver();
|
mSettingChangeReceiver = new SettingsBroadcastReceiver();
|
||||||
|
mVirtualDeviceListener = new VirtualDeviceListener();
|
||||||
|
|
||||||
mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
|
mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
|
||||||
.getSystemUiServiceComponent().getPackageName();
|
.getSystemUiServiceComponent().getPackageName();
|
||||||
@@ -257,6 +261,13 @@ final class VibrationSettings {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
VirtualDeviceManagerInternal vdm = LocalServices.getService(
|
||||||
|
VirtualDeviceManagerInternal.class);
|
||||||
|
if (vdm != null) {
|
||||||
|
vdm.registerVirtualDisplayListener(mVirtualDeviceListener);
|
||||||
|
vdm.registerAppsOnVirtualDeviceListener(mVirtualDeviceListener);
|
||||||
|
}
|
||||||
|
|
||||||
registerSettingsChangeReceiver(USER_SWITCHED_INTENT_FILTER);
|
registerSettingsChangeReceiver(USER_SWITCHED_INTENT_FILTER);
|
||||||
registerSettingsChangeReceiver(INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER);
|
registerSettingsChangeReceiver(INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER);
|
||||||
|
|
||||||
@@ -364,13 +375,17 @@ final class VibrationSettings {
|
|||||||
* null otherwise.
|
* null otherwise.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public Vibration.Status shouldIgnoreVibration(int uid, VibrationAttributes attrs) {
|
public Vibration.Status shouldIgnoreVibration(int uid, int displayId,
|
||||||
|
VibrationAttributes attrs) {
|
||||||
final int usage = attrs.getUsage();
|
final int usage = attrs.getUsage();
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (!mUidObserver.isUidForeground(uid)
|
if (!mUidObserver.isUidForeground(uid)
|
||||||
&& !BACKGROUND_PROCESS_USAGE_ALLOWLIST.contains(usage)) {
|
&& !BACKGROUND_PROCESS_USAGE_ALLOWLIST.contains(usage)) {
|
||||||
return Vibration.Status.IGNORED_BACKGROUND;
|
return Vibration.Status.IGNORED_BACKGROUND;
|
||||||
}
|
}
|
||||||
|
if (mVirtualDeviceListener.isAppOrDisplayOnAnyVirtualDevice(uid, displayId)) {
|
||||||
|
return Vibration.Status.IGNORED_FROM_VIRTUAL_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
if (mBatterySaverMode && !BATTERY_SAVER_USAGE_ALLOWLIST.contains(usage)) {
|
if (mBatterySaverMode && !BATTERY_SAVER_USAGE_ALLOWLIST.contains(usage)) {
|
||||||
return Vibration.Status.IGNORED_FOR_POWER;
|
return Vibration.Status.IGNORED_FOR_POWER;
|
||||||
@@ -741,4 +756,73 @@ final class VibrationSettings {
|
|||||||
public void onUidProcAdjChanged(int uid) {
|
public void onUidProcAdjChanged(int uid) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of Virtual Device listeners for the changes of virtual displays and of apps
|
||||||
|
* running on any virtual device.
|
||||||
|
*/
|
||||||
|
final class VirtualDeviceListener implements
|
||||||
|
VirtualDeviceManagerInternal.VirtualDisplayListener,
|
||||||
|
VirtualDeviceManagerInternal.AppsOnVirtualDeviceListener {
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private final Set<Integer> mVirtualDisplays = new HashSet<>();
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private final Set<Integer> mAppsOnVirtualDevice = new HashSet<>();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVirtualDisplayCreated(int displayId) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mVirtualDisplays.add(displayId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVirtualDisplayRemoved(int displayId) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mVirtualDisplays.remove(displayId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAppsOnAnyVirtualDeviceChanged(Set<Integer> allRunningUids) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mAppsOnVirtualDevice.clear();
|
||||||
|
mAppsOnVirtualDevice.addAll(allRunningUids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uid: uid of the calling app.
|
||||||
|
* @param displayId: the id of a Display.
|
||||||
|
* @return Returns true if:
|
||||||
|
* <ul>
|
||||||
|
* <li> the displayId is valid, and it's owned by a virtual device.</li>
|
||||||
|
* <li> the displayId is invalid, and the calling app (uid) is running on a virtual
|
||||||
|
* device.</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public boolean isAppOrDisplayOnAnyVirtualDevice(int uid, int displayId) {
|
||||||
|
if (displayId == Display.DEFAULT_DISPLAY) {
|
||||||
|
// The default display is the primary physical display on the phone.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (displayId == Display.INVALID_DISPLAY) {
|
||||||
|
// There is no Display object associated with the Context of calling
|
||||||
|
// {@link SystemVibratorManager}, checking the calling UID instead.
|
||||||
|
return mAppsOnVirtualDevice.contains(uid);
|
||||||
|
} else {
|
||||||
|
// Other valid display IDs representing valid logical displays will be
|
||||||
|
// checked
|
||||||
|
// against the active virtual displays set built with the registered
|
||||||
|
// {@link VirtualDisplayListener}.
|
||||||
|
return mVirtualDisplays.contains(displayId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import android.text.TextUtils;
|
|||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
import android.view.Display;
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -378,9 +379,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override // Binder call
|
@Override // Binder call
|
||||||
public void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect,
|
public void vibrate(int uid, int displayId, String opPkg, @NonNull CombinedVibration effect,
|
||||||
@Nullable VibrationAttributes attrs, String reason, IBinder token) {
|
@Nullable VibrationAttributes attrs, String reason, IBinder token) {
|
||||||
vibrateInternal(uid, opPkg, effect, attrs, reason, token);
|
vibrateInternal(uid, displayId, opPkg, effect, attrs, reason, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -389,8 +390,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Vibration vibrateInternal(int uid, String opPkg, @NonNull CombinedVibration effect,
|
Vibration vibrateInternal(int uid, int displayId, String opPkg,
|
||||||
@Nullable VibrationAttributes attrs, String reason, IBinder token) {
|
@NonNull CombinedVibration effect, @Nullable VibrationAttributes attrs,
|
||||||
|
String reason, IBinder token) {
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason = " + reason);
|
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason = " + reason);
|
||||||
try {
|
try {
|
||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.VIBRATE, "vibrate");
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.VIBRATE, "vibrate");
|
||||||
@@ -406,7 +408,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
attrs = fixupVibrationAttributes(attrs, effect);
|
attrs = fixupVibrationAttributes(attrs, effect);
|
||||||
// Create Vibration.Stats as close to the received request as possible, for tracking.
|
// Create Vibration.Stats as close to the received request as possible, for tracking.
|
||||||
Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(), effect, attrs,
|
Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(), effect, attrs,
|
||||||
uid, opPkg, reason);
|
uid, displayId, opPkg, reason);
|
||||||
fillVibrationFallbacks(vib, effect);
|
fillVibrationFallbacks(vib, effect);
|
||||||
|
|
||||||
if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
|
if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
|
||||||
@@ -424,7 +426,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
Vibration.Status status = null;
|
Vibration.Status status = null;
|
||||||
|
|
||||||
// Check if user settings or DnD is set to ignore this vibration.
|
// Check if user settings or DnD is set to ignore this vibration.
|
||||||
status = shouldIgnoreVibrationLocked(vib.uid, vib.opPkg, vib.attrs);
|
status = shouldIgnoreVibrationLocked(vib.uid, vib.displayId, vib.opPkg, vib.attrs);
|
||||||
|
|
||||||
// Check if something has external control, assume it's more important.
|
// Check if something has external control, assume it's more important.
|
||||||
if ((status == null) && (mCurrentExternalVibration != null)) {
|
if ((status == null) && (mCurrentExternalVibration != null)) {
|
||||||
@@ -629,7 +631,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
|
|
||||||
Vibration vib = mCurrentVibration.getVibration();
|
Vibration vib = mCurrentVibration.getVibration();
|
||||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
||||||
vib.uid, vib.opPkg, vib.attrs);
|
vib.uid, vib.displayId, vib.opPkg, vib.attrs);
|
||||||
|
|
||||||
if (inputDevicesChanged || (ignoreStatus != null)) {
|
if (inputDevicesChanged || (ignoreStatus != null)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -659,7 +661,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
||||||
vib.uid, vib.opPkg, vib.attrs);
|
vib.uid, Display.DEFAULT_DISPLAY, vib.opPkg, vib.attrs);
|
||||||
if (ignoreStatus == null) {
|
if (ignoreStatus == null) {
|
||||||
effect = mVibrationScaler.scale(effect, vib.attrs.getUsage());
|
effect = mVibrationScaler.scale(effect, vib.attrs.getUsage());
|
||||||
} else {
|
} else {
|
||||||
@@ -780,6 +782,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
+ attrs);
|
+ attrs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IGNORED_FROM_VIRTUAL_DEVICE:
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.d(TAG, "Ignoring incoming vibration because it came from a virtual"
|
||||||
|
+ " device, attrs= " + attrs);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "Vibration for uid=" + uid + " and with attrs=" + attrs
|
Slog.d(TAG, "Vibration for uid=" + uid + " and with attrs=" + attrs
|
||||||
@@ -894,9 +902,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@Nullable
|
@Nullable
|
||||||
private Vibration.Status shouldIgnoreVibrationLocked(int uid, String opPkg,
|
private Vibration.Status shouldIgnoreVibrationLocked(int uid, int displayId, String opPkg,
|
||||||
VibrationAttributes attrs) {
|
VibrationAttributes attrs) {
|
||||||
Vibration.Status statusFromSettings = mVibrationSettings.shouldIgnoreVibration(uid, attrs);
|
Vibration.Status statusFromSettings = mVibrationSettings.shouldIgnoreVibration(uid,
|
||||||
|
displayId, attrs);
|
||||||
if (statusFromSettings != null) {
|
if (statusFromSettings != null) {
|
||||||
return statusFromSettings;
|
return statusFromSettings;
|
||||||
}
|
}
|
||||||
@@ -1442,6 +1451,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
return new Vibration.DebugInfo(
|
return new Vibration.DebugInfo(
|
||||||
mStatus, stats, /* effect= */ null, /* originalEffect= */ null, scale,
|
mStatus, stats, /* effect= */ null, /* originalEffect= */ null, scale,
|
||||||
externalVibration.getVibrationAttributes(), externalVibration.getUid(),
|
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);
|
externalVibration.getPackage(), /* reason= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1647,8 +1659,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
boolean alreadyUnderExternalControl = false;
|
boolean alreadyUnderExternalControl = false;
|
||||||
boolean waitForCompletion = false;
|
boolean waitForCompletion = false;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
|
// TODO(b/243604888): propagating displayID from IExternalVibration instead of
|
||||||
|
// using INVALID_DISPLAY for all external vibrations.
|
||||||
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
|
||||||
vib.getUid(), vib.getPackage(), attrs);
|
vib.getUid(), Display.INVALID_DISPLAY, vib.getPackage(), attrs);
|
||||||
if (ignoreStatus != null) {
|
if (ignoreStatus != null) {
|
||||||
vibHolder.scale = IExternalVibratorService.SCALE_MUTE;
|
vibHolder.scale = IExternalVibratorService.SCALE_MUTE;
|
||||||
// Failed to start the vibration, end it and report metrics right away.
|
// Failed to start the vibration, end it and report metrics right away.
|
||||||
@@ -1840,8 +1854,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
|
|||||||
// only cancel background vibrations.
|
// only cancel background vibrations.
|
||||||
IBinder deathBinder = commonOptions.background ? VibratorManagerService.this
|
IBinder deathBinder = commonOptions.background ? VibratorManagerService.this
|
||||||
: mShellCallbacksToken;
|
: mShellCallbacksToken;
|
||||||
Vibration vib = vibrateInternal(Binder.getCallingUid(), SHELL_PACKAGE_NAME, combined,
|
Vibration vib = vibrateInternal(Binder.getCallingUid(), Display.DEFAULT_DISPLAY,
|
||||||
attrs, commonOptions.description, deathBinder);
|
SHELL_PACKAGE_NAME, combined, attrs, commonOptions.description, deathBinder);
|
||||||
if (vib != null && !commonOptions.background) {
|
if (vib != null && !commonOptions.background) {
|
||||||
try {
|
try {
|
||||||
vib.waitForEnd();
|
vib.waitForEnd();
|
||||||
|
|||||||
@@ -66,12 +66,15 @@ import android.os.test.TestLooper;
|
|||||||
import android.os.vibrator.VibrationConfig;
|
import android.os.vibrator.VibrationConfig;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
import android.view.Display;
|
||||||
|
|
||||||
import androidx.test.InstrumentationRegistry;
|
import androidx.test.InstrumentationRegistry;
|
||||||
|
|
||||||
import com.android.internal.util.test.FakeSettingsProvider;
|
import com.android.internal.util.test.FakeSettingsProvider;
|
||||||
import com.android.internal.util.test.FakeSettingsProviderRule;
|
import com.android.internal.util.test.FakeSettingsProviderRule;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
|
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -95,6 +98,7 @@ import java.util.Set;
|
|||||||
public class VibrationSettingsTest {
|
public class VibrationSettingsTest {
|
||||||
|
|
||||||
private static final int UID = 1;
|
private static final int UID = 1;
|
||||||
|
private static final int VIRTUAL_DISPLAY_ID = 1;
|
||||||
private static final String SYSUI_PACKAGE_NAME = "sysui";
|
private static final String SYSUI_PACKAGE_NAME = "sysui";
|
||||||
private static final PowerSaveState NORMAL_POWER_STATE = new PowerSaveState.Builder().build();
|
private static final PowerSaveState NORMAL_POWER_STATE = new PowerSaveState.Builder().build();
|
||||||
private static final PowerSaveState LOW_POWER_STATE = new PowerSaveState.Builder()
|
private static final PowerSaveState LOW_POWER_STATE = new PowerSaveState.Builder()
|
||||||
@@ -117,15 +121,23 @@ public class VibrationSettingsTest {
|
|||||||
@Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
|
@Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
|
||||||
|
|
||||||
@Mock private VibrationSettings.OnVibratorSettingsChanged mListenerMock;
|
@Mock private VibrationSettings.OnVibratorSettingsChanged mListenerMock;
|
||||||
@Mock private PowerManagerInternal mPowerManagerInternalMock;
|
@Mock
|
||||||
@Mock private PackageManagerInternal mPackageManagerInternalMock;
|
private PowerManagerInternal mPowerManagerInternalMock;
|
||||||
@Mock private VibrationConfig mVibrationConfigMock;
|
@Mock
|
||||||
|
private VirtualDeviceManagerInternal mVirtualDeviceManagerInternalMock;
|
||||||
|
@Mock
|
||||||
|
private PackageManagerInternal mPackageManagerInternalMock;
|
||||||
|
@Mock
|
||||||
|
private VibrationConfig mVibrationConfigMock;
|
||||||
|
|
||||||
private TestLooper mTestLooper;
|
private TestLooper mTestLooper;
|
||||||
private ContextWrapper mContextSpy;
|
private ContextWrapper mContextSpy;
|
||||||
private AudioManager mAudioManager;
|
private AudioManager mAudioManager;
|
||||||
private VibrationSettings mVibrationSettings;
|
private VibrationSettings mVibrationSettings;
|
||||||
private PowerManagerInternal.LowPowerModeListener mRegisteredPowerModeListener;
|
private PowerManagerInternal.LowPowerModeListener mRegisteredPowerModeListener;
|
||||||
|
private VirtualDeviceManagerInternal.VirtualDisplayListener mRegisteredVirtualDisplayListener;
|
||||||
|
private VirtualDeviceManagerInternal.AppsOnVirtualDeviceListener
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@@ -140,11 +152,17 @@ public class VibrationSettingsTest {
|
|||||||
}).when(mPowerManagerInternalMock).registerLowPowerModeObserver(any());
|
}).when(mPowerManagerInternalMock).registerLowPowerModeObserver(any());
|
||||||
when(mPackageManagerInternalMock.getSystemUiServiceComponent())
|
when(mPackageManagerInternalMock.getSystemUiServiceComponent())
|
||||||
.thenReturn(new ComponentName(SYSUI_PACKAGE_NAME, ""));
|
.thenReturn(new ComponentName(SYSUI_PACKAGE_NAME, ""));
|
||||||
|
doAnswer(invocation -> {
|
||||||
|
mRegisteredVirtualDisplayListener = invocation.getArgument(0);
|
||||||
|
return null;
|
||||||
|
}).when(mVirtualDeviceManagerInternalMock).registerVirtualDisplayListener(any());
|
||||||
|
doAnswer(invocation -> {
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener = invocation.getArgument(0);
|
||||||
|
return null;
|
||||||
|
}).when(mVirtualDeviceManagerInternalMock).registerAppsOnVirtualDeviceListener(any());
|
||||||
|
|
||||||
LocalServices.removeServiceForTest(PowerManagerInternal.class);
|
removeServicesForTest();
|
||||||
LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
|
addServicesForTest();
|
||||||
LocalServices.removeServiceForTest(PackageManagerInternal.class);
|
|
||||||
LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
|
|
||||||
|
|
||||||
setDefaultIntensity(VIBRATION_INTENSITY_MEDIUM);
|
setDefaultIntensity(VIBRATION_INTENSITY_MEDIUM);
|
||||||
mAudioManager = mContextSpy.getSystemService(AudioManager.class);
|
mAudioManager = mContextSpy.getSystemService(AudioManager.class);
|
||||||
@@ -167,6 +185,18 @@ public class VibrationSettingsTest {
|
|||||||
LocalServices.removeServiceForTest(PowerManagerInternal.class);
|
LocalServices.removeServiceForTest(PowerManagerInternal.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void create_withOnlyRequiredSystemServices() {
|
||||||
|
// The only core services that we depend on are PowerManager and PackageManager
|
||||||
|
removeServicesForTest();
|
||||||
|
LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
|
||||||
|
LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
|
||||||
|
|
||||||
|
VibrationSettings minimalVibrationSettings = new VibrationSettings(mContextSpy,
|
||||||
|
new Handler(mTestLooper.getLooper()), mVibrationConfigMock);
|
||||||
|
minimalVibrationSettings.onSystemReady();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addListener_settingsChangeTriggerListener() {
|
public void addListener_settingsChangeTriggerListener() {
|
||||||
mVibrationSettings.addListener(mListenerMock);
|
mVibrationSettings.addListener(mListenerMock);
|
||||||
@@ -446,6 +476,65 @@ public class VibrationSettingsTest {
|
|||||||
assertVibrationIgnoredForUsage(USAGE_RINGTONE, Vibration.Status.IGNORED_FOR_RINGER_MODE);
|
assertVibrationIgnoredForUsage(USAGE_RINGTONE, Vibration.Status.IGNORED_FOR_RINGER_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldIgnoreVibrationFromVirtualDisplays_displayNonVirtual_neverIgnored() {
|
||||||
|
// Vibrations from the primary display is never ignored regardless of the creation and
|
||||||
|
// removal of virtual displays and of the changes of apps running on virtual displays.
|
||||||
|
mRegisteredVirtualDisplayListener.onVirtualDisplayCreated(VIRTUAL_DISPLAY_ID);
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener.onAppsOnAnyVirtualDeviceChanged(
|
||||||
|
new ArraySet<>(Arrays.asList(UID)));
|
||||||
|
for (int usage : ALL_USAGES) {
|
||||||
|
assertVibrationNotIgnoredForUsageAndDisplay(usage, Display.DEFAULT_DISPLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
mRegisteredVirtualDisplayListener.onVirtualDisplayRemoved(VIRTUAL_DISPLAY_ID);
|
||||||
|
for (int usage : ALL_USAGES) {
|
||||||
|
assertVibrationNotIgnoredForUsageAndDisplay(usage, Display.DEFAULT_DISPLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener.onAppsOnAnyVirtualDeviceChanged(new ArraySet<>());
|
||||||
|
for (int usage : ALL_USAGES) {
|
||||||
|
assertVibrationNotIgnoredForUsageAndDisplay(usage, Display.DEFAULT_DISPLAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldIgnoreVibrationFromVirtualDisplays_displayVirtual() {
|
||||||
|
// Ignore the vibration when the coming display id represents a virtual display.
|
||||||
|
mRegisteredVirtualDisplayListener.onVirtualDisplayCreated(VIRTUAL_DISPLAY_ID);
|
||||||
|
|
||||||
|
for (int usage : ALL_USAGES) {
|
||||||
|
assertVibrationIgnoredForUsageAndDisplay(usage, VIRTUAL_DISPLAY_ID,
|
||||||
|
Vibration.Status.IGNORED_FROM_VIRTUAL_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop ignoring when the virtual display is removed.
|
||||||
|
mRegisteredVirtualDisplayListener.onVirtualDisplayRemoved(VIRTUAL_DISPLAY_ID);
|
||||||
|
for (int usage : ALL_USAGES) {
|
||||||
|
assertVibrationNotIgnoredForUsageAndDisplay(usage, VIRTUAL_DISPLAY_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldIgnoreVibrationFromVirtualDisplays_appsOnVirtualDisplay() {
|
||||||
|
// Ignore when the passed-in display id is invalid and the calling uid is on a virtual
|
||||||
|
// display.
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener.onAppsOnAnyVirtualDeviceChanged(
|
||||||
|
new ArraySet<>(Arrays.asList(UID)));
|
||||||
|
for (int usage : ALL_USAGES) {
|
||||||
|
assertVibrationIgnoredForUsageAndDisplay(usage, Display.INVALID_DISPLAY,
|
||||||
|
Vibration.Status.IGNORED_FROM_VIRTUAL_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop ignoring when the app is no longer on virtual display.
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener.onAppsOnAnyVirtualDeviceChanged(new ArraySet<>());
|
||||||
|
for (int usage : ALL_USAGES) {
|
||||||
|
assertVibrationNotIgnoredForUsageAndDisplay(usage, Display.INVALID_DISPLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldVibrateInputDevices_returnsSettingsValue() {
|
public void shouldVibrateInputDevices_returnsSettingsValue() {
|
||||||
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
|
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
|
||||||
@@ -646,11 +735,29 @@ public class VibrationSettingsTest {
|
|||||||
assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_DOUBLE_CLICK));
|
assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_DOUBLE_CLICK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeServicesForTest() {
|
||||||
|
LocalServices.removeServiceForTest(PowerManagerInternal.class);
|
||||||
|
LocalServices.removeServiceForTest(PackageManagerInternal.class);
|
||||||
|
LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addServicesForTest() {
|
||||||
|
LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
|
||||||
|
LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
|
||||||
|
LocalServices.addService(VirtualDeviceManagerInternal.class,
|
||||||
|
mVirtualDeviceManagerInternalMock);
|
||||||
|
}
|
||||||
|
|
||||||
private void assertVibrationIgnoredForUsage(@VibrationAttributes.Usage int usage,
|
private void assertVibrationIgnoredForUsage(@VibrationAttributes.Usage int usage,
|
||||||
Vibration.Status expectedStatus) {
|
Vibration.Status expectedStatus) {
|
||||||
|
assertVibrationIgnoredForUsageAndDisplay(usage, Display.DEFAULT_DISPLAY, expectedStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertVibrationIgnoredForUsageAndDisplay(@VibrationAttributes.Usage int usage,
|
||||||
|
int displayId, Vibration.Status expectedStatus) {
|
||||||
assertEquals(errorMessageForUsage(usage),
|
assertEquals(errorMessageForUsage(usage),
|
||||||
expectedStatus,
|
expectedStatus,
|
||||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
mVibrationSettings.shouldIgnoreVibration(UID, displayId,
|
||||||
VibrationAttributes.createForUsage(usage)));
|
VibrationAttributes.createForUsage(usage)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,8 +767,20 @@ public class VibrationSettingsTest {
|
|||||||
|
|
||||||
private void assertVibrationNotIgnoredForUsageAndFlags(@VibrationAttributes.Usage int usage,
|
private void assertVibrationNotIgnoredForUsageAndFlags(@VibrationAttributes.Usage int usage,
|
||||||
@VibrationAttributes.Flag int flags) {
|
@VibrationAttributes.Flag int flags) {
|
||||||
|
assertVibrationNotIgnoredForUsageAndFlagsAndDidsplay(usage, Display.DEFAULT_DISPLAY, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertVibrationNotIgnoredForUsageAndDisplay(@VibrationAttributes.Usage int usage,
|
||||||
|
int displayId) {
|
||||||
|
assertVibrationNotIgnoredForUsageAndFlagsAndDidsplay(usage, displayId, /* flags= */ 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertVibrationNotIgnoredForUsageAndFlagsAndDidsplay(
|
||||||
|
@VibrationAttributes.Usage int usage, int displayId,
|
||||||
|
@VibrationAttributes.Flag int flags) {
|
||||||
assertNull(errorMessageForUsage(usage),
|
assertNull(errorMessageForUsage(usage),
|
||||||
mVibrationSettings.shouldIgnoreVibration(UID,
|
mVibrationSettings.shouldIgnoreVibration(UID,
|
||||||
|
displayId,
|
||||||
new VibrationAttributes.Builder()
|
new VibrationAttributes.Builder()
|
||||||
.setUsage(usage)
|
.setUsage(usage)
|
||||||
.setFlags(flags)
|
.setFlags(flags)
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ public class VibrationThreadTest {
|
|||||||
|
|
||||||
private static final int TEST_TIMEOUT_MILLIS = 900;
|
private static final int TEST_TIMEOUT_MILLIS = 900;
|
||||||
private static final int UID = Process.ROOT_UID;
|
private static final int UID = Process.ROOT_UID;
|
||||||
|
private static final int DISPLAY_ID = 10;
|
||||||
private static final int VIBRATOR_ID = 1;
|
private static final int VIBRATOR_ID = 1;
|
||||||
private static final String PACKAGE_NAME = "package";
|
private static final String PACKAGE_NAME = "package";
|
||||||
private static final VibrationAttributes ATTRS = new VibrationAttributes.Builder().build();
|
private static final VibrationAttributes ATTRS = new VibrationAttributes.Builder().build();
|
||||||
@@ -1584,7 +1585,8 @@ public class VibrationThreadTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Vibration createVibration(long id, CombinedVibration effect) {
|
private Vibration createVibration(long id, CombinedVibration effect) {
|
||||||
return new Vibration(mVibrationToken, (int) id, effect, ATTRS, UID, PACKAGE_NAME, "reason");
|
return new Vibration(mVibrationToken, (int) id, effect, ATTRS, UID, DISPLAY_ID,
|
||||||
|
PACKAGE_NAME, "reason");
|
||||||
}
|
}
|
||||||
|
|
||||||
private SparseArray<VibratorController> createVibratorControllers() {
|
private SparseArray<VibratorController> createVibratorControllers() {
|
||||||
|
|||||||
@@ -76,7 +76,9 @@ import android.os.vibrator.VibrationConfig;
|
|||||||
import android.os.vibrator.VibrationEffectSegment;
|
import android.os.vibrator.VibrationEffectSegment;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.util.ArraySet;
|
||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
|
import android.view.Display;
|
||||||
import android.view.InputDevice;
|
import android.view.InputDevice;
|
||||||
|
|
||||||
import androidx.test.InstrumentationRegistry;
|
import androidx.test.InstrumentationRegistry;
|
||||||
@@ -86,6 +88,7 @@ import com.android.internal.util.FrameworkStatsLog;
|
|||||||
import com.android.internal.util.test.FakeSettingsProvider;
|
import com.android.internal.util.test.FakeSettingsProvider;
|
||||||
import com.android.internal.util.test.FakeSettingsProviderRule;
|
import com.android.internal.util.test.FakeSettingsProviderRule;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
|
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -115,6 +118,7 @@ public class VibratorManagerServiceTest {
|
|||||||
|
|
||||||
private static final int TEST_TIMEOUT_MILLIS = 1_000;
|
private static final int TEST_TIMEOUT_MILLIS = 1_000;
|
||||||
private static final int UID = Process.ROOT_UID;
|
private static final int UID = Process.ROOT_UID;
|
||||||
|
private static final int VIRTUAL_DISPLAY_ID = 1;
|
||||||
private static final String PACKAGE_NAME = "package";
|
private static final String PACKAGE_NAME = "package";
|
||||||
private static final PowerSaveState NORMAL_POWER_STATE = new PowerSaveState.Builder().build();
|
private static final PowerSaveState NORMAL_POWER_STATE = new PowerSaveState.Builder().build();
|
||||||
private static final PowerSaveState LOW_POWER_STATE = new PowerSaveState.Builder()
|
private static final PowerSaveState LOW_POWER_STATE = new PowerSaveState.Builder()
|
||||||
@@ -153,6 +157,8 @@ public class VibratorManagerServiceTest {
|
|||||||
private IBatteryStats mBatteryStatsMock;
|
private IBatteryStats mBatteryStatsMock;
|
||||||
@Mock
|
@Mock
|
||||||
private VibratorFrameworkStatsLogger mVibratorFrameworkStatsLoggerMock;
|
private VibratorFrameworkStatsLogger mVibratorFrameworkStatsLoggerMock;
|
||||||
|
@Mock
|
||||||
|
private VirtualDeviceManagerInternal mVirtualDeviceManagerInternalMock;
|
||||||
|
|
||||||
private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
|
private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
|
||||||
|
|
||||||
@@ -162,6 +168,9 @@ public class VibratorManagerServiceTest {
|
|||||||
private PowerManagerInternal.LowPowerModeListener mRegisteredPowerModeListener;
|
private PowerManagerInternal.LowPowerModeListener mRegisteredPowerModeListener;
|
||||||
private VibratorManagerService.ExternalVibratorService mExternalVibratorService;
|
private VibratorManagerService.ExternalVibratorService mExternalVibratorService;
|
||||||
private VibrationConfig mVibrationConfig;
|
private VibrationConfig mVibrationConfig;
|
||||||
|
private VirtualDeviceManagerInternal.VirtualDisplayListener mRegisteredVirtualDisplayListener;
|
||||||
|
private VirtualDeviceManagerInternal.AppsOnVirtualDeviceListener
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@@ -186,6 +195,14 @@ public class VibratorManagerServiceTest {
|
|||||||
mRegisteredPowerModeListener = invocation.getArgument(0);
|
mRegisteredPowerModeListener = invocation.getArgument(0);
|
||||||
return null;
|
return null;
|
||||||
}).when(mPowerManagerInternalMock).registerLowPowerModeObserver(any());
|
}).when(mPowerManagerInternalMock).registerLowPowerModeObserver(any());
|
||||||
|
doAnswer(invocation -> {
|
||||||
|
mRegisteredVirtualDisplayListener = invocation.getArgument(0);
|
||||||
|
return null;
|
||||||
|
}).when(mVirtualDeviceManagerInternalMock).registerVirtualDisplayListener(any());
|
||||||
|
doAnswer(invocation -> {
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener = invocation.getArgument(0);
|
||||||
|
return null;
|
||||||
|
}).when(mVirtualDeviceManagerInternalMock).registerAppsOnVirtualDeviceListener(any());
|
||||||
|
|
||||||
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
|
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
|
||||||
setUserSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
|
setUserSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
|
||||||
@@ -202,6 +219,7 @@ public class VibratorManagerServiceTest {
|
|||||||
|
|
||||||
addLocalServiceMock(PackageManagerInternal.class, mPackageManagerInternalMock);
|
addLocalServiceMock(PackageManagerInternal.class, mPackageManagerInternalMock);
|
||||||
addLocalServiceMock(PowerManagerInternal.class, mPowerManagerInternalMock);
|
addLocalServiceMock(PowerManagerInternal.class, mPowerManagerInternalMock);
|
||||||
|
addLocalServiceMock(VirtualDeviceManagerInternal.class, mVirtualDeviceManagerInternalMock);
|
||||||
|
|
||||||
mTestLooper.startAutoDispatch();
|
mTestLooper.startAutoDispatch();
|
||||||
}
|
}
|
||||||
@@ -1166,6 +1184,64 @@ public class VibratorManagerServiceTest {
|
|||||||
assertFalse(waitUntil(s -> !s.isVibrating(1), service, 50));
|
assertFalse(waitUntil(s -> !s.isVibrating(1), service, 50));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void vibrate_withVitualDisplayChange_ignoreVibrationFromVirtualDisplay()
|
||||||
|
throws Exception {
|
||||||
|
mockVibrators(1);
|
||||||
|
VibratorManagerService service = createSystemReadyService();
|
||||||
|
mRegisteredVirtualDisplayListener.onVirtualDisplayCreated(VIRTUAL_DISPLAY_ID);
|
||||||
|
|
||||||
|
vibrateWithDisplay(service,
|
||||||
|
VIRTUAL_DISPLAY_ID,
|
||||||
|
CombinedVibration.startParallel()
|
||||||
|
.addVibrator(1, VibrationEffect.createOneShot(1000, 100))
|
||||||
|
.combine(),
|
||||||
|
HAPTIC_FEEDBACK_ATTRS);
|
||||||
|
|
||||||
|
// Haptic feedback ignored when it's from a virtual display.
|
||||||
|
assertFalse(waitUntil(s -> s.isVibrating(1), service, /* timeout= */ 50));
|
||||||
|
|
||||||
|
mRegisteredVirtualDisplayListener.onVirtualDisplayRemoved(VIRTUAL_DISPLAY_ID);
|
||||||
|
vibrateWithDisplay(service,
|
||||||
|
VIRTUAL_DISPLAY_ID,
|
||||||
|
CombinedVibration.startParallel()
|
||||||
|
.addVibrator(1, VibrationEffect.createOneShot(1000, 100))
|
||||||
|
.combine(),
|
||||||
|
HAPTIC_FEEDBACK_ATTRS);
|
||||||
|
// Haptic feedback played normally when the virtual display is removed.
|
||||||
|
assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void vibrate_withAppsOnVitualDisplayChange_ignoreVibrationFromVirtualDisplay()
|
||||||
|
throws Exception {
|
||||||
|
mockVibrators(1);
|
||||||
|
VibratorManagerService service = createSystemReadyService();
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener.onAppsOnAnyVirtualDeviceChanged(
|
||||||
|
new ArraySet<>(Arrays.asList(UID)));
|
||||||
|
vibrateWithDisplay(service,
|
||||||
|
Display.INVALID_DISPLAY,
|
||||||
|
CombinedVibration.startParallel()
|
||||||
|
.addVibrator(1, VibrationEffect.createOneShot(1000, 100))
|
||||||
|
.combine(),
|
||||||
|
HAPTIC_FEEDBACK_ATTRS);
|
||||||
|
|
||||||
|
// Haptic feedback ignored when it's from an app running virtual display.
|
||||||
|
assertFalse(waitUntil(s -> s.isVibrating(1), service, /* timeout= */ 50));
|
||||||
|
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener.onAppsOnAnyVirtualDeviceChanged(new ArraySet<>());
|
||||||
|
vibrateWithDisplay(service,
|
||||||
|
Display.INVALID_DISPLAY,
|
||||||
|
CombinedVibration.startParallel()
|
||||||
|
.addVibrator(1, VibrationEffect.createOneShot(1000, 100))
|
||||||
|
.combine(),
|
||||||
|
HAPTIC_FEEDBACK_ATTRS);
|
||||||
|
// Haptic feedback played normally when the same app no long runs on a virtual display.
|
||||||
|
assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void cancelVibrate_withoutUsageFilter_stopsVibrating() throws Exception {
|
public void cancelVibrate_withoutUsageFilter_stopsVibrating() throws Exception {
|
||||||
mockVibrators(1);
|
mockVibrators(1);
|
||||||
@@ -1239,6 +1315,24 @@ public class VibratorManagerServiceTest {
|
|||||||
assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
|
assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onExternalVibration_ignoreVibrationFromVirtualDevices() throws Exception {
|
||||||
|
mockVibrators(1);
|
||||||
|
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
|
||||||
|
createSystemReadyService();
|
||||||
|
|
||||||
|
IBinder binderToken = mock(IBinder.class);
|
||||||
|
ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME, AUDIO_ATTRS,
|
||||||
|
mock(IExternalVibrationController.class), binderToken);
|
||||||
|
int scale = mExternalVibratorService.onExternalVibrationStart(externalVibration);
|
||||||
|
assertNotEquals(IExternalVibratorService.SCALE_MUTE, scale);
|
||||||
|
|
||||||
|
mRegisteredAppsOnVirtualDeviceListener.onAppsOnAnyVirtualDeviceChanged(
|
||||||
|
new ArraySet<>(Arrays.asList(UID)));
|
||||||
|
scale = mExternalVibratorService.onExternalVibrationStart(externalVibration);
|
||||||
|
assertEquals(IExternalVibratorService.SCALE_MUTE, scale);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onExternalVibration_setsExternalControl() throws Exception {
|
public void onExternalVibration_setsExternalControl() throws Exception {
|
||||||
mockVibrators(1);
|
mockVibrators(1);
|
||||||
@@ -1820,7 +1914,8 @@ public class VibratorManagerServiceTest {
|
|||||||
private void vibrateAndWaitUntilFinished(VibratorManagerService service,
|
private void vibrateAndWaitUntilFinished(VibratorManagerService service,
|
||||||
CombinedVibration effect, VibrationAttributes attrs) throws InterruptedException {
|
CombinedVibration effect, VibrationAttributes attrs) throws InterruptedException {
|
||||||
Vibration vib =
|
Vibration vib =
|
||||||
service.vibrateInternal(UID, PACKAGE_NAME, effect, attrs, "some reason", service);
|
service.vibrateInternal(UID, Display.DEFAULT_DISPLAY, PACKAGE_NAME, effect, attrs,
|
||||||
|
"some reason", service);
|
||||||
if (vib != null) {
|
if (vib != null) {
|
||||||
vib.waitForEnd();
|
vib.waitForEnd();
|
||||||
}
|
}
|
||||||
@@ -1833,7 +1928,12 @@ public class VibratorManagerServiceTest {
|
|||||||
|
|
||||||
private void vibrate(VibratorManagerService service, CombinedVibration effect,
|
private void vibrate(VibratorManagerService service, CombinedVibration effect,
|
||||||
VibrationAttributes attrs) {
|
VibrationAttributes attrs) {
|
||||||
service.vibrate(UID, PACKAGE_NAME, effect, attrs, "some reason", service);
|
vibrateWithDisplay(service, Display.DEFAULT_DISPLAY, effect, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void vibrateWithDisplay(VibratorManagerService service, int displayId,
|
||||||
|
CombinedVibration effect, VibrationAttributes attrs) {
|
||||||
|
service.vibrate(UID, displayId, PACKAGE_NAME, effect, attrs, "some reason", service);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean waitUntil(Predicate<VibratorManagerService> predicate,
|
private boolean waitUntil(Predicate<VibratorManagerService> predicate,
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import org.junit.runners.JUnit4;
|
|||||||
public class VibratorManagerServicePermissionTest {
|
public class VibratorManagerServicePermissionTest {
|
||||||
|
|
||||||
private static final String PACKAGE_NAME = "com.android.framework.permission.tests";
|
private static final String PACKAGE_NAME = "com.android.framework.permission.tests";
|
||||||
|
private static final int DISPLAY_ID = 1;
|
||||||
private static final CombinedVibration EFFECT =
|
private static final CombinedVibration EFFECT =
|
||||||
CombinedVibration.createParallel(
|
CombinedVibration.createParallel(
|
||||||
VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
|
VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
|
||||||
@@ -106,7 +107,8 @@ public class VibratorManagerServicePermissionTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testVibrateWithoutPermissionFails() throws RemoteException {
|
public void testVibrateWithoutPermissionFails() throws RemoteException {
|
||||||
expectSecurityException("VIBRATE");
|
expectSecurityException("VIBRATE");
|
||||||
mVibratorService.vibrate(Process.myUid(), PACKAGE_NAME, EFFECT, ATTRS, "testVibrate",
|
mVibratorService.vibrate(Process.myUid(), DISPLAY_ID, PACKAGE_NAME, EFFECT, ATTRS,
|
||||||
|
"testVibrate",
|
||||||
new Binder());
|
new Binder());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +117,8 @@ public class VibratorManagerServicePermissionTest {
|
|||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
|
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
|
||||||
Manifest.permission.VIBRATE);
|
Manifest.permission.VIBRATE);
|
||||||
mVibratorService.vibrate(Process.myUid(), PACKAGE_NAME, EFFECT, ATTRS, "testVibrate",
|
mVibratorService.vibrate(Process.myUid(), DISPLAY_ID, PACKAGE_NAME, EFFECT, ATTRS,
|
||||||
|
"testVibrate",
|
||||||
new Binder());
|
new Binder());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +127,8 @@ public class VibratorManagerServicePermissionTest {
|
|||||||
expectSecurityException("UPDATE_APP_OPS_STATS");
|
expectSecurityException("UPDATE_APP_OPS_STATS");
|
||||||
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
|
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
|
||||||
Manifest.permission.VIBRATE);
|
Manifest.permission.VIBRATE);
|
||||||
mVibratorService.vibrate(Process.SYSTEM_UID, "android", EFFECT, ATTRS, "testVibrate",
|
mVibratorService.vibrate(Process.SYSTEM_UID, DISPLAY_ID, "android", EFFECT, ATTRS,
|
||||||
|
"testVibrate",
|
||||||
new Binder());
|
new Binder());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +137,8 @@ public class VibratorManagerServicePermissionTest {
|
|||||||
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
|
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
|
||||||
Manifest.permission.VIBRATE,
|
Manifest.permission.VIBRATE,
|
||||||
Manifest.permission.UPDATE_APP_OPS_STATS);
|
Manifest.permission.UPDATE_APP_OPS_STATS);
|
||||||
mVibratorService.vibrate(Process.SYSTEM_UID, "android", EFFECT, ATTRS, "testVibrate",
|
mVibratorService.vibrate(Process.SYSTEM_UID, DISPLAY_ID, "android", EFFECT, ATTRS,
|
||||||
|
"testVibrate",
|
||||||
new Binder());
|
new Binder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user