diff options
| author | 2017-08-29 09:59:08 -0700 | |
|---|---|---|
| committer | 2017-08-29 10:15:07 -0700 | |
| commit | 4b89d63b63d936e7ec71eafab92f5810f55014ef (patch) | |
| tree | f6ae28a28eec9d177cc68c6ec277b89ca58cb80d | |
| parent | 9f5e99159056da901aefc4ac4ff26aa382a23765 (diff) | |
Don't dump print state while holding lock
This causes ANRs as we are trying to the the print spooler connection
while holding a lock that can also be aquired on the system server's
main thread.
Fixes: 63159459
Test: cts-tradefed run singleCommand cts-dev -m Print
adb shell dumpsys print
incident_report print
Change-Id: I228fc5ddc10c1c89f61e8a6d8eb8ea9e384197a8
| -rw-r--r-- | services/print/java/com/android/server/print/PrintManagerService.java | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java index 6a6b542f9bb6..71ba685b99c9 100644 --- a/services/print/java/com/android/server/print/PrintManagerService.java +++ b/services/print/java/com/android/server/print/PrintManagerService.java @@ -63,6 +63,7 @@ import com.android.server.SystemService; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -645,7 +646,6 @@ public final class PrintManagerService extends SystemService { int opti = 0; boolean dumpAsProto = false; - int user = UserHandle.USER_ALL; while (opti < args.length) { String opt = args[opti]; if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { @@ -659,48 +659,47 @@ public final class PrintManagerService extends SystemService { } } + ArrayList<UserState> userStatesToDump = new ArrayList<>(); synchronized (mLock) { - final long identity = Binder.clearCallingIdentity(); - try { - if (dumpAsProto) { - dumpLocked(new ProtoOutputStream(fd), UserHandle.of(user)); - } else { - dumpLocked(fd, pw, UserHandle.of(user)); - } - } finally { - Binder.restoreCallingIdentity(identity); + int numUserStates = mUserStates.size(); + for (int i = 0; i < numUserStates; i++) { + userStatesToDump.add(mUserStates.valueAt(i)); + } + } + + final long identity = Binder.clearCallingIdentity(); + try { + if (dumpAsProto) { + dump(new ProtoOutputStream(fd), userStatesToDump); + } else { + dump(fd, pw, userStatesToDump); } + } finally { + Binder.restoreCallingIdentity(identity); } } - private void dumpLocked(@NonNull ProtoOutputStream proto, @NonNull UserHandle user) { - final int userStateCount = mUserStates.size(); + private void dump(@NonNull ProtoOutputStream proto, + @NonNull ArrayList<UserState> userStatesToDump) { + final int userStateCount = userStatesToDump.size(); for (int i = 0; i < userStateCount; i++) { - UserState userState = mUserStates.valueAt(i); - - if (user.equals(UserHandle.ALL) || mUserStates.keyAt(i) == user.getIdentifier()) { - long token = proto.start(PrintServiceDumpProto.USER_STATES); - userState.dump(proto); - proto.end(token); - } + long token = proto.start(PrintServiceDumpProto.USER_STATES); + userStatesToDump.get(i).dump(proto); + proto.end(token); } proto.flush(); } - private void dumpLocked(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, - @NonNull UserHandle user) { + private void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, + @NonNull ArrayList<UserState> userStatesToDump) { pw = Preconditions.checkNotNull(pw); pw.println("PRINT MANAGER STATE (dumpsys print)"); - final int userStateCount = mUserStates.size(); + final int userStateCount = userStatesToDump.size(); for (int i = 0; i < userStateCount; i++) { - UserState userState = mUserStates.valueAt(i); - - if (user.equals(UserHandle.ALL) || mUserStates.keyAt(i) == user.getIdentifier()) { - userState.dump(fd, pw, ""); - pw.println(); - } + userStatesToDump.get(i).dump(fd, pw, ""); + pw.println(); } } |