FileDocCategorySizeDatePackage
FileBridge.javaAPI DocAndroid 5.1 API6339Thu Mar 12 22:22:10 GMT 2015android.os

FileBridge

public class FileBridge extends Thread
Simple bridge that allows file access across process boundaries without returning the underlying {@link FileDescriptor}. This is useful when the server side needs to strongly assert that a client side is completely hands-off.
hide

Fields Summary
private static final String
TAG
private static final int
MSG_LENGTH
private static final int
CMD_WRITE
CMD_WRITE [len] [data]
private static final int
CMD_FSYNC
CMD_FSYNC
private static final int
CMD_CLOSE
CMD_CLOSE
private FileDescriptor
mTarget
private final FileDescriptor
mServer
private final FileDescriptor
mClient
private volatile boolean
mClosed
Constructors Summary
public FileBridge()


      
        try {
            Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mServer, mClient);
        } catch (ErrnoException e) {
            throw new RuntimeException("Failed to create bridge");
        }
    
Methods Summary
public voidforceClose()

        IoUtils.closeQuietly(mTarget);
        IoUtils.closeQuietly(mServer);
        IoUtils.closeQuietly(mClient);
        mClosed = true;
    
public java.io.FileDescriptorgetClientSocket()

        return mClient;
    
public booleanisClosed()

        return mClosed;
    
public voidrun()

        final byte[] temp = new byte[8192];
        try {
            while (IoBridge.read(mServer, temp, 0, MSG_LENGTH) == MSG_LENGTH) {
                final int cmd = Memory.peekInt(temp, 0, ByteOrder.BIG_ENDIAN);
                if (cmd == CMD_WRITE) {
                    // Shuttle data into local file
                    int len = Memory.peekInt(temp, 4, ByteOrder.BIG_ENDIAN);
                    while (len > 0) {
                        int n = IoBridge.read(mServer, temp, 0, Math.min(temp.length, len));
                        if (n == -1) {
                            throw new IOException(
                                    "Unexpected EOF; still expected " + len + " bytes");
                        }
                        IoBridge.write(mTarget, temp, 0, n);
                        len -= n;
                    }

                } else if (cmd == CMD_FSYNC) {
                    // Sync and echo back to confirm
                    Os.fsync(mTarget);
                    IoBridge.write(mServer, temp, 0, MSG_LENGTH);

                } else if (cmd == CMD_CLOSE) {
                    // Close and echo back to confirm
                    Os.fsync(mTarget);
                    Os.close(mTarget);
                    mClosed = true;
                    IoBridge.write(mServer, temp, 0, MSG_LENGTH);
                    break;
                }
            }

        } catch (ErrnoException | IOException e) {
            Log.wtf(TAG, "Failed during bridge", e);
        } finally {
            forceClose();
        }
    
public voidsetTargetFile(java.io.FileDescriptor target)

        mTarget = target;