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

Commit c172c7d8 authored by Erik Kline's avatar Erik Kline
Browse files

Add static IpClient logging

Support keeping IpClient logs around and dumping them
during dumpsys.  Previously we got this benefit for
wifi by virtue of WifiStateMachine's long-lived nature.
Now that this is changing we need to be sure we have
logs, and this method gets us Ethernet logs as well.

Bug: 62476366
Bug: 77999594
Test: as follows
    - built
    - flashed
    - booted
    - runtest frameworks-net passes
    - dumpsys connmetrics [ipclient] works
Merged-In: Ib4daf0902cae91acadbe9965de1fb73c96a47bec
Merged-In: Ie947394fabcaca7fc1d067f095c2442ee2704593
Change-Id: I1136a83de8097fdb4130debe1eaf689be7132fe5
(cherry picked from commit 3f8306b8)
parent 17280c61
Loading
Loading
Loading
Loading
+4 −10
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ import com.android.internal.net.NetworkStatsFactory;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnInfo;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
@@ -1935,13 +1936,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
        return ret;
    }

    private boolean argsContain(String[] args, String target) {
        for (String arg : args) {
            if (target.equals(arg)) return true;
        }
        return false;
    }

    private void dumpNetworkDiagnostics(IndentingPrintWriter pw) {
        final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
        final long DIAG_TIME_MS = 5000;
@@ -1965,10 +1959,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;

        if (argsContain(args, DIAG_ARG)) {
        if (ArrayUtils.contains(args, DIAG_ARG)) {
            dumpNetworkDiagnostics(pw);
            return;
        } else if (argsContain(args, TETHERING_ARG)) {
        } else if (ArrayUtils.contains(args, TETHERING_ARG)) {
            mTethering.dump(fd, pw, args);
            return;
        }
@@ -2033,7 +2027,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        pw.println();
        dumpAvoidBadWifiSettings(pw);

        if (argsContain(args, SHORT_ARG) == false) {
        if (ArrayUtils.contains(args, SHORT_ARG) == false) {
            pw.println();
            synchronized (mValidationLogs) {
                pw.println("mValidationLogs (most recent first):");
+19 −5
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Context;
import android.net.ConnectivityMetricsEvent;
import android.net.IIpConnectivityMetrics;
import android.net.INetdEventCallback;
import android.net.ip.IpClient;
import android.net.metrics.ApfProgramEvent;
import android.net.metrics.IpConnectivityLog;
import android.os.Binder;
@@ -269,10 +270,12 @@ final public class IpConnectivityMetrics extends SystemService {
        // Dump the rolling buffer of metrics event and pretty print events using a human readable
        // format. Also print network dns/connect statistics and default network event time series.
        static final String CMD_LIST = "list";
        // By default any other argument will fall into the default case which is remapped to the
        // "list" command. This includes most notably bug reports collected by dumpsys.cpp with
        // the "-a" argument.
        static final String CMD_DEFAULT = CMD_LIST;
        // Dump all IpClient logs ("ipclient").
        static final String CMD_IPCLIENT = IpClient.DUMP_ARG;
        // By default any other argument will fall into the default case which is the equivalent
        // of calling both the "list" and "ipclient" commands. This includes most notably bug
        // reports collected by dumpsys.cpp with the "-a" argument.
        static final String CMD_DEFAULT = "";

        @Override
        public int logEvent(ConnectivityMetricsEvent event) {
@@ -292,9 +295,20 @@ final public class IpConnectivityMetrics extends SystemService {
                case CMD_PROTO:
                    cmdListAsProto(pw);
                    return;
                case CMD_LIST: // fallthrough
                case CMD_IPCLIENT: {
                    final String[] ipclientArgs = ((args != null) && (args.length > 1))
                            ? Arrays.copyOfRange(args, 1, args.length)
                            : null;
                    IpClient.dumpAllLogs(pw, ipclientArgs);
                    return;
                }
                case CMD_LIST:
                    cmdList(pw);
                    return;
                default:
                    cmdList(pw);
                    pw.println("");
                    IpClient.dumpAllLogs(pw, null);
                    return;
            }
        }
+36 −2
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.IState;
import com.android.internal.util.Preconditions;
@@ -73,6 +74,7 @@ import java.util.Objects;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -99,6 +101,36 @@ public class IpClient extends StateMachine {
    private static final Class[] sMessageClasses = { IpClient.class, DhcpClient.class };
    private static final SparseArray<String> sWhatToString =
            MessageUtils.findMessageNames(sMessageClasses);
    // Two static concurrent hashmaps of interface name to logging classes.
    // One holds StateMachine logs and the other connectivity packet logs.
    private static final ConcurrentHashMap<String, SharedLog> sSmLogs = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>();

    // If |args| is non-empty, assume it's a list of interface names for which
    // we should print IpClient logs (filter out all others).
    public static void dumpAllLogs(PrintWriter writer, String[] args) {
        for (String ifname : sSmLogs.keySet()) {
            if (!ArrayUtils.isEmpty(args) && !ArrayUtils.contains(args, ifname)) continue;

            writer.println(String.format("--- BEGIN %s ---", ifname));

            final SharedLog smLog = sSmLogs.get(ifname);
            if (smLog != null) {
                writer.println("State machine log:");
                smLog.dump(null, writer, null);
            }

            writer.println("");

            final LocalLog pktLog = sPktLogs.get(ifname);
            if (pktLog != null) {
                writer.println("Connectivity packet log:");
                pktLog.readOnlyLocalLog().dump(null, writer, null);
            }

            writer.println(String.format("--- END %s ---", ifname));
        }
    }

    /**
     * Callbacks for handling IpClient events.
@@ -659,8 +691,10 @@ public class IpClient extends StateMachine {
        mShutdownLatch = new CountDownLatch(1);
        mNwService = deps.getNMS();

        mLog = new SharedLog(MAX_LOG_RECORDS, mTag);
        mConnectivityPacketLog = new LocalLog(MAX_PACKET_RECORDS);
        sSmLogs.putIfAbsent(mInterfaceName, new SharedLog(MAX_LOG_RECORDS, mTag));
        mLog = sSmLogs.get(mInterfaceName);
        sPktLogs.putIfAbsent(mInterfaceName, new LocalLog(MAX_PACKET_RECORDS));
        mConnectivityPacketLog = sPktLogs.get(mInterfaceName);
        mMsgStateLogger = new MessageHandlingLogger();

        // TODO: Consider creating, constructing, and passing in some kind of