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

Commit 8093d78d authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

Add a module-lib API for constructing a LocalSocket from an fd.

This allows constructing a LocalSocket from a FileDescriptor
referring to an already-connected socket. The LocalSocket can
then be used to exchange ancillary filedescriptors and fetch
peer socket credentials for the existing FD.

The fd is not dup'd or closed by the API, and the caller is
responsible for closing it. This is consistent with the
constructor of the related LocalServerSocket class, which also
takes an fd and does not manage its lifecycle.

Bug: 200200870
Test: atest CoreTests:android.net.LocalSocketTest CtsNetTestCases:android.net.cts.LocalSocketTest
Change-Id: I86448ba80475c4563194a4a2d9a0c0bbd0b76444
parent 64085cd5
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -235,6 +235,10 @@ package android.net {
    method public int getResourceId();
    method public int getResourceId();
  }
  }


  public class LocalSocket implements java.io.Closeable {
    ctor public LocalSocket(@NonNull java.io.FileDescriptor);
  }

  public class NetworkIdentity {
  public class NetworkIdentity {
    method public int getOemManaged();
    method public int getOemManaged();
    method public int getRatType();
    method public int getRatType();
+3 −1
Original line number Original line Diff line number Diff line
@@ -55,7 +55,9 @@ public class LocalServerSocket implements Closeable {
     * Create a LocalServerSocket from a file descriptor that's already
     * Create a LocalServerSocket from a file descriptor that's already
     * been created and bound. listen() will be called immediately on it.
     * been created and bound. listen() will be called immediately on it.
     * Used for cases where file descriptors are passed in via environment
     * Used for cases where file descriptors are passed in via environment
     * variables
     * variables. The passed-in FileDescriptor is not managed by this class
     * and must be closed by the caller. Calling {@link #close()} on a socket
     * created by this method has no effect.
     *
     *
     * @param fd bound file descriptor
     * @param fd bound file descriptor
     * @throws IOException
     * @throws IOException
+40 −13
Original line number Original line Diff line number Diff line
@@ -16,7 +16,14 @@


package android.net;
package android.net;


import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;

import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.system.ErrnoException;
import android.system.Os;


import java.io.Closeable;
import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.FileDescriptor;
@@ -74,32 +81,52 @@ public class LocalSocket implements Closeable {
        this.isBound = false;
        this.isBound = false;
    }
    }


    private void checkConnected() {
        try {
            Os.getpeername(impl.getFileDescriptor());
        } catch (ErrnoException e) {
            throw new IllegalArgumentException("Not a connected socket", e);
        }
        isConnected = true;
        isBound = true;
        implCreated = true;
    }

    /**
     * Creates a LocalSocket instance using the {@link FileDescriptor} for an already-connected
     * AF_LOCAL/UNIX domain stream socket. The passed-in FileDescriptor is not managed by this class
     * and must be closed by the caller. Calling {@link #close()} on a socket created by this
     * method has no effect.
     *
     * @param fd the filedescriptor to adopt
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public LocalSocket(@NonNull @SuppressLint("UseParcelFileDescriptor") FileDescriptor fd) {
        this(new LocalSocketImpl(fd), SOCKET_UNKNOWN);
        checkConnected();
    }

    /**
    /**
     * Creates a LocalSocket instances using the FileDescriptor for an already-connected
     * Creates a LocalSocket instances using the FileDescriptor for an already-connected
     * AF_LOCAL/UNIX domain stream socket. Note: the FileDescriptor must be closed by the caller:
     * AF_LOCAL/UNIX domain stream socket. Note: the FileDescriptor must be closed by the caller:
     * closing the LocalSocket will not close it.
     * closing the LocalSocket will not close it.
     *
     *
     * @hide - used by BluetoothSocket.
     * TODO: delete this method when Bluetooth is no longer using it.
     *
     * @hide
     */
     */
    public static LocalSocket createConnectedLocalSocket(FileDescriptor fd) {
    public static LocalSocket createConnectedLocalSocket(FileDescriptor fd) {
        return createConnectedLocalSocket(new LocalSocketImpl(fd), SOCKET_UNKNOWN);
        return new LocalSocket(fd);
    }
    }


    /**
    /**
     * for use with LocalServerSocket.accept()
     * for use with LocalServerSocket.accept()
     */
     */
    static LocalSocket createLocalSocketForAccept(LocalSocketImpl impl) {
    static LocalSocket createLocalSocketForAccept(LocalSocketImpl impl) {
        return createConnectedLocalSocket(impl, SOCKET_UNKNOWN);
        LocalSocket socket = new LocalSocket(impl, SOCKET_UNKNOWN);
    }
        socket.checkConnected();

    /**
     * Creates a LocalSocket from an existing LocalSocketImpl that is already connected.
     */
    private static LocalSocket createConnectedLocalSocket(LocalSocketImpl impl, int sockType) {
        LocalSocket socket = new LocalSocket(impl, sockType);
        socket.isConnected = true;
        socket.isBound = true;
        socket.implCreated = true;
        return socket;
        return socket;
    }
    }