diff options
author | 2025-01-14 13:34:51 -0800 | |
---|---|---|
committer | 2025-01-14 13:34:51 -0800 | |
commit | 94ee6d726a143ea40a574e3a45afe4aa1e022958 (patch) | |
tree | e6c5875461242fb871a6b1e7611540130a74e375 | |
parent | dd4984e9733e3f3b3e35af8dd4af28aed2634061 (diff) |
Dispatch pending events outside a lock
This minimizes the time that dispatchPending() holds the mCallback
lock. mPendingEvents (which is guarded by mCallback) is copied to an
array inside the lock. Any pending events are then transmitted
outside the lock. This is done so that, if the client is frozen
during transmission (unlikely), the binder callback will not be
blocked.
Flag: com.android.server.am.defer_display_events_when_frozen
Bug: 298055811
Test: atest
* DisplayServiceTests
* CtsDisplayTestCases
Change-Id: Iaeedd8d67caba44dd0a0517316f39bb8d756ea17
-rw-r--r-- | services/core/java/com/android/server/display/DisplayManagerService.java | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index ca001b9c7e6d..a37e9c3ac1b8 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -4382,26 +4382,29 @@ public final class DisplayManagerService extends SystemService { // would be unusual to do so. The method returns true on success. // This is only used if {@link deferDisplayEventsWhenFrozen()} is true. public boolean dispatchPending() { + Event[] pending; + synchronized (mCallback) { + if (mPendingEvents == null || mPendingEvents.isEmpty() || !mAlive) { + return true; + } + if (!isReadyLocked()) { + return false; + } + pending = new Event[mPendingEvents.size()]; + pending = mPendingEvents.toArray(pending); + mPendingEvents.clear(); + } try { - synchronized (mCallback) { - if (mPendingEvents == null || mPendingEvents.isEmpty() || !mAlive) { - return true; - } - if (!isReadyLocked()) { - return false; - } - for (int i = 0; i < mPendingEvents.size(); i++) { - Event displayEvent = mPendingEvents.get(i); - if (DEBUG) { - Slog.d(TAG, "Send pending display event #" + i + " " - + displayEvent.displayId + "/" - + displayEvent.event + " to " + mUid + "/" + mPid); - } - transmitDisplayEvent(displayEvent.displayId, displayEvent.event); + for (int i = 0; i < pending.length; i++) { + Event displayEvent = pending[i]; + if (DEBUG) { + Slog.d(TAG, "Send pending display event #" + i + " " + + displayEvent.displayId + "/" + + displayEvent.event + " to " + mUid + "/" + mPid); } - mPendingEvents.clear(); - return true; + transmitDisplayEvent(displayEvent.displayId, displayEvent.event); } + return true; } catch (RemoteException ex) { Slog.w(TAG, "Failed to notify process " + mPid + " that display topology changed, assuming it died.", ex); |