diff options
3 files changed, 59 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 76e3131c37e8..9838de1474d0 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -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):"); diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java index f4278196b576..ac745985417e 100644 --- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java +++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java @@ -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; } } diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java index 87249dfc925f..37bb2ad8f6c1 100644 --- a/services/net/java/android/net/ip/IpClient.java +++ b/services/net/java/android/net/ip/IpClient.java @@ -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 |