1e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn/* 2e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project 3e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * 4e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * you may not use this file except in compliance with the License. 6e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * You may obtain a copy of the License at 7e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * 8e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * 10e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * See the License for the specific language governing permissions and 14e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * limitations under the License. 15e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn */ 16e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 17cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackbornpackage com.android.internal.os; 18e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 19850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkeyimport java.io.Closeable; 20e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.FileDescriptor; 21e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.FileInputStream; 22e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.FileOutputStream; 23e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.IOException; 24e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 25e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.Binder; 26e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.IBinder; 27e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.IInterface; 28e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.ParcelFileDescriptor; 29e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.RemoteException; 30e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.SystemClock; 31e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.util.Slog; 32e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 33e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn/** 34e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * Helper for transferring data through a pipe from a client app. 35e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn */ 36850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkeypublic final class TransferPipe implements Runnable, Closeable { 37e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static final String TAG = "TransferPipe"; 38e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static final boolean DEBUG = false; 39e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 40e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static final long DEFAULT_TIMEOUT = 5000; // 5 seconds 41e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 42850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey final Thread mThread; 43e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn final ParcelFileDescriptor[] mFds; 44e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 45e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn FileDescriptor mOutFd; 46e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn long mEndTime; 47e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String mFailure; 48e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn boolean mComplete; 49e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 50e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String mBufferPrefix; 51e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 52e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn interface Caller { 53e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn void go(IInterface iface, FileDescriptor fd, String prefix, 54e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String[] args) throws RemoteException; 55e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 56e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 57cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn public TransferPipe() throws IOException { 58850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey this(null); 59850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey } 60850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey 61850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey public TransferPipe(String bufferPrefix) throws IOException { 62e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mThread = new Thread(this, "TransferPipe"); 63e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mFds = ParcelFileDescriptor.createPipe(); 64850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey mBufferPrefix = bufferPrefix; 65e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 66e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 67e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn ParcelFileDescriptor getReadFd() { 68e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return mFds[0]; 69e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 70e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 71cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn public ParcelFileDescriptor getWriteFd() { 72e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return mFds[1]; 73e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 74e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 75cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn public void setBufferPrefix(String prefix) { 76e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mBufferPrefix = prefix; 77e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 78e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 79850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey public static void dumpAsync(IBinder binder, FileDescriptor out, String[] args) 80850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey throws IOException, RemoteException { 81850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey goDump(binder, out, args); 82850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey } 83850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey 84e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static void go(Caller caller, IInterface iface, FileDescriptor out, 85e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String prefix, String[] args) throws IOException, RemoteException { 86e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT); 87e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 88e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 89e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static void go(Caller caller, IInterface iface, FileDescriptor out, 90e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String prefix, String[] args, long timeout) throws IOException, RemoteException { 91e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if ((iface.asBinder()) instanceof Binder) { 92e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn // This is a local object... just call it directly. 93e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 94e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn caller.go(iface, out, prefix, args); 95e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (RemoteException e) { 96e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 97e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return; 98e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 99e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 100850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey try (TransferPipe tp = new TransferPipe()) { 101e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn caller.go(iface, tp.getWriteFd().getFileDescriptor(), prefix, args); 102e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn tp.go(out, timeout); 103e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 104e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 105e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 106e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static void goDump(IBinder binder, FileDescriptor out, 107e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String[] args) throws IOException, RemoteException { 108e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn goDump(binder, out, args, DEFAULT_TIMEOUT); 109e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 110e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 111e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static void goDump(IBinder binder, FileDescriptor out, 112e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String[] args, long timeout) throws IOException, RemoteException { 113e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (binder instanceof Binder) { 114e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn // This is a local object... just call it directly. 115e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 116e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn binder.dump(out, args); 117e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (RemoteException e) { 118e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 119e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return; 120e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 121e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 122850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey try (TransferPipe tp = new TransferPipe()) { 123e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn binder.dumpAsync(tp.getWriteFd().getFileDescriptor(), args); 124e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn tp.go(out, timeout); 125e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 126e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 127e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 128cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn public void go(FileDescriptor out) throws IOException { 129e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn go(out, DEFAULT_TIMEOUT); 130e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 131e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 132cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn public void go(FileDescriptor out, long timeout) throws IOException { 133e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 134e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn synchronized (this) { 135e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mOutFd = out; 136e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mEndTime = SystemClock.uptimeMillis() + timeout; 137e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 138e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "read=" + getReadFd() + " write=" + getWriteFd() 139e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn + " out=" + out); 140e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 141e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn // Close the write fd, so we know when the other side is done. 142e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn closeFd(1); 143e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 144e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mThread.start(); 145e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 146e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn while (mFailure == null && !mComplete) { 147e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn long waitTime = mEndTime - SystemClock.uptimeMillis(); 148e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (waitTime <= 0) { 149e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "TIMEOUT!"); 150e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mThread.interrupt(); 151e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn throw new IOException("Timeout"); 152e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 153e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 154e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 155e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn wait(waitTime); 156e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (InterruptedException e) { 157e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 158e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 159e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 160e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Finished: " + mFailure); 161e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (mFailure != null) { 162e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn throw new IOException(mFailure); 163e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 164e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 165e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } finally { 166e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn kill(); 167e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 168e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 169e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 170e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn void closeFd(int num) { 171e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (mFds[num] != null) { 172e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Closing: " + mFds[num]); 173e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 174e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mFds[num].close(); 175e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (IOException e) { 176e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 177e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mFds[num] = null; 178e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 179e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 180e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 181850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey @Override 182850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey public void close() { 183850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey kill(); 184850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey } 185850c83e6da3b34a4eab804133420247fc9dbb8a1Jeff Sharkey 186cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn public void kill() { 1875ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan synchronized (this) { 1885ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan closeFd(0); 1895ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan closeFd(1); 1905ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan } 191e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 192e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 193e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn @Override 194e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn public void run() { 195e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn final byte[] buffer = new byte[1024]; 1965ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan final FileInputStream fis; 1975ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan final FileOutputStream fos; 1985ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan 1995ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan synchronized (this) { 2005ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan ParcelFileDescriptor readFd = getReadFd(); 2015ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan if (readFd == null) { 2025ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan Slog.w(TAG, "Pipe has been closed..."); 2035ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan return; 2045ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan } 2055ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan fis = new FileInputStream(readFd.getFileDescriptor()); 2065ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan fos = new FileOutputStream(mOutFd); 2075ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan } 208e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 209e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Ready to read pipe..."); 210e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn byte[] bufferPrefix = null; 211e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn boolean needPrefix = true; 212e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (mBufferPrefix != null) { 213e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn bufferPrefix = mBufferPrefix.getBytes(); 214e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 215e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 216e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn int size; 217e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 218e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn while ((size=fis.read(buffer)) > 0) { 219e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Got " + size + " bytes"); 220e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (bufferPrefix == null) { 221e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn fos.write(buffer, 0, size); 222e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } else { 223e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn int start = 0; 224e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn for (int i=0; i<size; i++) { 225e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (buffer[i] != '\n') { 226e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (i > start) { 227e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn fos.write(buffer, start, i-start); 228e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 229e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn start = i; 230e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (needPrefix) { 231e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn fos.write(bufferPrefix); 232e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn needPrefix = false; 233e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 234e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn do { 235e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn i++; 236e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } while (i<size && buffer[i] != '\n'); 237e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (i < size) { 238e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn needPrefix = true; 239e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 240e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 241e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 242e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (size > start) { 243e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn fos.write(buffer, start, size-start); 244e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 245e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 246e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 247e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "End of pipe: size=" + size); 248e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (mThread.isInterrupted()) { 249e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Interrupted!"); 250e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 251e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (IOException e) { 252e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn synchronized (this) { 253e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mFailure = e.toString(); 254e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn notifyAll(); 255e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return; 256e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 257e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 258e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 259e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn synchronized (this) { 260e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mComplete = true; 261e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn notifyAll(); 262e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 263e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 264e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn} 265