Loading services/core/java/com/android/server/vibrator/VendorVibrationSession.java +20 −13 Original line number Diff line number Diff line Loading @@ -176,14 +176,14 @@ final class VendorVibrationSession extends IVibrationSession.Stub @Override public void onCancel() { Slog.d(TAG, "Cancellation signal received, cancelling vibration session..."); Slog.d(TAG, "Session cancellation signal received, aborting vibration session..."); requestEndSession(Status.CANCELLED_BY_USER, /* shouldAbort= */ true, /* isVendorRequest= */ true); } @Override public void binderDied() { Slog.d(TAG, "Binder died, cancelling vibration session..."); Slog.d(TAG, "Session binder died, aborting vibration session..."); requestEndSession(Status.CANCELLED_BINDER_DIED, /* shouldAbort= */ true, /* isVendorRequest= */ false); } Loading Loading @@ -219,18 +219,20 @@ final class VendorVibrationSession extends IVibrationSession.Stub @Override public void notifyVibratorCallback(int vibratorId, long vibrationId) { // Ignore it, the session vibration playback doesn't depend on HAL timings Slog.d(TAG, "Vibration callback received for vibration " + vibrationId + " on vibrator " + vibratorId + ", ignoring..."); } @Override public void notifySyncedVibratorsCallback(long vibrationId) { // Ignore it, the session vibration playback doesn't depend on HAL timings Slog.d(TAG, "Synced vibration callback received for vibration " + vibrationId + ", ignoring..."); } @Override public void notifySessionCallback() { synchronized (mLock) { Slog.d(TAG, "Session callback received, ending vibration session..."); synchronized (mLock) { // If end was not requested then the HAL has cancelled the session. maybeSetEndRequestLocked(Status.CANCELLED_BY_UNKNOWN_REASON, /* isVendorRequest= */ false); Loading Loading @@ -307,7 +309,7 @@ final class VendorVibrationSession extends IVibrationSession.Stub } } if (isAlreadyEnded) { // Session already ended, make sure we end it in the HAL. Slog.d(TAG, "Session already ended after starting the HAL, aborting..."); mHandler.post(() -> mManagerHooks.endSession(mSessionId, /* shouldAbort= */ true)); } } Loading Loading @@ -335,8 +337,8 @@ final class VendorVibrationSession extends IVibrationSession.Stub public boolean maybeSetVibrationConductor(VibrationStepConductor conductor) { synchronized (mLock) { if (mConductor != null) { Slog.d(TAG, "Vibration session still dispatching previous vibration," + " new vibration ignored"); Slog.d(TAG, "Session still dispatching previous vibration, new vibration " + conductor.getVibration().id + " ignored"); return false; } mConductor = conductor; Loading @@ -345,19 +347,22 @@ final class VendorVibrationSession extends IVibrationSession.Stub } private void requestEndSession(Status status, boolean shouldAbort, boolean isVendorRequest) { Slog.d(TAG, "Session end request received with status " + status); boolean shouldTriggerSessionHook = false; synchronized (mLock) { maybeSetEndRequestLocked(status, isVendorRequest); if (isStarted()) { // Always trigger session hook after it has started, in case new request aborts an // already finishing session. Wait for HAL callback before actually ending here. if (!isEnded() && isStarted()) { // Trigger session hook even if it was already triggered, in case a second request // is aborting the ongoing/ending session. This might cause it to end right away. // Wait for HAL callback before setting the end status. shouldTriggerSessionHook = true; } else { // Session did not start in the HAL, end it right away. // Session not active in the HAL, set end status right away. maybeSetStatusToRequestedLocked(); } } if (shouldTriggerSessionHook) { Slog.d(TAG, "Requesting HAL session end with abort=" + shouldAbort); mHandler.post(() -> mManagerHooks.endSession(mSessionId, shouldAbort)); } } Loading @@ -368,6 +373,7 @@ final class VendorVibrationSession extends IVibrationSession.Stub // End already requested, keep first requested status and time. return; } Slog.d(TAG, "Session end request accepted for status " + status); mEndStatusRequest = status; mEndedByVendor = isVendorRequest; mEndTime = System.currentTimeMillis(); Loading Loading @@ -400,6 +406,7 @@ final class VendorVibrationSession extends IVibrationSession.Stub // No end status was requested, nothing to set. return; } Slog.d(TAG, "Session end request applied for status " + mEndStatusRequest); mStatus = mEndStatusRequest; // Run client callback in separate thread. final Status endStatus = mStatus; Loading @@ -407,7 +414,7 @@ final class VendorVibrationSession extends IVibrationSession.Stub try { mCallback.onFinished(toSessionStatus(endStatus)); } catch (RemoteException e) { Slog.e(TAG, "Error notifying vendor session is finishing", e); Slog.e(TAG, "Error notifying vendor session finished", e); } }); } Loading services/core/java/com/android/server/vibrator/VibratorManagerService.java +32 −11 Original line number Diff line number Diff line Loading @@ -786,7 +786,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { synchronized (mLock) { if (DEBUG) { Slog.d(TAG, "Starting session " + session.getSessionId()); Slog.d(TAG, "Starting vendor session " + session.getSessionId()); } Status ignoreStatus = null; Loading Loading @@ -864,13 +864,16 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // Session already ended, possibly cancelled by app cancellation signal. return session.getStatus(); } int mode = startAppOpModeLocked(session.getCallerInfo()); CallerInfo callerInfo = session.getCallerInfo(); int mode = startAppOpModeLocked(callerInfo); switch (mode) { case AppOpsManager.MODE_ALLOWED: Trace.asyncTraceBegin(TRACE_TAG_VIBRATOR, "vibration", 0); // Make sure mCurrentVibration is set while triggering the HAL. mCurrentSession = session; if (!session.linkToDeath()) { // Shouldn't happen. The method call already logs. finishAppOpModeLocked(callerInfo); mCurrentSession = null; return Status.IGNORED_ERROR_TOKEN; } Loading @@ -878,14 +881,14 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { Slog.e(TAG, "Error starting session " + sessionId + " on vibrators " + Arrays.toString(session.getVibratorIds())); session.unlinkToDeath(); finishAppOpModeLocked(callerInfo); mCurrentSession = null; return Status.IGNORED_UNSUPPORTED; } session.notifyStart(); return null; case AppOpsManager.MODE_ERRORED: Slog.w(TAG, "Start AppOpsManager operation errored for uid " + session.getCallerInfo().uid); Slog.w(TAG, "Start AppOpsManager operation errored for uid " + callerInfo.uid); return Status.IGNORED_ERROR_APP_OPS; default: return Status.IGNORED_APP_OPS; Loading Loading @@ -1085,7 +1088,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } VibrationStepConductor conductor = createVibrationStepConductor(session.getVibration()); session.setVibrationConductor(conductor); int mode = startAppOpModeLocked(session.getCallerInfo()); CallerInfo callerInfo = session.getCallerInfo(); int mode = startAppOpModeLocked(callerInfo); switch (mode) { case AppOpsManager.MODE_ALLOWED: Trace.asyncTraceBegin(TRACE_TAG_VIBRATOR, "vibration", 0); Loading @@ -1093,19 +1097,21 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mCurrentSession = session; if (!mCurrentSession.linkToDeath()) { // Shouldn't happen. The method call already logs. finishAppOpModeLocked(callerInfo); mCurrentSession = null; // Aborted. return Status.IGNORED_ERROR_TOKEN; } if (!mVibrationThread.runVibrationOnVibrationThread(conductor)) { // Shouldn't happen. The method call already logs. session.setVibrationConductor(null); // Rejected by thread, clear it in session. mCurrentSession.unlinkToDeath(); finishAppOpModeLocked(callerInfo); mCurrentSession = null; // Aborted. return Status.IGNORED_ERROR_SCHEDULING; } return null; case AppOpsManager.MODE_ERRORED: Slog.w(TAG, "Start AppOpsManager operation errored for uid " + session.getCallerInfo().uid); Slog.w(TAG, "Start AppOpsManager operation errored for uid " + callerInfo.uid); return Status.IGNORED_ERROR_APP_OPS; default: return Status.IGNORED_APP_OPS; Loading Loading @@ -1494,6 +1500,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { private int checkAppOpModeLocked(CallerInfo callerInfo) { int mode = mAppOps.checkAudioOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.attrs.getAudioUsage(), callerInfo.uid, callerInfo.opPkg); if (DEBUG) { int opMode = mAppOps.checkOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg); Slog.d(TAG, "Check AppOp mode VIBRATE for uid " + callerInfo.uid + " and package " + callerInfo.opPkg + " returned audio=" + AppOpsManager.MODE_NAMES[mode] + ", op=" + AppOpsManager.MODE_NAMES[opMode]); } 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 Loading @@ -1507,9 +1520,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /** Start an operation in {@link AppOpsManager}, if allowed. */ @GuardedBy("mLock") private int startAppOpModeLocked(CallerInfo callerInfo) { return fixupAppOpModeLocked( mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg), callerInfo.attrs); int mode = mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg); if (DEBUG) { Slog.d(TAG, "Start AppOp mode VIBRATE for uid " + callerInfo.uid + " and package " + callerInfo.opPkg + " returned " + AppOpsManager.MODE_NAMES[mode]); } return fixupAppOpModeLocked(mode, callerInfo.attrs); } /** Loading @@ -1518,6 +1535,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { */ @GuardedBy("mLock") private void finishAppOpModeLocked(CallerInfo callerInfo) { if (DEBUG) { Slog.d(TAG, "Finish AppOp mode VIBRATE for uid " + callerInfo.uid + " and package " + callerInfo.opPkg); } mAppOps.finishOp(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg); } Loading Loading
services/core/java/com/android/server/vibrator/VendorVibrationSession.java +20 −13 Original line number Diff line number Diff line Loading @@ -176,14 +176,14 @@ final class VendorVibrationSession extends IVibrationSession.Stub @Override public void onCancel() { Slog.d(TAG, "Cancellation signal received, cancelling vibration session..."); Slog.d(TAG, "Session cancellation signal received, aborting vibration session..."); requestEndSession(Status.CANCELLED_BY_USER, /* shouldAbort= */ true, /* isVendorRequest= */ true); } @Override public void binderDied() { Slog.d(TAG, "Binder died, cancelling vibration session..."); Slog.d(TAG, "Session binder died, aborting vibration session..."); requestEndSession(Status.CANCELLED_BINDER_DIED, /* shouldAbort= */ true, /* isVendorRequest= */ false); } Loading Loading @@ -219,18 +219,20 @@ final class VendorVibrationSession extends IVibrationSession.Stub @Override public void notifyVibratorCallback(int vibratorId, long vibrationId) { // Ignore it, the session vibration playback doesn't depend on HAL timings Slog.d(TAG, "Vibration callback received for vibration " + vibrationId + " on vibrator " + vibratorId + ", ignoring..."); } @Override public void notifySyncedVibratorsCallback(long vibrationId) { // Ignore it, the session vibration playback doesn't depend on HAL timings Slog.d(TAG, "Synced vibration callback received for vibration " + vibrationId + ", ignoring..."); } @Override public void notifySessionCallback() { synchronized (mLock) { Slog.d(TAG, "Session callback received, ending vibration session..."); synchronized (mLock) { // If end was not requested then the HAL has cancelled the session. maybeSetEndRequestLocked(Status.CANCELLED_BY_UNKNOWN_REASON, /* isVendorRequest= */ false); Loading Loading @@ -307,7 +309,7 @@ final class VendorVibrationSession extends IVibrationSession.Stub } } if (isAlreadyEnded) { // Session already ended, make sure we end it in the HAL. Slog.d(TAG, "Session already ended after starting the HAL, aborting..."); mHandler.post(() -> mManagerHooks.endSession(mSessionId, /* shouldAbort= */ true)); } } Loading Loading @@ -335,8 +337,8 @@ final class VendorVibrationSession extends IVibrationSession.Stub public boolean maybeSetVibrationConductor(VibrationStepConductor conductor) { synchronized (mLock) { if (mConductor != null) { Slog.d(TAG, "Vibration session still dispatching previous vibration," + " new vibration ignored"); Slog.d(TAG, "Session still dispatching previous vibration, new vibration " + conductor.getVibration().id + " ignored"); return false; } mConductor = conductor; Loading @@ -345,19 +347,22 @@ final class VendorVibrationSession extends IVibrationSession.Stub } private void requestEndSession(Status status, boolean shouldAbort, boolean isVendorRequest) { Slog.d(TAG, "Session end request received with status " + status); boolean shouldTriggerSessionHook = false; synchronized (mLock) { maybeSetEndRequestLocked(status, isVendorRequest); if (isStarted()) { // Always trigger session hook after it has started, in case new request aborts an // already finishing session. Wait for HAL callback before actually ending here. if (!isEnded() && isStarted()) { // Trigger session hook even if it was already triggered, in case a second request // is aborting the ongoing/ending session. This might cause it to end right away. // Wait for HAL callback before setting the end status. shouldTriggerSessionHook = true; } else { // Session did not start in the HAL, end it right away. // Session not active in the HAL, set end status right away. maybeSetStatusToRequestedLocked(); } } if (shouldTriggerSessionHook) { Slog.d(TAG, "Requesting HAL session end with abort=" + shouldAbort); mHandler.post(() -> mManagerHooks.endSession(mSessionId, shouldAbort)); } } Loading @@ -368,6 +373,7 @@ final class VendorVibrationSession extends IVibrationSession.Stub // End already requested, keep first requested status and time. return; } Slog.d(TAG, "Session end request accepted for status " + status); mEndStatusRequest = status; mEndedByVendor = isVendorRequest; mEndTime = System.currentTimeMillis(); Loading Loading @@ -400,6 +406,7 @@ final class VendorVibrationSession extends IVibrationSession.Stub // No end status was requested, nothing to set. return; } Slog.d(TAG, "Session end request applied for status " + mEndStatusRequest); mStatus = mEndStatusRequest; // Run client callback in separate thread. final Status endStatus = mStatus; Loading @@ -407,7 +414,7 @@ final class VendorVibrationSession extends IVibrationSession.Stub try { mCallback.onFinished(toSessionStatus(endStatus)); } catch (RemoteException e) { Slog.e(TAG, "Error notifying vendor session is finishing", e); Slog.e(TAG, "Error notifying vendor session finished", e); } }); } Loading
services/core/java/com/android/server/vibrator/VibratorManagerService.java +32 −11 Original line number Diff line number Diff line Loading @@ -786,7 +786,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { synchronized (mLock) { if (DEBUG) { Slog.d(TAG, "Starting session " + session.getSessionId()); Slog.d(TAG, "Starting vendor session " + session.getSessionId()); } Status ignoreStatus = null; Loading Loading @@ -864,13 +864,16 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // Session already ended, possibly cancelled by app cancellation signal. return session.getStatus(); } int mode = startAppOpModeLocked(session.getCallerInfo()); CallerInfo callerInfo = session.getCallerInfo(); int mode = startAppOpModeLocked(callerInfo); switch (mode) { case AppOpsManager.MODE_ALLOWED: Trace.asyncTraceBegin(TRACE_TAG_VIBRATOR, "vibration", 0); // Make sure mCurrentVibration is set while triggering the HAL. mCurrentSession = session; if (!session.linkToDeath()) { // Shouldn't happen. The method call already logs. finishAppOpModeLocked(callerInfo); mCurrentSession = null; return Status.IGNORED_ERROR_TOKEN; } Loading @@ -878,14 +881,14 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { Slog.e(TAG, "Error starting session " + sessionId + " on vibrators " + Arrays.toString(session.getVibratorIds())); session.unlinkToDeath(); finishAppOpModeLocked(callerInfo); mCurrentSession = null; return Status.IGNORED_UNSUPPORTED; } session.notifyStart(); return null; case AppOpsManager.MODE_ERRORED: Slog.w(TAG, "Start AppOpsManager operation errored for uid " + session.getCallerInfo().uid); Slog.w(TAG, "Start AppOpsManager operation errored for uid " + callerInfo.uid); return Status.IGNORED_ERROR_APP_OPS; default: return Status.IGNORED_APP_OPS; Loading Loading @@ -1085,7 +1088,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } VibrationStepConductor conductor = createVibrationStepConductor(session.getVibration()); session.setVibrationConductor(conductor); int mode = startAppOpModeLocked(session.getCallerInfo()); CallerInfo callerInfo = session.getCallerInfo(); int mode = startAppOpModeLocked(callerInfo); switch (mode) { case AppOpsManager.MODE_ALLOWED: Trace.asyncTraceBegin(TRACE_TAG_VIBRATOR, "vibration", 0); Loading @@ -1093,19 +1097,21 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mCurrentSession = session; if (!mCurrentSession.linkToDeath()) { // Shouldn't happen. The method call already logs. finishAppOpModeLocked(callerInfo); mCurrentSession = null; // Aborted. return Status.IGNORED_ERROR_TOKEN; } if (!mVibrationThread.runVibrationOnVibrationThread(conductor)) { // Shouldn't happen. The method call already logs. session.setVibrationConductor(null); // Rejected by thread, clear it in session. mCurrentSession.unlinkToDeath(); finishAppOpModeLocked(callerInfo); mCurrentSession = null; // Aborted. return Status.IGNORED_ERROR_SCHEDULING; } return null; case AppOpsManager.MODE_ERRORED: Slog.w(TAG, "Start AppOpsManager operation errored for uid " + session.getCallerInfo().uid); Slog.w(TAG, "Start AppOpsManager operation errored for uid " + callerInfo.uid); return Status.IGNORED_ERROR_APP_OPS; default: return Status.IGNORED_APP_OPS; Loading Loading @@ -1494,6 +1500,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { private int checkAppOpModeLocked(CallerInfo callerInfo) { int mode = mAppOps.checkAudioOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.attrs.getAudioUsage(), callerInfo.uid, callerInfo.opPkg); if (DEBUG) { int opMode = mAppOps.checkOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg); Slog.d(TAG, "Check AppOp mode VIBRATE for uid " + callerInfo.uid + " and package " + callerInfo.opPkg + " returned audio=" + AppOpsManager.MODE_NAMES[mode] + ", op=" + AppOpsManager.MODE_NAMES[opMode]); } 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 Loading @@ -1507,9 +1520,13 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /** Start an operation in {@link AppOpsManager}, if allowed. */ @GuardedBy("mLock") private int startAppOpModeLocked(CallerInfo callerInfo) { return fixupAppOpModeLocked( mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg), callerInfo.attrs); int mode = mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg); if (DEBUG) { Slog.d(TAG, "Start AppOp mode VIBRATE for uid " + callerInfo.uid + " and package " + callerInfo.opPkg + " returned " + AppOpsManager.MODE_NAMES[mode]); } return fixupAppOpModeLocked(mode, callerInfo.attrs); } /** Loading @@ -1518,6 +1535,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { */ @GuardedBy("mLock") private void finishAppOpModeLocked(CallerInfo callerInfo) { if (DEBUG) { Slog.d(TAG, "Finish AppOp mode VIBRATE for uid " + callerInfo.uid + " and package " + callerInfo.opPkg); } mAppOps.finishOp(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg); } Loading