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
19e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.FileDescriptor;
20e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.FileInputStream;
21e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.FileOutputStream;
22e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.IOException;
23e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
24e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.Binder;
25e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.IBinder;
26e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.IInterface;
27e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.ParcelFileDescriptor;
28e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.RemoteException;
29e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.SystemClock;
30e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.util.Slog;
31e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
32e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn/**
33e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * Helper for transferring data through a pipe from a client app.
34e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn */
35cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackbornpublic final class TransferPipe implements Runnable {
36e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    static final String TAG = "TransferPipe";
37e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    static final boolean DEBUG = false;
38e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
39e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    static final long DEFAULT_TIMEOUT = 5000;  // 5 seconds
40e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
41e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    final Thread mThread;;
42e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    final ParcelFileDescriptor[] mFds;
43e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
44e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    FileDescriptor mOutFd;
45e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    long mEndTime;
46e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    String mFailure;
47e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    boolean mComplete;
48e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
49e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    String mBufferPrefix;
50e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
51e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    interface Caller {
52e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        void go(IInterface iface, FileDescriptor fd, String prefix,
53e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                String[] args) throws RemoteException;
54e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
55e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
56cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn    public TransferPipe() throws IOException {
57e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        mThread = new Thread(this, "TransferPipe");
58e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        mFds = ParcelFileDescriptor.createPipe();
59e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
60e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
61e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    ParcelFileDescriptor getReadFd() {
62e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        return mFds[0];
63e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
64e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
65cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn    public ParcelFileDescriptor getWriteFd() {
66e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        return mFds[1];
67e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
68e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
69cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn    public void setBufferPrefix(String prefix) {
70e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        mBufferPrefix = prefix;
71e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
72e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
73e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    static void go(Caller caller, IInterface iface, FileDescriptor out,
74e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            String prefix, String[] args) throws IOException, RemoteException {
75e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT);
76e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
77e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
78e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    static void go(Caller caller, IInterface iface, FileDescriptor out,
79e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            String prefix, String[] args, long timeout) throws IOException, RemoteException {
80e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        if ((iface.asBinder()) instanceof Binder) {
81e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            // This is a local object...  just call it directly.
82e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            try {
83e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                caller.go(iface, out, prefix, args);
84e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            } catch (RemoteException e) {
85e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            }
86e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            return;
87e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        }
88e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
89e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        TransferPipe tp = new TransferPipe();
90e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        try {
91e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            caller.go(iface, tp.getWriteFd().getFileDescriptor(), prefix, args);
92e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            tp.go(out, timeout);
93e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        } finally {
94e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            tp.kill();
95e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        }
96e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
97e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
98e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    static void goDump(IBinder binder, FileDescriptor out,
99e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            String[] args) throws IOException, RemoteException {
100e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        goDump(binder, out, args, DEFAULT_TIMEOUT);
101e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
102e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
103e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    static void goDump(IBinder binder, FileDescriptor out,
104e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            String[] args, long timeout) throws IOException, RemoteException {
105e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        if (binder instanceof Binder) {
106e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            // This is a local object...  just call it directly.
107e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            try {
108e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                binder.dump(out, args);
109e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            } catch (RemoteException e) {
110e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            }
111e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            return;
112e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        }
113e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
114e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        TransferPipe tp = new TransferPipe();
115e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        try {
116e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            binder.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
117e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            tp.go(out, timeout);
118e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        } finally {
119e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            tp.kill();
120e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        }
121e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
122e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
123cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn    public void go(FileDescriptor out) throws IOException {
124e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        go(out, DEFAULT_TIMEOUT);
125e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
126e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
127cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn    public void go(FileDescriptor out, long timeout) throws IOException {
128e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        try {
129e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            synchronized (this) {
130e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                mOutFd = out;
131e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                mEndTime = SystemClock.uptimeMillis() + timeout;
132e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
133e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                if (DEBUG) Slog.i(TAG, "read=" + getReadFd() + " write=" + getWriteFd()
134e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                        + " out=" + out);
135e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
136e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                // Close the write fd, so we know when the other side is done.
137e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                closeFd(1);
138e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
139e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                mThread.start();
140e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
141e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                while (mFailure == null && !mComplete) {
142e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    long waitTime = mEndTime - SystemClock.uptimeMillis();
143e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    if (waitTime <= 0) {
144e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                        if (DEBUG) Slog.i(TAG, "TIMEOUT!");
145e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                        mThread.interrupt();
146e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                        throw new IOException("Timeout");
147e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    }
148e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
149e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    try {
150e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                        wait(waitTime);
151e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    } catch (InterruptedException e) {
152e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    }
153e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                }
154e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
155e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                if (DEBUG) Slog.i(TAG, "Finished: " + mFailure);
156e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                if (mFailure != null) {
157e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    throw new IOException(mFailure);
158e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                }
159e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            }
160e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        } finally {
161e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            kill();
162e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        }
163e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
164e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
165e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    void closeFd(int num) {
166e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        if (mFds[num] != null) {
167e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            if (DEBUG) Slog.i(TAG, "Closing: " + mFds[num]);
168e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            try {
169e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                mFds[num].close();
170e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            } catch (IOException e) {
171e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            }
172e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            mFds[num] = null;
173e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        }
174e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
175e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
176cbfd23ee6f14445c3e17c5169abbc80c216fa137Dianne Hackborn    public void kill() {
1775ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan        synchronized (this) {
1785ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan            closeFd(0);
1795ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan            closeFd(1);
1805ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan        }
181e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
182e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
183e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    @Override
184e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    public void run() {
185e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        final byte[] buffer = new byte[1024];
1865ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan        final FileInputStream fis;
1875ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan        final FileOutputStream fos;
1885ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan
1895ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan        synchronized (this) {
1905ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan            ParcelFileDescriptor readFd = getReadFd();
1915ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan            if (readFd == null) {
1925ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan                Slog.w(TAG, "Pipe has been closed...");
1935ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan                return;
1945ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan            }
1955ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan            fis = new FileInputStream(readFd.getFileDescriptor());
1965ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan            fos = new FileOutputStream(mOutFd);
1975ec679a0fa2e26c058a8094836d80e4e989f74d5Xin Guan        }
198e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
199e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        if (DEBUG) Slog.i(TAG, "Ready to read pipe...");
200e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        byte[] bufferPrefix = null;
201e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        boolean needPrefix = true;
202e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        if (mBufferPrefix != null) {
203e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            bufferPrefix = mBufferPrefix.getBytes();
204e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        }
205e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
206e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        int size;
207e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        try {
208e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            while ((size=fis.read(buffer)) > 0) {
209e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                if (DEBUG) Slog.i(TAG, "Got " + size + " bytes");
210e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                if (bufferPrefix == null) {
211e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    fos.write(buffer, 0, size);
212e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                } else {
213e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    int start = 0;
214e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    for (int i=0; i<size; i++) {
215e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                        if (buffer[i] != '\n') {
216e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                            if (i > start) {
217e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                                fos.write(buffer, start, i-start);
218e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                            }
219e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                            start = i;
220e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                            if (needPrefix) {
221e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                                fos.write(bufferPrefix);
222e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                                needPrefix = false;
223e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                            }
224e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                            do {
225e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                                i++;
226e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                            } while (i<size && buffer[i] != '\n');
227e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                            if (i < size) {
228e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                                needPrefix = true;
229e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                            }
230e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                        }
231e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    }
232e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    if (size > start) {
233e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                        fos.write(buffer, start, size-start);
234e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                    }
235e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                }
236e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            }
237e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            if (DEBUG) Slog.i(TAG, "End of pipe: size=" + size);
238e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            if (mThread.isInterrupted()) {
239e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                if (DEBUG) Slog.i(TAG, "Interrupted!");
240e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            }
241e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        } catch (IOException e) {
242e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            synchronized (this) {
243e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                mFailure = e.toString();
244e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                notifyAll();
245e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn                return;
246e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            }
247e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        }
248e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn
249e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        synchronized (this) {
250e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            mComplete = true;
251e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn            notifyAll();
252e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn        }
253e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn    }
254e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn}
255