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

Commit a2786c1f authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topic "appfuse-upstr"

* changes:
  cheets: Delegate openAppFuseFile operation to vold
  Add FileUtils.translateModePfdToPosix
parents 1e8399f1 70ee4328
Loading
Loading
Loading
Loading
+37 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,18 @@


package android.os;
package android.os;


import static android.os.ParcelFileDescriptor.MODE_APPEND;
import static android.os.ParcelFileDescriptor.MODE_CREATE;
import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY;
import static android.system.OsConstants.O_APPEND;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDONLY;
import static android.system.OsConstants.O_RDWR;
import static android.system.OsConstants.O_TRUNC;
import static android.system.OsConstants.O_WRONLY;
import static android.system.OsConstants.SPLICE_F_MORE;
import static android.system.OsConstants.SPLICE_F_MORE;
import static android.system.OsConstants.SPLICE_F_MOVE;
import static android.system.OsConstants.SPLICE_F_MOVE;
import static android.system.OsConstants.S_ISFIFO;
import static android.system.OsConstants.S_ISFIFO;
@@ -1050,6 +1062,30 @@ public class FileUtils {
        return val * pow;
        return val * pow;
    }
    }


    /** {@hide} */
    public static int translateModePfdToPosix(int mode) {
        int res = 0;
        if ((mode & MODE_READ_WRITE) == MODE_READ_WRITE) {
            res |= O_RDWR;
        } else if ((mode & MODE_WRITE_ONLY) == MODE_WRITE_ONLY) {
            res |= O_WRONLY;
        } else if ((mode & MODE_READ_ONLY) == MODE_READ_ONLY) {
            res |= O_RDONLY;
        } else {
            throw new IllegalArgumentException("Bad mode: " + mode);
        }
        if ((mode & MODE_CREATE) == MODE_CREATE) {
            res |= O_CREAT;
        }
        if ((mode & MODE_TRUNCATE) == MODE_TRUNCATE) {
            res |= O_TRUNC;
        }
        if ((mode & MODE_APPEND) == MODE_APPEND) {
            res |= O_APPEND;
        }
        return res;
    }

    @VisibleForTesting
    @VisibleForTesting
    public static class MemoryPipe extends Thread implements AutoCloseable {
    public static class MemoryPipe extends Thread implements AutoCloseable {
        private final FileDescriptor[] pipe;
        private final FileDescriptor[] pipe;
@@ -1115,3 +1151,4 @@ public class FileUtils {
        }
        }
    }
    }
}
}
+17 −8
Original line number Original line Diff line number Diff line
@@ -2602,24 +2602,35 @@ class StorageManagerService extends IStorageManager.Stub
    class AppFuseMountScope extends AppFuseBridge.MountScope {
    class AppFuseMountScope extends AppFuseBridge.MountScope {
        boolean opened = false;
        boolean opened = false;


        public AppFuseMountScope(int uid, int pid, int mountId) {
        public AppFuseMountScope(int uid, int mountId) {
            super(uid, pid, mountId);
            super(uid, mountId);
        }
        }


        @Override
        @Override
        public ParcelFileDescriptor open() throws NativeDaemonConnectorException {
        public ParcelFileDescriptor open() throws NativeDaemonConnectorException {
            try {
            try {
                return new ParcelFileDescriptor(
                return new ParcelFileDescriptor(
                        mVold.mountAppFuse(uid, Process.myPid(), mountId));
                        mVold.mountAppFuse(uid, mountId));
            } catch (Exception e) {
            } catch (Exception e) {
                throw new NativeDaemonConnectorException("Failed to mount", e);
                throw new NativeDaemonConnectorException("Failed to mount", e);
            }
            }
        }
        }


        @Override
        public ParcelFileDescriptor openFile(int mountId, int fileId, int flags)
                throws NativeDaemonConnectorException {
            try {
                return new ParcelFileDescriptor(
                        mVold.openAppFuseFile(uid, mountId, fileId, flags));
            } catch (Exception e) {
                throw new NativeDaemonConnectorException("Failed to open", e);
            }
        }

        @Override
        @Override
        public void close() throws Exception {
        public void close() throws Exception {
            if (opened) {
            if (opened) {
                mVold.unmountAppFuse(uid, Process.myPid(), mountId);
                mVold.unmountAppFuse(uid, mountId);
                opened = false;
                opened = false;
            }
            }
        }
        }
@@ -2629,7 +2640,6 @@ class StorageManagerService extends IStorageManager.Stub
    public @Nullable AppFuseMount mountProxyFileDescriptorBridge() {
    public @Nullable AppFuseMount mountProxyFileDescriptorBridge() {
        Slog.v(TAG, "mountProxyFileDescriptorBridge");
        Slog.v(TAG, "mountProxyFileDescriptorBridge");
        final int uid = Binder.getCallingUid();
        final int uid = Binder.getCallingUid();
        final int pid = Binder.getCallingPid();


        while (true) {
        while (true) {
            synchronized (mAppFuseLock) {
            synchronized (mAppFuseLock) {
@@ -2643,7 +2653,7 @@ class StorageManagerService extends IStorageManager.Stub
                    final int name = mNextAppFuseName++;
                    final int name = mNextAppFuseName++;
                    try {
                    try {
                        return new AppFuseMount(
                        return new AppFuseMount(
                            name, mAppFuseBridge.addBridge(new AppFuseMountScope(uid, pid, name)));
                            name, mAppFuseBridge.addBridge(new AppFuseMountScope(uid, name)));
                    } catch (FuseUnavailableMountException e) {
                    } catch (FuseUnavailableMountException e) {
                        if (newlyCreated) {
                        if (newlyCreated) {
                            // If newly created bridge fails, it's a real error.
                            // If newly created bridge fails, it's a real error.
@@ -2664,14 +2674,13 @@ class StorageManagerService extends IStorageManager.Stub
    public @Nullable ParcelFileDescriptor openProxyFileDescriptor(
    public @Nullable ParcelFileDescriptor openProxyFileDescriptor(
            int mountId, int fileId, int mode) {
            int mountId, int fileId, int mode) {
        Slog.v(TAG, "mountProxyFileDescriptor");
        Slog.v(TAG, "mountProxyFileDescriptor");
        final int pid = Binder.getCallingPid();
        try {
        try {
            synchronized (mAppFuseLock) {
            synchronized (mAppFuseLock) {
                if (mAppFuseBridge == null) {
                if (mAppFuseBridge == null) {
                    Slog.e(TAG, "FuseBridge has not been created");
                    Slog.e(TAG, "FuseBridge has not been created");
                    return null;
                    return null;
                }
                }
                return mAppFuseBridge.openFile(pid, mountId, fileId, mode);
                return mAppFuseBridge.openFile(mountId, fileId, mode);
            }
            }
        } catch (FuseUnavailableMountException | InterruptedException error) {
        } catch (FuseUnavailableMountException | InterruptedException error) {
            Slog.v(TAG, "The mount point has already been invalid", error);
            Slog.v(TAG, "The mount point has already been invalid", error);
+8 −14
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.server.storage;
package com.android.server.storage;


import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.ErrnoException;
import android.system.Os;
import android.system.Os;
@@ -25,8 +26,6 @@ import com.android.internal.os.FuseUnavailableMountException;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Preconditions;
import com.android.server.NativeDaemonConnectorException;
import com.android.server.NativeDaemonConnectorException;
import libcore.io.IoUtils;
import libcore.io.IoUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CountDownLatch;


/**
/**
@@ -87,7 +86,7 @@ public class AppFuseBridge implements Runnable {
        }
        }
    }
    }


    public ParcelFileDescriptor openFile(int pid, int mountId, int fileId, int mode)
    public ParcelFileDescriptor openFile(int mountId, int fileId, int mode)
            throws FuseUnavailableMountException, InterruptedException {
            throws FuseUnavailableMountException, InterruptedException {
        final MountScope scope;
        final MountScope scope;
        synchronized (this) {
        synchronized (this) {
@@ -96,17 +95,14 @@ public class AppFuseBridge implements Runnable {
                throw new FuseUnavailableMountException(mountId);
                throw new FuseUnavailableMountException(mountId);
            }
            }
        }
        }
        if (scope.pid != pid) {
            throw new SecurityException("PID does not match");
        }
        final boolean result = scope.waitForMount();
        final boolean result = scope.waitForMount();
        if (result == false) {
        if (result == false) {
            throw new FuseUnavailableMountException(mountId);
            throw new FuseUnavailableMountException(mountId);
        }
        }
        try {
        try {
            return ParcelFileDescriptor.open(
            int flags = FileUtils.translateModePfdToPosix(mode);
                    new File(scope.mountPoint, String.valueOf(fileId)), mode);
            return scope.openFile(mountId, fileId, flags);
        } catch (FileNotFoundException error) {
        } catch (NativeDaemonConnectorException error) {
            throw new FuseUnavailableMountException(mountId);
            throw new FuseUnavailableMountException(mountId);
        }
        }
    }
    }
@@ -131,17 +127,13 @@ public class AppFuseBridge implements Runnable {


    public static abstract class MountScope implements AutoCloseable {
    public static abstract class MountScope implements AutoCloseable {
        public final int uid;
        public final int uid;
        public final int pid;
        public final int mountId;
        public final int mountId;
        public final File mountPoint;
        private final CountDownLatch mMounted = new CountDownLatch(1);
        private final CountDownLatch mMounted = new CountDownLatch(1);
        private boolean mMountResult = false;
        private boolean mMountResult = false;


        public MountScope(int uid, int pid, int mountId) {
        public MountScope(int uid, int mountId) {
            this.uid = uid;
            this.uid = uid;
            this.pid = pid;
            this.mountId = mountId;
            this.mountId = mountId;
            this.mountPoint = new File(String.format(APPFUSE_MOUNT_NAME_TEMPLATE,  uid, mountId));
        }
        }


        @GuardedBy("AppFuseBridge.this")
        @GuardedBy("AppFuseBridge.this")
@@ -159,6 +151,8 @@ public class AppFuseBridge implements Runnable {
        }
        }


        public abstract ParcelFileDescriptor open() throws NativeDaemonConnectorException;
        public abstract ParcelFileDescriptor open() throws NativeDaemonConnectorException;
        public abstract ParcelFileDescriptor openFile(int mountId, int fileId, int flags)
                throws NativeDaemonConnectorException;
    }
    }


    private native long native_new();
    private native long native_new();