Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da5a3e12 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Richer ParcelFileDescriptor close events.

When reading from the end of a pipe or socket, there is no way to
tell if the other end has finished successfully, encountered an error,
or outright crashed.  To solve this, we create a second socketpair()
as a communication channel between the two ends of a pipe or
socket pair, sending a status code with details about why the
ParcelFileDescriptor was closed.

The writer end of a pipe or socket can closeWithError() to send a
message to the reader end.  When the reader encounters EOF, they
call checkError() to detect if any error occured.  This also detects
the case where the remote process died without sending a success
message.

This design is also extended to support regular files on disk, using
the communication channel above to detect various remote close events
or crashes, and delivering that event to a supplied OnCloseListener.

Replaces JNI with best-practice Libcore.os calls, and deprecates
some flags to match Context.

Bug: 10330121
Change-Id: I8cfa1e4fb6f57397667c7f785106193e0faccad3
parent 2241d45c
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -18108,8 +18108,14 @@ package android.os {
  public class ParcelFileDescriptor implements java.io.Closeable android.os.Parcelable {
    ctor public ParcelFileDescriptor(android.os.ParcelFileDescriptor);
    method public static android.os.ParcelFileDescriptor adoptFd(int);
    method public boolean canDetectErrors();
    method public void checkError(boolean) throws java.io.IOException;
    method public void close() throws java.io.IOException;
    method public void closeWithError(java.lang.String) throws java.io.IOException;
    method public static android.os.ParcelFileDescriptor[] createPipe() throws java.io.IOException;
    method public static android.os.ParcelFileDescriptor[] createReliablePipe() throws java.io.IOException;
    method public static android.os.ParcelFileDescriptor[] createReliableSocketPair() throws java.io.IOException;
    method public static android.os.ParcelFileDescriptor[] createSocketPair() throws java.io.IOException;
    method public int describeContents();
    method public int detachFd();
    method public static android.os.ParcelFileDescriptor dup(java.io.FileDescriptor) throws java.io.IOException;
@@ -18121,6 +18127,7 @@ package android.os {
    method public java.io.FileDescriptor getFileDescriptor();
    method public long getStatSize();
    method public static android.os.ParcelFileDescriptor open(java.io.File, int) throws java.io.FileNotFoundException;
    method public static android.os.ParcelFileDescriptor open(java.io.File, int, android.os.Handler, android.os.ParcelFileDescriptor.OnCloseListener) throws java.io.IOException;
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final int MODE_APPEND = 33554432; // 0x2000000
@@ -18128,8 +18135,8 @@ package android.os {
    field public static final int MODE_READ_ONLY = 268435456; // 0x10000000
    field public static final int MODE_READ_WRITE = 805306368; // 0x30000000
    field public static final int MODE_TRUNCATE = 67108864; // 0x4000000
    field public static final int MODE_WORLD_READABLE = 1; // 0x1
    field public static final int MODE_WORLD_WRITEABLE = 2; // 0x2
    field public static final deprecated int MODE_WORLD_READABLE = 1; // 0x1
    field public static final deprecated int MODE_WORLD_WRITEABLE = 2; // 0x2
    field public static final int MODE_WRITE_ONLY = 536870912; // 0x20000000
  }
@@ -18141,6 +18148,10 @@ package android.os {
    ctor public ParcelFileDescriptor.AutoCloseOutputStream(android.os.ParcelFileDescriptor);
  }
  public static abstract interface ParcelFileDescriptor.OnCloseListener {
    method public abstract void onClose(java.io.IOException, boolean);
  }
  public class ParcelFormatException extends java.lang.RuntimeException {
    ctor public ParcelFormatException();
    ctor public ParcelFormatException(java.lang.String);
+4 −11
Original line number Diff line number Diff line
@@ -2060,7 +2060,7 @@ public abstract class ContentResolver {

    private final class ParcelFileDescriptorInner extends ParcelFileDescriptor {
        private final IContentProvider mContentProvider;
        private boolean mReleaseProviderFlag = false;
        private boolean mProviderReleased;

        ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) {
            super(pfd);
@@ -2069,17 +2069,10 @@ public abstract class ContentResolver {

        @Override
        public void close() throws IOException {
            if(!mReleaseProviderFlag) {
            super.close();
            if (!mProviderReleased) {
                ContentResolver.this.releaseProvider(mContentProvider);
                mReleaseProviderFlag = true;
            }
        }

        @Override
        protected void finalize() throws Throwable {
            if (!mReleaseProviderFlag) {
                close();
                mProviderReleased = true;
            }
        }
    }
+5 −0
Original line number Diff line number Diff line
@@ -1520,6 +1520,11 @@ public final class Parcel {
        return fd != null ? new ParcelFileDescriptor(fd) : null;
    }

    /** {@hide} */
    public final FileDescriptor readRawFileDescriptor() {
        return nativeReadFileDescriptor(mNativePtr);
    }

    /*package*/ static native FileDescriptor openFileDescriptor(String file,
            int mode) throws FileNotFoundException;
    /*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
+635 −109

File changed.

Preview size limit exceeded, changes collapsed.

+0 −1
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ LOCAL_SRC_FILES:= \
	android_os_FileUtils.cpp \
	android_os_MemoryFile.cpp \
	android_os_MessageQueue.cpp \
	android_os_ParcelFileDescriptor.cpp \
	android_os_Parcel.cpp \
	android_os_SELinux.cpp \
	android_os_SystemClock.cpp \
Loading