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

Commit 22b4c6a0 authored by Robert Greenwalt's avatar Robert Greenwalt
Browse files

Add Validation logging.

Persist the last 20 lines of validation info for the last 10
networks.

bug: 21599856
Change-Id: I8124480cc9181eea2adb7eb6eabcd07c9506b6d3
parent 0d99d43e
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -54,4 +54,18 @@ public final class LocalLog {
            pw.println(itr.next());
        }
    }

    public static class ReadOnlyLocalLog {
        private final LocalLog mLog;
        ReadOnlyLocalLog(LocalLog log) {
            mLog = log;
        }
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            mLog.dump(fd, pw, args);
        }
    }

    public ReadOnlyLocalLog readOnlyLocalLog() {
        return new ReadOnlyLocalLog(this);
    }
}
+35 −5
Original line number Diff line number Diff line
@@ -92,6 +92,9 @@ import android.security.Credentials;
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.Inet4Address;
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 @@ public class ConnectivityService extends IConnectivityManager.Stub
    // 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 @@ public class ConnectivityService extends IConnectivityManager.Stub
        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 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }

        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 @@ public class ConnectivityService extends IConnectivityManager.Stub
            }
            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 @@ public class ConnectivityService extends IConnectivityManager.Stub
        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;
+20 −11
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ import android.telephony.CellInfoGsm;
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 @@ public class NetworkMonitor extends StateMachine {
    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 @@ public class NetworkMonitor extends StateMachine {
        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 @@ public class NetworkMonitor extends StateMachine {
                    fetchPac = true;
                }
            }
            if (DBG) {
                log("Checking " + url.toString() + " on " +
            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 @@ public class NetworkMonitor extends StateMachine {
            long responseTimestamp = SystemClock.elapsedRealtime();

            httpResponseCode = urlConnection.getResponseCode();
            if (DBG) {
                log("isCaptivePortal: ret=" + httpResponseCode +
            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 @@ public class NetworkMonitor extends StateMachine {
            // 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 @@ public class NetworkMonitor extends StateMachine {
                    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.
            }