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

Commit 352dc2f2 authored by junyulai's avatar junyulai Committed by Chalard Jean
Browse files

[KA04] Expose TCP socket keepalive API

The new set of API allows applications to request keepalives
offload for established TCP sockets over wifi.

However, the application must not write to or read from the
socket after calling this method, until specific callbacks are
called.

Bug: 114151147
Test: atest FrameworksNetTests FrameworksWifiTests NetworkStackTests

Change-Id: I3880505dbc35fefa34ef6c79555458ecf5d296a4
parent 6606b772
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3069,6 +3069,7 @@ package android.net {
  public class ConnectivityManager {
    method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull java.io.FileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
    method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
    method public boolean getAvoidBadWifi();
    method @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS) public String getCaptivePortalServerUrl();
    method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementValue(int, boolean, @NonNull android.net.ConnectivityManager.TetheringEntitlementValueListener, @Nullable android.os.Handler);
+33 −1
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -1889,7 +1890,8 @@ public class ConnectivityManager {
     * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive
     *        changes. Must be extended by applications that use this API.
     *
     * @return A {@link SocketKeepalive} object, which can be used to control this keepalive object.
     * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
     *         given socket.
     **/
    public SocketKeepalive createSocketKeepalive(@NonNull Network network,
            @NonNull UdpEncapsulationSocket socket,
@@ -1918,6 +1920,8 @@ public class ConnectivityManager {
     * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive
     *        changes. Must be extended by applications that use this API.
     *
     * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
     *         given socket.
     * @hide
     */
    @SystemApi
@@ -1932,6 +1936,34 @@ public class ConnectivityManager {
                source, destination, executor, callback);
    }

    /**
     * Request that keepalives be started on a TCP socket.
     * The socket must be established.
     *
     * @param network The {@link Network} the socket is on.
     * @param socket The socket that needs to be kept alive.
     * @param executor The executor on which callback will be invoked. This implementation assumes
     *                 the provided {@link Executor} runs the callbacks in sequence with no
     *                 concurrency. Failing this, no guarantee of correctness can be made. It is
     *                 the responsibility of the caller to ensure the executor provides this
     *                 guarantee. A simple way of creating such an executor is with the standard
     *                 tool {@code Executors.newSingleThreadExecutor}.
     * @param callback A {@link SocketKeepalive.Callback}. Used for notifications about keepalive
     *        changes. Must be extended by applications that use this API.
     *
     * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the
     *         given socket.
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD)
    public SocketKeepalive createSocketKeepalive(@NonNull Network network,
            @NonNull Socket socket,
            @NonNull Executor executor,
            @NonNull Callback callback) {
        return new TcpSocketKeepalive(mService, network, socket, executor, callback);
    }

    /**
     * Ensure that a network route exists to deliver traffic to the specified
     * host via the specified network interface. An attempt to add a route that
+3 −0
Original line number Diff line number Diff line
@@ -188,6 +188,9 @@ interface IConnectivityManager
            int intervalSeconds, in Messenger messenger, in IBinder binder, String srcAddr,
            String dstAddr);

    void startTcpKeepalive(in Network network, in FileDescriptor fd, int intervalSeconds,
            in Messenger messenger, in IBinder binder);

    void stopKeepalive(in Network network, int slot);

    String getCaptivePortalServerUrl();
+46 −0
Original line number Diff line number Diff line
@@ -177,6 +177,26 @@ public abstract class NetworkAgent extends Handler {
     */
    public static final int EVENT_SOCKET_KEEPALIVE = BASE + 13;

    // TODO: move the above 2 constants down so they are in order once merge conflicts are resolved
    /**
     * Sent by the KeepaliveTracker to NetworkAgent to add a packet filter.
     *
     * For TCP keepalive offloads, keepalive packets are sent by the firmware. However, because the
     * remote site will send ACK packets in response to the keepalive packets, the firmware also
     * needs to be configured to properly filter the ACKs to prevent the system from waking up.
     * This does not happen with UDP, so this message is TCP-specific.
     * arg1 = slot number of the keepalive to filter for.
     * obj = the keepalive packet to send repeatedly.
     */
    public static final int CMD_ADD_KEEPALIVE_PACKET_FILTER = BASE + 16;

    /**
     * Sent by the KeepaliveTracker to NetworkAgent to remove a packet filter. See
     * {@link #CMD_ADD_KEEPALIVE_PACKET_FILTER}.
     * arg1 = slot number of the keepalive packet filter to remove.
     */
    public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;

    /**
     * Sent by ConnectivityService to inform this network transport of signal strength thresholds
     * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
@@ -312,6 +332,14 @@ public abstract class NetworkAgent extends Handler {
                preventAutomaticReconnect();
                break;
            }
            case CMD_ADD_KEEPALIVE_PACKET_FILTER: {
                addKeepalivePacketFilter(msg);
                break;
            }
            case CMD_REMOVE_KEEPALIVE_PACKET_FILTER: {
                removeKeepalivePacketFilter(msg);
                break;
            }
        }
    }

@@ -460,6 +488,24 @@ public abstract class NetworkAgent extends Handler {
        queueOrSendMessage(EVENT_SOCKET_KEEPALIVE, slot, reason);
    }

    /**
     * Called by ConnectivityService to add specific packet filter to network hardware to block
     * ACKs matching the sent keepalive packets. Implementations that support this feature must
     * override this method.
     */
    protected void addKeepalivePacketFilter(Message msg) {
        onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
    }

    /**
     * Called by ConnectivityService to remove a packet filter installed with
     * {@link #addKeepalivePacketFilter(Message)}. Implementations that support this feature
     * must override this method.
     */
    protected void removeKeepalivePacketFilter(Message msg) {
        onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED);
    }

    /**
     * Called by ConnectivityService to inform this network transport of signal strength thresholds
     * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.net;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -155,7 +156,7 @@ public abstract class SocketKeepalive implements AutoCloseable {
    @NonNull private final SocketKeepalive.Callback mCallback;
    @NonNull private final Looper mLooper;
    @NonNull final Messenger mMessenger;
    @NonNull Integer mSlot;
    @Nullable Integer mSlot;

    SocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network,
            @NonNull Executor executor, @NonNull Callback callback) {
Loading