From 14e260125e951c2c6372dae80b603996cbb4d362 Mon Sep 17 00:00:00 2001 From: Guang Zhu Date: Wed, 18 Mar 2015 20:54:46 -0700 Subject: [PATCH] pass stream contents in separate thread for executeShellCommand Doing it in binder thread will cause deadlock if stdout of process under execution is larger than buffer of java.lang.Runtime#exec(String). Bug: 19829679 Change-Id: Icf0fccd3e2e80b0db4cc1115e501f79066adf091 --- .../android/app/UiAutomationConnection.java | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index 81bcb3913aa27..9ba6a8ef12675 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -227,7 +227,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { } @Override - public void executeShellCommand(String command, ParcelFileDescriptor sink) + public void executeShellCommand(final String command, final ParcelFileDescriptor sink) throws RemoteException { synchronized (mLock) { throwIfCalledByNotTrustedUidLocked(); @@ -235,30 +235,35 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { throwIfNotConnectedLocked(); } - InputStream in = null; - OutputStream out = null; + Thread streamReader = new Thread() { + public void run() { + InputStream in = null; + OutputStream out = null; - try { - java.lang.Process process = Runtime.getRuntime().exec(command); + try { + java.lang.Process process = Runtime.getRuntime().exec(command); - in = process.getInputStream(); - out = new FileOutputStream(sink.getFileDescriptor()); + in = process.getInputStream(); + out = new FileOutputStream(sink.getFileDescriptor()); - final byte[] buffer = new byte[8192]; - while (true) { - final int readByteCount = in.read(buffer); - if (readByteCount < 0) { - break; + final byte[] buffer = new byte[8192]; + while (true) { + final int readByteCount = in.read(buffer); + if (readByteCount < 0) { + break; + } + out.write(buffer, 0, readByteCount); + } + } catch (IOException ioe) { + throw new RuntimeException("Error running shell command", ioe); + } finally { + IoUtils.closeQuietly(in); + IoUtils.closeQuietly(out); + IoUtils.closeQuietly(sink); } - out.write(buffer, 0, readByteCount); - } - } catch (IOException ioe) { - throw new RuntimeException("Error running shell command", ioe); - } finally { - IoUtils.closeQuietly(in); - IoUtils.closeQuietly(out); - IoUtils.closeQuietly(sink); - } + }; + }; + streamReader.start(); } @Override