FileDocCategorySizeDatePackage
TransferPipe.javaAPI DocAndroid 5.1 API7872Thu Mar 12 22:22:10 GMT 2015com.android.internal.os

TransferPipe

public final class TransferPipe extends Object implements Runnable
Helper for transferring data through a pipe from a client app.

Fields Summary
static final String
TAG
static final boolean
DEBUG
static final long
DEFAULT_TIMEOUT
final Thread
mThread
final android.os.ParcelFileDescriptor[]
mFds
FileDescriptor
mOutFd
long
mEndTime
String
mFailure
boolean
mComplete
String
mBufferPrefix
Constructors Summary
public TransferPipe()


      
              
                   
    

        
        mThread = new Thread(this, "TransferPipe");
        mFds = ParcelFileDescriptor.createPipe();
    
Methods Summary
voidcloseFd(int num)

        if (mFds[num] != null) {
            if (DEBUG) Slog.i(TAG, "Closing: " + mFds[num]);
            try {
                mFds[num].close();
            } catch (IOException e) {
            }
            mFds[num] = null;
        }
    
android.os.ParcelFileDescriptorgetReadFd()

        return mFds[0];
    
public android.os.ParcelFileDescriptorgetWriteFd()

        return mFds[1];
    
public voidgo(java.io.FileDescriptor out, long timeout)

        try {
            synchronized (this) {
                mOutFd = out;
                mEndTime = SystemClock.uptimeMillis() + timeout;

                if (DEBUG) Slog.i(TAG, "read=" + getReadFd() + " write=" + getWriteFd()
                        + " out=" + out);

                // Close the write fd, so we know when the other side is done.
                closeFd(1);

                mThread.start();

                while (mFailure == null && !mComplete) {
                    long waitTime = mEndTime - SystemClock.uptimeMillis();
                    if (waitTime <= 0) {
                        if (DEBUG) Slog.i(TAG, "TIMEOUT!");
                        mThread.interrupt();
                        throw new IOException("Timeout");
                    }

                    try {
                        wait(waitTime);
                    } catch (InterruptedException e) {
                    }
                }

                if (DEBUG) Slog.i(TAG, "Finished: " + mFailure);
                if (mFailure != null) {
                    throw new IOException(mFailure);
                }
            }
        } finally {
            kill();
        }
    
static voidgo(com.android.internal.os.TransferPipe$Caller caller, android.os.IInterface iface, java.io.FileDescriptor out, java.lang.String prefix, java.lang.String[] args)

        go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT);
    
static voidgo(com.android.internal.os.TransferPipe$Caller caller, android.os.IInterface iface, java.io.FileDescriptor out, java.lang.String prefix, java.lang.String[] args, long timeout)

        if ((iface.asBinder()) instanceof Binder) {
            // This is a local object...  just call it directly.
            try {
                caller.go(iface, out, prefix, args);
            } catch (RemoteException e) {
            }
            return;
        }

        TransferPipe tp = new TransferPipe();
        try {
            caller.go(iface, tp.getWriteFd().getFileDescriptor(), prefix, args);
            tp.go(out, timeout);
        } finally {
            tp.kill();
        }
    
public voidgo(java.io.FileDescriptor out)

        go(out, DEFAULT_TIMEOUT);
    
static voidgoDump(android.os.IBinder binder, java.io.FileDescriptor out, java.lang.String[] args)

        goDump(binder, out, args, DEFAULT_TIMEOUT);
    
static voidgoDump(android.os.IBinder binder, java.io.FileDescriptor out, java.lang.String[] args, long timeout)

        if (binder instanceof Binder) {
            // This is a local object...  just call it directly.
            try {
                binder.dump(out, args);
            } catch (RemoteException e) {
            }
            return;
        }

        TransferPipe tp = new TransferPipe();
        try {
            binder.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
            tp.go(out, timeout);
        } finally {
            tp.kill();
        }
    
public voidkill()

        synchronized (this) {
            closeFd(0);
            closeFd(1);
        }
    
public voidrun()

        final byte[] buffer = new byte[1024];
        final FileInputStream fis;
        final FileOutputStream fos;

        synchronized (this) {
            ParcelFileDescriptor readFd = getReadFd();
            if (readFd == null) {
                Slog.w(TAG, "Pipe has been closed...");
                return;
            }
            fis = new FileInputStream(readFd.getFileDescriptor());
            fos = new FileOutputStream(mOutFd);
        }

        if (DEBUG) Slog.i(TAG, "Ready to read pipe...");
        byte[] bufferPrefix = null;
        boolean needPrefix = true;
        if (mBufferPrefix != null) {
            bufferPrefix = mBufferPrefix.getBytes();
        }

        int size;
        try {
            while ((size=fis.read(buffer)) > 0) {
                if (DEBUG) Slog.i(TAG, "Got " + size + " bytes");
                if (bufferPrefix == null) {
                    fos.write(buffer, 0, size);
                } else {
                    int start = 0;
                    for (int i=0; i<size; i++) {
                        if (buffer[i] != '\n") {
                            if (i > start) {
                                fos.write(buffer, start, i-start);
                            }
                            start = i;
                            if (needPrefix) {
                                fos.write(bufferPrefix);
                                needPrefix = false;
                            }
                            do {
                                i++;
                            } while (i<size && buffer[i] != '\n");
                            if (i < size) {
                                needPrefix = true;
                            }
                        }
                    }
                    if (size > start) {
                        fos.write(buffer, start, size-start);
                    }
                }
            }
            if (DEBUG) Slog.i(TAG, "End of pipe: size=" + size);
            if (mThread.isInterrupted()) {
                if (DEBUG) Slog.i(TAG, "Interrupted!");
            }
        } catch (IOException e) {
            synchronized (this) {
                mFailure = e.toString();
                notifyAll();
                return;
            }
        }

        synchronized (this) {
            mComplete = true;
            notifyAll();
        }
    
public voidsetBufferPrefix(java.lang.String prefix)

        mBufferPrefix = prefix;