Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa0b3e0d authored by Yeabkal Wubshit's avatar Yeabkal Wubshit
Browse files

Optimizations for Vibrator#performHapticFeedback

- Avoid re-computing the UID of the process; compute and cache it when
  the VibratorManager is created.
- Avoid passing the caller's IBinder as a token; the legacy haptic
  feedback path that goes through WindowManager did not do that, so we
  will now start using the VibratorManagerService as the token for
  haptic feedback vibrations.

Code path is already flagged via the `use_vibrator_haptic_feedback` flag
in the `android.os.vibrator` package.

Flag: EXEMPT
Bug: 309612548
Test: manual + shell command works + atest VibratorManagerServiceTest
Change-Id: I0c8602d73705447bec7013ca838bce6e6f784c1f
parent 13db1201
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -41,5 +41,5 @@ interface IVibratorManagerService {
    // There is no order guarantee with respect to the two-way APIs above like
    // vibrate/isVibrating/cancel.
    oneway void performHapticFeedback(int uid, int deviceId, String opPkg, int constant,
            boolean always, String reason, IBinder token);
            boolean always, String reason);
}
+3 −2
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ public class SystemVibratorManager extends VibratorManager {

    private final IVibratorManagerService mService;
    private final Context mContext;
    private final int mUid;
    private final Binder mToken = new Binder();
    private final Object mLock = new Object();
    @GuardedBy("mLock")
@@ -56,6 +57,7 @@ public class SystemVibratorManager extends VibratorManager {
    public SystemVibratorManager(Context context) {
        super(context);
        mContext = context;
        mUid = Process.myUid();
        mService = IVibratorManagerService.Stub.asInterface(
                ServiceManager.getService(Context.VIBRATOR_MANAGER_SERVICE));
    }
@@ -152,8 +154,7 @@ public class SystemVibratorManager extends VibratorManager {
        }
        try {
            mService.performHapticFeedback(
                    Process.myUid(), mContext.getDeviceId(), mPackageName, constant, always, reason,
                    mToken);
                    mUid, mContext.getDeviceId(), mPackageName, constant, always, reason);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to perform haptic feedback.", e);
        }
+7 −3
Original line number Diff line number Diff line
@@ -411,9 +411,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {

    @Override // Binder call
    public void performHapticFeedback(
            int uid, int deviceId, String opPkg, int constant, boolean always, String reason,
            IBinder token) {
        performHapticFeedbackInternal(uid, deviceId, opPkg, constant, always, reason, token);
            int uid, int deviceId, String opPkg, int constant, boolean always, String reason) {
        // Note that the `performHapticFeedback` method does not take a token argument from the
        // caller, and instead, uses this service as the token. This is to mitigate performance
        // impact that would otherwise be caused due to marshal latency. Haptic feedback effects are
        // short-lived, so we don't need to cancel when the process dies.
        performHapticFeedbackInternal(
                uid, deviceId, opPkg, constant, always, reason, /* token= */ this);
    }

    /**
+11 −0
Original line number Diff line number Diff line
@@ -1398,6 +1398,17 @@ public class VibratorManagerServiceTest {
        assertTrue(mVibratorProviders.get(1).getAllEffectSegments().isEmpty());
    }

    @Test
    public void performHapticFeedback_usesServiceAsToken() throws Exception {
        VibratorManagerService service = createSystemReadyService();

        HalVibration vibration =
                performHapticFeedbackAndWaitUntilFinished(
                        service, HapticFeedbackConstants.SCROLL_TICK, /* always= */ true);

        assertTrue(vibration.callerToken == service);
    }

    @Test
    public void vibrate_withIntensitySettings_appliesSettingsToScaleVibrations() throws Exception {
        int defaultNotificationIntensity =