summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Lee Shombert <shombert@google.com> 2025-01-14 13:34:51 -0800
committer Lee Shombert <shombert@google.com> 2025-01-14 13:34:51 -0800
commit94ee6d726a143ea40a574e3a45afe4aa1e022958 (patch)
treee6c5875461242fb871a6b1e7611540130a74e375
parentdd4984e9733e3f3b3e35af8dd4af28aed2634061 (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.java37
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);