Merge "Split network monitoring and portal probe events" into nyc-dev
diff --git a/api/system-current.txt b/api/system-current.txt
index e05d9fe..7a71672 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -26012,29 +26012,6 @@
 
 package android.net.metrics {
 
-  public final class CaptivePortalCheckResultEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
-    method public int describeContents();
-    method public static void logEvent(int, int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.metrics.CaptivePortalCheckResultEvent> CREATOR;
-    field public final int netId;
-    field public final int result;
-  }
-
-  public final class CaptivePortalStateChangeEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
-    ctor public CaptivePortalStateChangeEvent(int, int);
-    ctor public CaptivePortalStateChangeEvent(android.os.Parcel);
-    method public int describeContents();
-    method public static void logEvent(int, int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.metrics.CaptivePortalStateChangeEvent> CREATOR;
-    field public static final int NETWORK_MONITOR_CONNECTED = 0; // 0x0
-    field public static final int NETWORK_MONITOR_DISCONNECTED = 1; // 0x1
-    field public static final int NETWORK_MONITOR_VALIDATED = 2; // 0x2
-    field public final int netId;
-    field public final int state;
-  }
-
   public final class DefaultNetworkEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
     method public int describeContents();
     method public static void logEvent(int, int[], int, boolean, boolean);
@@ -26148,16 +26125,35 @@
     field public final java.lang.String ifName;
   }
 
-  public final class NetworkMonitorEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
-    ctor public NetworkMonitorEvent(android.os.Parcel);
+  public final class NetworkEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
     method public int describeContents();
     method public static void logCaptivePortalFound(int, long);
-    method public static void logPortalProbeEvent(int, long, int);
+    method public static void logEvent(int, int);
     method public static void logValidated(int, long);
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.metrics.NetworkMonitorEvent> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.net.metrics.NetworkEvent> CREATOR;
+    field public static final int NETWORK_CAPTIVE_PORTAL_FOUND = 4; // 0x4
+    field public static final int NETWORK_CONNECTED = 1; // 0x1
+    field public static final int NETWORK_DISCONNECTED = 7; // 0x7
+    field public static final int NETWORK_LINGER = 5; // 0x5
+    field public static final int NETWORK_UNLINGER = 6; // 0x6
+    field public static final int NETWORK_VALIDATED = 2; // 0x2
+    field public static final int NETWORK_VALIDATION_FAILED = 3; // 0x3
+    field public final long durationMs;
+    field public final int eventType;
+    field public final int netId;
+  }
+
+  public final class ValidationProbeEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
+    method public int describeContents();
+    method public static void logEvent(int, long, int, int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.metrics.ValidationProbeEvent> CREATOR;
+    field public static final int PROBE_HTTP = 0; // 0x0
+    field public static final int PROBE_HTTPS = 1; // 0x1
     field public final long durationMs;
     field public final int netId;
+    field public final int probeType;
     field public final int returnCode;
   }
 
diff --git a/core/java/android/net/metrics/CaptivePortalCheckResultEvent.java b/core/java/android/net/metrics/CaptivePortalCheckResultEvent.java
deleted file mode 100644
index 02ab63e..0000000
--- a/core/java/android/net/metrics/CaptivePortalCheckResultEvent.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.net.metrics;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-@SystemApi
-public final class CaptivePortalCheckResultEvent extends IpConnectivityEvent implements Parcelable {
-    public final int netId;
-    public final int result;
-
-    private CaptivePortalCheckResultEvent(int netId, int result) {
-        this.netId = netId;
-        this.result = result;
-    }
-
-    private CaptivePortalCheckResultEvent(Parcel in) {
-        this.netId = in.readInt();
-        this.result = in.readInt();
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
-        out.writeInt(result);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<CaptivePortalCheckResultEvent> CREATOR
-        = new Parcelable.Creator<CaptivePortalCheckResultEvent>() {
-            public CaptivePortalCheckResultEvent createFromParcel(Parcel in) {
-                return new CaptivePortalCheckResultEvent(in);
-            }
-
-            public CaptivePortalCheckResultEvent[] newArray(int size) {
-                return new CaptivePortalCheckResultEvent[size];
-            }
-        };
-
-    public static void logEvent(int netId, int result) {
-        logEvent(IPCE_NETMON_CHECK_RESULT, new CaptivePortalCheckResultEvent(netId, result));
-    }
-};
diff --git a/core/java/android/net/metrics/CaptivePortalStateChangeEvent.java b/core/java/android/net/metrics/CaptivePortalStateChangeEvent.java
deleted file mode 100644
index a67589a..0000000
--- a/core/java/android/net/metrics/CaptivePortalStateChangeEvent.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.net.metrics;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-@SystemApi
-public final class CaptivePortalStateChangeEvent extends IpConnectivityEvent implements Parcelable {
-    public static final int NETWORK_MONITOR_CONNECTED    = 0;
-    public static final int NETWORK_MONITOR_DISCONNECTED = 1;
-    public static final int NETWORK_MONITOR_VALIDATED    = 2;
-
-    public final int netId;
-    public final int state;
-
-    public CaptivePortalStateChangeEvent(int netId, int state) {
-        this.netId = netId;
-        this.state = state;
-    }
-
-    public CaptivePortalStateChangeEvent(Parcel in) {
-        netId = in.readInt();
-        state = in.readInt();
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
-        out.writeInt(state);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<CaptivePortalStateChangeEvent> CREATOR
-        = new Parcelable.Creator<CaptivePortalStateChangeEvent>() {
-        public CaptivePortalStateChangeEvent createFromParcel(Parcel in) {
-            return new CaptivePortalStateChangeEvent(in);
-        }
-
-        public CaptivePortalStateChangeEvent[] newArray(int size) {
-            return new CaptivePortalStateChangeEvent[size];
-        }
-    };
-
-    public static void logEvent(int netId, int state) {
-        logEvent(IPCE_NETMON_STATE_CHANGE, new CaptivePortalStateChangeEvent(netId, state));
-    }
-};
diff --git a/core/java/android/net/metrics/NetworkEvent.java b/core/java/android/net/metrics/NetworkEvent.java
new file mode 100644
index 0000000..b15dcee
--- /dev/null
+++ b/core/java/android/net/metrics/NetworkEvent.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 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 android.net.metrics;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * {@hide}
+ */
+@SystemApi
+public final class NetworkEvent extends IpConnectivityEvent implements Parcelable {
+
+    public static final int NETWORK_CONNECTED            = 1;
+    public static final int NETWORK_VALIDATED            = 2;
+    public static final int NETWORK_VALIDATION_FAILED    = 3;
+    public static final int NETWORK_CAPTIVE_PORTAL_FOUND = 4;
+    public static final int NETWORK_LINGER               = 5;
+    public static final int NETWORK_UNLINGER             = 6;
+    public static final int NETWORK_DISCONNECTED         = 7;
+
+    public final int netId;
+    public final int eventType;
+    public final long durationMs;
+
+    private NetworkEvent(int netId, int eventType, long durationMs) {
+        this.netId = netId;
+        this.eventType = eventType;
+        this.durationMs = durationMs;
+    }
+
+    private NetworkEvent(Parcel in) {
+        netId = in.readInt();
+        eventType = in.readInt();
+        durationMs = in.readLong();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(netId);
+        out.writeInt(eventType);
+        out.writeLong(durationMs);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<NetworkEvent> CREATOR
+        = new Parcelable.Creator<NetworkEvent>() {
+        public NetworkEvent createFromParcel(Parcel in) {
+            return new NetworkEvent(in);
+        }
+
+        public NetworkEvent[] newArray(int size) {
+            return new NetworkEvent[size];
+        }
+    };
+
+    public static void logEvent(int netId, int eventType) {
+        logEvent(IPCE_NETMON_STATE_CHANGE, new NetworkEvent(netId, eventType, 0));
+    }
+
+    public static void logValidated(int netId, long durationMs) {
+        logEvent(IPCE_NETMON_VALIDATED, new NetworkEvent(netId, NETWORK_VALIDATED, durationMs));
+    }
+
+    public static void logCaptivePortalFound(int netId, long durationMs) {
+        final NetworkEvent ev = new NetworkEvent(netId, NETWORK_CAPTIVE_PORTAL_FOUND, durationMs);
+        logEvent(IPCE_NETMON_CAPPORT_FOUND, ev);
+    }
+};
diff --git a/core/java/android/net/metrics/NetworkMonitorEvent.java b/core/java/android/net/metrics/NetworkMonitorEvent.java
deleted file mode 100644
index 2371266..0000000
--- a/core/java/android/net/metrics/NetworkMonitorEvent.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.net.metrics;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-@SystemApi
-public final class NetworkMonitorEvent extends IpConnectivityEvent implements Parcelable {
-    public final int netId;
-    public final long durationMs;
-    public final int returnCode;
-
-    private NetworkMonitorEvent(int netId, long durationMs, int returnCode) {
-        this.netId = netId;
-        this.durationMs = durationMs;
-        this.returnCode = returnCode;
-    }
-
-    public NetworkMonitorEvent(Parcel in) {
-        netId = in.readInt();
-        durationMs = in.readLong();
-        returnCode = in.readInt();
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
-        out.writeLong(durationMs);
-        out.writeInt(returnCode);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<NetworkMonitorEvent> CREATOR
-        = new Parcelable.Creator<NetworkMonitorEvent>() {
-        public NetworkMonitorEvent createFromParcel(Parcel in) {
-            return new NetworkMonitorEvent(in);
-        }
-
-        public NetworkMonitorEvent[] newArray(int size) {
-            return new NetworkMonitorEvent[size];
-        }
-    };
-
-    private static void logEvent(int eventType, int netId, long durationMs, int returnCode) {
-        logEvent(eventType, new NetworkMonitorEvent(netId, durationMs, returnCode));
-    }
-
-    public static void logValidated(int netId, long durationMs) {
-        logEvent(IPCE_NETMON_VALIDATED, netId, durationMs, 0);
-    }
-
-    public static void logPortalProbeEvent(int netId, long durationMs, int returnCode) {
-        logEvent(IPCE_NETMON_PORTAL_PROBE, netId, durationMs, returnCode);
-    }
-
-    public static void logCaptivePortalFound(int netId, long durationMs) {
-        logEvent(IPCE_NETMON_CAPPORT_FOUND, netId, durationMs, 0);
-    }
-};
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
new file mode 100644
index 0000000..0a524c6
--- /dev/null
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 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 android.net.metrics;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * {@hide}
+ */
+@SystemApi
+public final class ValidationProbeEvent extends IpConnectivityEvent implements Parcelable {
+
+    public static final int PROBE_HTTP  = 0;
+    public static final int PROBE_HTTPS = 1;
+
+    public final int netId;
+    public final long durationMs;
+    public final int probeType;
+    public final int returnCode;
+
+    private ValidationProbeEvent(int netId, long durationMs, int probeType, int returnCode) {
+        this.netId = netId;
+        this.durationMs = durationMs;
+        this.probeType = probeType;
+        this.returnCode = returnCode;
+    }
+
+    private ValidationProbeEvent(Parcel in) {
+        netId = in.readInt();
+        durationMs = in.readLong();
+        probeType = in.readInt();
+        returnCode = in.readInt();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(netId);
+        out.writeLong(durationMs);
+        out.writeInt(probeType);
+        out.writeInt(returnCode);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<ValidationProbeEvent> CREATOR
+        = new Parcelable.Creator<ValidationProbeEvent>() {
+        public ValidationProbeEvent createFromParcel(Parcel in) {
+            return new ValidationProbeEvent(in);
+        }
+
+        public ValidationProbeEvent[] newArray(int size) {
+            return new ValidationProbeEvent[size];
+        }
+    };
+
+    public static void logEvent(int netId, long durationMs, int probeType, int returnCode) {
+        logEvent(IPCE_NETMON_PORTAL_PROBE,
+                 new ValidationProbeEvent(netId, durationMs, probeType, returnCode));
+    }
+};
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b965f64..b069361 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -72,6 +72,7 @@
 import android.net.UidRange;
 import android.net.Uri;
 import android.net.metrics.DefaultNetworkEvent;
+import android.net.metrics.NetworkEvent;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -2109,6 +2110,7 @@
 
     private void linger(NetworkAgentInfo nai) {
         nai.lingering = true;
+        NetworkEvent.logEvent(nai.network.netId, NetworkEvent.NETWORK_LINGER);
         nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_LINGER);
         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING);
     }
@@ -2122,6 +2124,7 @@
         nai.networkLingered.clear();
         if (!nai.lingering) return;
         nai.lingering = false;
+        NetworkEvent.logEvent(nai.network.netId, NetworkEvent.NETWORK_UNLINGER);
         if (VDBG) log("Canceling linger of " + nai.name());
         nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
     }
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 381a110..f7784ac 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -34,9 +34,8 @@
 import android.net.ProxyInfo;
 import android.net.TrafficStats;
 import android.net.Uri;
-import android.net.metrics.CaptivePortalCheckResultEvent;
-import android.net.metrics.CaptivePortalStateChangeEvent;
-import android.net.metrics.NetworkMonitorEvent;
+import android.net.metrics.ValidationProbeEvent;
+import android.net.metrics.NetworkEvent;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.util.Stopwatch;
@@ -306,13 +305,11 @@
                     transitionTo(mLingeringState);
                     return HANDLED;
                 case CMD_NETWORK_CONNECTED:
-                    CaptivePortalStateChangeEvent.logEvent(mNetId,
-                            CaptivePortalStateChangeEvent.NETWORK_MONITOR_CONNECTED);
+                    NetworkEvent.logEvent(mNetId, NetworkEvent.NETWORK_CONNECTED);
                     transitionTo(mEvaluatingState);
                     return HANDLED;
                 case CMD_NETWORK_DISCONNECTED:
-                    CaptivePortalStateChangeEvent.logEvent(mNetId,
-                            CaptivePortalStateChangeEvent.NETWORK_MONITOR_DISCONNECTED);
+                    NetworkEvent.logEvent(mNetId, NetworkEvent.NETWORK_DISCONNECTED);
                     if (mLaunchCaptivePortalAppBroadcastReceiver != null) {
                         mContext.unregisterReceiver(mLaunchCaptivePortalAppBroadcastReceiver);
                         mLaunchCaptivePortalAppBroadcastReceiver = null;
@@ -363,11 +360,9 @@
         @Override
         public void enter() {
             if (mEvaluationTimer.isRunning()) {
-                NetworkMonitorEvent.logValidated(mNetId, mEvaluationTimer.stop());
+                NetworkEvent.logValidated(mNetId, mEvaluationTimer.stop());
                 mEvaluationTimer.reset();
             }
-            CaptivePortalStateChangeEvent.logEvent(mNetId,
-                   CaptivePortalStateChangeEvent.NETWORK_MONITOR_VALIDATED);
             mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
                     NETWORK_TEST_RESULT_VALID, mNetworkAgentInfo.network.netId, null));
         }
@@ -497,7 +492,6 @@
                     // will be unresponsive. isCaptivePortal() could be executed on another Thread
                     // if this is found to cause problems.
                     CaptivePortalProbeResult probeResult = isCaptivePortal();
-                    CaptivePortalCheckResultEvent.logEvent(mNetId, probeResult.mHttpResponseCode);
                     if (probeResult.mHttpResponseCode == 204) {
                         transitionTo(mValidatedState);
                     } else if (probeResult.mHttpResponseCode >= 200 &&
@@ -508,6 +502,7 @@
                     } else {
                         final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
                         sendMessageDelayed(msg, mReevaluateDelayMs);
+                        NetworkEvent.logEvent(mNetId, NetworkEvent.NETWORK_VALIDATION_FAILED);
                         mConnectivityServiceHandler.sendMessage(obtainMessage(
                                 EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetId,
                                 probeResult.mRedirectUrl));
@@ -568,7 +563,7 @@
         @Override
         public void enter() {
             if (mEvaluationTimer.isRunning()) {
-                NetworkMonitorEvent.logCaptivePortalFound(mNetId, mEvaluationTimer.stop());
+                NetworkEvent.logCaptivePortalFound(mNetId, mEvaluationTimer.stop());
                 mEvaluationTimer.reset();
             }
             // Don't annoy user with sign-in notifications.
@@ -779,7 +774,8 @@
                 urlConnection.disconnect();
             }
         }
-        NetworkMonitorEvent.logPortalProbeEvent(mNetId, probeTimer.stop(), httpResponseCode);
+        final int probeType = ValidationProbeEvent.PROBE_HTTP;
+        ValidationProbeEvent.logEvent(mNetId, probeTimer.stop(), probeType, httpResponseCode);
         return new CaptivePortalProbeResult(httpResponseCode, redirectUrl);
     }