summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Philip P. Moltmann <moltmann@google.com> 2017-08-29 09:59:08 -0700
committer Philip P. Moltmann <moltmann@google.com> 2017-08-29 10:15:07 -0700
commit4b89d63b63d936e7ec71eafab92f5810f55014ef (patch)
treef6ae28a28eec9d177cc68c6ec277b89ca58cb80d
parent9f5e99159056da901aefc4ac4ff26aa382a23765 (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.java55
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();
}
}