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

Commit 2d6ac035 authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN Committed by Automerger Merge Worker
Browse files

Merge "Add OsCompat" into sc-dev am: 8080246d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13946372

Change-Id: Ifeb25fe7c8dcc720a769d4e70af4f2ab2df74021
parents 71a8ad1c 8080246d
Loading
Loading
Loading
Loading
+75 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.connectivity;

import android.system.ErrnoException;
import android.system.Os;

import java.io.FileDescriptor;

/**
 * Compatibility utility for android.system.Os core platform APIs.
 *
 * Connectivity has access to such APIs, but they are not part of the module_current stubs yet
 * (only core_current). Most stable core platform APIs are included manually in the connectivity
 * build rules, but because Os is also part of the base java SDK that is earlier on the
 * classpath, the extra core platform APIs are not seen.
 *
 * TODO (b/157639992, b/183097033): remove as soon as core_current is part of system_server_current
 * @hide
 */
public class OsCompat {
    // This value should be correct on all architectures supported by Android, but hardcoding ioctl
    // numbers should be avoided.
    /**
     * @see android.system.OsConstants#TIOCOUTQ
     */
    public static final int TIOCOUTQ = 0x5411;

    /**
     * @see android.system.Os#getsockoptInt(FileDescriptor, int, int)
     */
    public static int getsockoptInt(FileDescriptor fd, int level, int option) throws
            ErrnoException {
        try {
            return (int) Os.class.getMethod(
                    "getsockoptInt", FileDescriptor.class, int.class, int.class)
                    .invoke(null, fd, level, option);
        } catch (ReflectiveOperationException e) {
            if (e.getCause() instanceof ErrnoException) {
                throw (ErrnoException) e.getCause();
            }
            throw new IllegalStateException("Error calling getsockoptInt", e);
        }
    }

    /**
     * @see android.system.Os#ioctlInt(FileDescriptor, int)
     */
    public static int ioctlInt(FileDescriptor fd, int cmd) throws
            ErrnoException {
        try {
            return (int) Os.class.getMethod(
                    "ioctlInt", FileDescriptor.class, int.class).invoke(null, fd, cmd);
        } catch (ReflectiveOperationException e) {
            if (e.getCause() instanceof ErrnoException) {
                throw (ErrnoException) e.getCause();
            }
            throw new IllegalStateException("Error calling ioctlInt", e);
        }
    }
}
+8 −7
Original line number Diff line number Diff line
@@ -27,7 +27,8 @@ import static android.system.OsConstants.IPPROTO_IP;
import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IP_TOS;
import static android.system.OsConstants.IP_TTL;
import static android.system.OsConstants.TIOCOUTQ;

import static com.android.server.connectivity.OsCompat.TIOCOUTQ;

import android.annotation.NonNull;
import android.net.InvalidPacketException;
@@ -175,10 +176,10 @@ public class TcpKeepaliveController {
            }
            // Query write sequence number from SEND_QUEUE.
            Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_SEND_QUEUE);
            tcpDetails.seq = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
            tcpDetails.seq = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
            // Query read sequence number from RECV_QUEUE.
            Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_RECV_QUEUE);
            tcpDetails.ack = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
            tcpDetails.ack = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
            // Switch to NO_QUEUE to prevent illegal socket read/write in repair mode.
            Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_NO_QUEUE);
            // Finally, check if socket is still idle. TODO : this check needs to move to
@@ -198,9 +199,9 @@ public class TcpKeepaliveController {
            tcpDetails.rcvWndScale = trw.rcvWndScale;
            if (tcpDetails.srcAddress.length == 4 /* V4 address length */) {
                // Query TOS.
                tcpDetails.tos = Os.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
                tcpDetails.tos = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
                // Query TTL.
                tcpDetails.ttl = Os.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
                tcpDetails.ttl = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
            }
        } catch (ErrnoException e) {
            Log.e(TAG, "Exception reading TCP state from socket", e);
@@ -305,7 +306,7 @@ public class TcpKeepaliveController {

    private static boolean isReceiveQueueEmpty(FileDescriptor fd)
            throws ErrnoException {
        final int result = Os.ioctlInt(fd, SIOCINQ);
        final int result = OsCompat.ioctlInt(fd, SIOCINQ);
        if (result != 0) {
            Log.e(TAG, "Read queue has data");
            return false;
@@ -315,7 +316,7 @@ public class TcpKeepaliveController {

    private static boolean isSendQueueEmpty(FileDescriptor fd)
            throws ErrnoException {
        final int result = Os.ioctlInt(fd, SIOCOUTQ);
        final int result = OsCompat.ioctlInt(fd, SIOCOUTQ);
        if (result != 0) {
            Log.e(TAG, "Write queue has data");
            return false;