Add Validation logging.
Persist the last 20 lines of validation info for the last 10
networks.
bug: 21599856
Change-Id: I8124480cc9181eea2adb7eb6eabcd07c9506b6d3
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 25d4d5e..84bcf66 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -92,6 +92,9 @@
import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.LocalLog.ReadOnlyLocalLog;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -139,6 +142,7 @@
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -414,6 +418,20 @@
// sequence number of NetworkRequests
private int mNextNetworkRequestId = 1;
+ // Array of <Network,ReadOnlyLocalLogs> tracking network validation and results
+ private static final int MAX_VALIDATION_LOGS = 10;
+ private final ArrayDeque<Pair<Network,ReadOnlyLocalLog>> mValidationLogs =
+ new ArrayDeque<Pair<Network,ReadOnlyLocalLog>>(MAX_VALIDATION_LOGS);
+
+ private void addValidationLogs(ReadOnlyLocalLog log, Network network) {
+ synchronized(mValidationLogs) {
+ while (mValidationLogs.size() >= MAX_VALIDATION_LOGS) {
+ mValidationLogs.removeLast();
+ }
+ mValidationLogs.addFirst(new Pair(network, log));
+ }
+ }
+
/**
* Implements support for the legacy "one network per network type" model.
*
@@ -1715,11 +1733,9 @@
return ret;
}
- private boolean shouldPerformDiagnostics(String[] args) {
+ private boolean argsContain(String[] args, String target) {
for (String arg : args) {
- if (arg.equals("--diag")) {
- return true;
- }
+ if (arg.equals(target)) return true;
}
return false;
}
@@ -1737,7 +1753,7 @@
}
final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
- if (shouldPerformDiagnostics(args)) {
+ if (argsContain(args, "--diag")) {
final long DIAG_TIME_MS = 5000;
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
// Start gathering diagnostic information.
@@ -1824,6 +1840,19 @@
}
pw.decreaseIndent();
}
+
+ if (argsContain(args, "--short") == false) {
+ pw.println();
+ synchronized (mValidationLogs) {
+ pw.println("mValidationLogs (most recent first):");
+ for (Pair<Network,ReadOnlyLocalLog> p : mValidationLogs) {
+ pw.println(p.first);
+ pw.increaseIndent();
+ p.second.dump(fd, pw, args);
+ pw.decreaseIndent();
+ }
+ }
+ }
}
private boolean isLiveNetworkAgent(NetworkAgentInfo nai, String msg) {
@@ -3814,6 +3843,7 @@
synchronized (this) {
nai.networkMonitor.systemReady = mSystemReady;
}
+ addValidationLogs(nai.networkMonitor.getValidationLogs(), nai.network);
if (DBG) log("registerNetworkAgent " + nai);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
return nai.network.netId;
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 99a0567..310e361 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -47,6 +47,8 @@
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.TelephonyManager;
+import android.util.LocalLog;
+import android.util.LocalLog.ReadOnlyLocalLog;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -232,6 +234,8 @@
private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;
private String mCaptivePortalLoggedInResponseToken = null;
+ private final LocalLog validationLogs = new LocalLog(20); // 20 lines
+
public NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo,
NetworkRequest defaultRequest) {
// Add suffix indicating which NetworkMonitor we're talking about.
@@ -272,6 +276,15 @@
Log.d(TAG + "/" + mNetworkAgentInfo.name(), s);
}
+ private void validationLog(String s) {
+ if (DBG) log(s);
+ validationLogs.log(s);
+ }
+
+ public ReadOnlyLocalLog getValidationLogs() {
+ return validationLogs.readOnlyLocalLog();
+ }
+
// DefaultState is the parent of all States. It exists only to handle CMD_* messages but
// does not entail any real state (hence no enter() or exit() routines).
private class DefaultState extends State {
@@ -649,10 +662,8 @@
fetchPac = true;
}
}
- if (DBG) {
- log("Checking " + url.toString() + " on " +
- mNetworkAgentInfo.networkInfo.getExtraInfo());
- }
+ validationLog("Checking " + url.toString() + " on " +
+ mNetworkAgentInfo.networkInfo.getExtraInfo());
urlConnection = (HttpURLConnection) mNetworkAgentInfo.network.openConnection(url);
urlConnection.setInstanceFollowRedirects(fetchPac);
urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
@@ -668,10 +679,8 @@
long responseTimestamp = SystemClock.elapsedRealtime();
httpResponseCode = urlConnection.getResponseCode();
- if (DBG) {
- log("isCaptivePortal: ret=" + httpResponseCode +
- " headers=" + urlConnection.getHeaderFields());
- }
+ validationLog("isCaptivePortal: ret=" + httpResponseCode +
+ " headers=" + urlConnection.getHeaderFields());
// NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
// portal. The only example of this seen so far was a captive portal. For
// the time being go with prior behavior of assuming it's not a captive
@@ -684,12 +693,12 @@
// sign-in to an empty page. Probably the result of a broken transparent proxy.
// See http://b/9972012.
if (httpResponseCode == 200 && urlConnection.getContentLength() == 0) {
- if (DBG) log("Empty 200 response interpreted as 204 response.");
+ validationLog("Empty 200 response interpreted as 204 response.");
httpResponseCode = 204;
}
if (httpResponseCode == 200 && fetchPac) {
- if (DBG) log("PAC fetch 200 response interpreted as 204 response.");
+ validationLog("PAC fetch 200 response interpreted as 204 response.");
httpResponseCode = 204;
}
@@ -697,7 +706,7 @@
httpResponseCode != 204 /* isCaptivePortal */,
requestTimestamp, responseTimestamp);
} catch (IOException e) {
- if (DBG) log("Probably not a portal: exception " + e);
+ validationLog("Probably not a portal: exception " + e);
if (httpResponseCode == 599) {
// TODO: Ping gateway and DNS server and log results.
}