summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java50
1 files changed, 33 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 11660a59afe6..3e4f37b92a27 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -130,6 +130,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.function.BiConsumer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -216,6 +218,7 @@ public class LauncherAppsService extends SystemService {
private final ShortcutChangeHandler mShortcutChangeHandler;
private final Handler mCallbackHandler;
+ private final ExecutorService mOnDumpExecutor = Executors.newSingleThreadExecutor();
private PackageInstallerService mPackageInstallerService;
@@ -1569,24 +1572,37 @@ public class LauncherAppsService extends SystemService {
*/
private void forEachViewCaptureWindow(
@NonNull BiConsumer<String, InputStream> outputtingConsumer) {
- for (int i = mDumpCallbacks.beginBroadcast() - 1; i >= 0; i--) {
- String packageName = (String) mDumpCallbacks.getBroadcastCookie(i);
- String fileName = WM_TRACE_DIR + packageName + "_" + i + VC_FILE_SUFFIX;
-
- try {
- // Order is important here. OnDump needs to be called before the BiConsumer
- // accepts & starts blocking on reading the input stream.
- ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
- mDumpCallbacks.getBroadcastItem(i).onDump(pipe[1]);
-
- InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pipe[0]);
- outputtingConsumer.accept(fileName, is);
- is.close();
- } catch (Exception e) {
- Log.d(TAG, "failed to pipe view capture data", e);
- }
+ try {
+ // This multi-threading prevents ctrl-C command line command aborting from putting
+ // the mDumpCallbacks RemoteCallbackList in a bad Broadcast state. We need to wait
+ // for it to complete even though it is on a background thread.
+ mOnDumpExecutor.submit(() -> {
+ try {
+ for (int i = mDumpCallbacks.beginBroadcast() - 1; i >= 0; i--) {
+ String packageName = (String) mDumpCallbacks.getBroadcastCookie(i);
+ String fileName = WM_TRACE_DIR + packageName + "_" + i + VC_FILE_SUFFIX;
+
+ try {
+ // Order is important here. OnDump needs to be called before the
+ // BiConsumer accepts & starts blocking on reading the input stream.
+ ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+ mDumpCallbacks.getBroadcastItem(i).onDump(pipe[1]);
+
+ InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
+ pipe[0]);
+ outputtingConsumer.accept(fileName, is);
+ is.close();
+ } catch (Exception e) {
+ Log.d(TAG, "failed to pipe view capture data", e);
+ }
+ }
+ } finally {
+ mDumpCallbacks.finishBroadcast();
+ }
+ }).get();
+ } catch (InterruptedException | ExecutionException e) {
+ Log.e(TAG, "background work was interrupted", e);
}
- mDumpCallbacks.finishBroadcast();
}
@RequiresPermission(READ_FRAME_BUFFER)