Stop using IIpConnectivityMetrics in ConnectivityService.

Currently, ConnectivityService calls the IpConnectivityMetrics
service class directly to log default network events. This is
incompatible with ConnectivityService being in a mainline module.
Replace direct access to IIpConnectivityMetrics with public
methods in IpConnectivityLog, which is @SystemApi class.

The new methods are not yet @SystemApi, but they can be made so
if desired. Alternatively, these metrics could be deleted.

Also remove the IpConectivityMetrics service from the
service-connectivity JAR, and go back to starting it from
SystemServer.java, which is what was happening a few hours ago
before aosp/1542626 was merged.

Test: builds, boots
Test: atest FrameworksNetTests
Test: "dumpsys connmetrics" shows events, including default network events
Change-Id: I9d6147d93590363a2f8f83f39f05c03d001b4851
diff --git a/core/java/android/net/IIpConnectivityMetrics.aidl b/core/java/android/net/IIpConnectivityMetrics.aidl
index aeaf09d..aa3682d 100644
--- a/core/java/android/net/IIpConnectivityMetrics.aidl
+++ b/core/java/android/net/IIpConnectivityMetrics.aidl
@@ -19,6 +19,9 @@
 import android.os.Parcelable;
 import android.net.ConnectivityMetricsEvent;
 import android.net.INetdEventCallback;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 
 /** {@hide} */
 interface IIpConnectivityMetrics {
@@ -29,6 +32,11 @@
      */
     int logEvent(in ConnectivityMetricsEvent event);
 
+    void logDefaultNetworkValidity(boolean valid);
+    void logDefaultNetworkEvent(in Network defaultNetwork, int score, boolean validated,
+            in LinkProperties lp, in NetworkCapabilities nc, in Network previousDefaultNetwork,
+            int previousScore, in LinkProperties previousLp, in NetworkCapabilities previousNc);
+
     /**
      * Callback can be registered by DevicePolicyManager or NetworkWatchlistService only.
      * @return status {@code true} if registering/unregistering of the callback was successful,
diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java
index a008d85..58ea915 100644
--- a/core/java/android/net/metrics/IpConnectivityLog.java
+++ b/core/java/android/net/metrics/IpConnectivityLog.java
@@ -17,10 +17,13 @@
 package android.net.metrics;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
+import android.net.LinkProperties;
 import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -66,6 +69,9 @@
         final IIpConnectivityMetrics service =
                 IIpConnectivityMetrics.Stub.asInterface(ServiceManager.getService(SERVICE_NAME));
         if (service == null) {
+            if (DBG) {
+                Log.d(TAG, SERVICE_NAME + " service was not ready");
+            }
             return false;
         }
         // Two threads racing here will write the same pointer because getService
@@ -83,9 +89,6 @@
      */
     public boolean log(@NonNull ConnectivityMetricsEvent ev) {
         if (!checkLoggerService()) {
-            if (DBG) {
-                Log.d(TAG, SERVICE_NAME + " service was not ready");
-            }
             return false;
         }
         if (ev.timestamp == 0) {
@@ -161,6 +164,56 @@
         return log(makeEv(data));
     }
 
+    /**
+     * Logs the validation status of the default network.
+     * @param valid whether the current default network was validated (i.e., whether it had
+     *              {@link NetworkCapabilities.NET_CAPABILITY_VALIDATED}
+     * @return true if the event was successfully logged.
+     * @hide
+     */
+    public boolean logDefaultNetworkValidity(boolean valid) {
+        if (!checkLoggerService()) {
+            return false;
+        }
+        try {
+            mService.logDefaultNetworkValidity(valid);
+        } catch (RemoteException ignored) {
+            // Only called within the system server.
+        }
+        return true;
+    }
+
+    /**
+     * Logs a change in the default network.
+     *
+     * @param defaultNetwork the current default network
+     * @param score the current score of {@code defaultNetwork}
+     * @param lp the {@link LinkProperties} of {@code defaultNetwork}
+     * @param nc the {@link NetworkCapabilities} of the {@code defaultNetwork}
+     * @param validated whether {@code defaultNetwork} network is validated
+     * @param previousDefaultNetwork the previous default network
+     * @param previousScore the score of {@code previousDefaultNetwork}
+     * @param previousLp the {@link LinkProperties} of {@code previousDefaultNetwork}
+     * @param previousNc the {@link NetworkCapabilities} of {@code previousDefaultNetwork}
+     * @return true if the event was successfully logged.
+     * @hide
+     */
+    public boolean logDefaultNetworkEvent(@Nullable Network defaultNetwork, int score,
+            boolean validated, @Nullable LinkProperties lp, @Nullable NetworkCapabilities nc,
+            @Nullable Network previousDefaultNetwork, int previousScore,
+            @Nullable LinkProperties previousLp, @Nullable NetworkCapabilities previousNc) {
+        if (!checkLoggerService()) {
+            return false;
+        }
+        try {
+            mService.logDefaultNetworkEvent(defaultNetwork, score, validated, lp, nc,
+                    previousDefaultNetwork, previousScore, previousLp, previousNc);
+        } catch (RemoteException ignored) {
+            // Only called within the system server.
+        }
+        return true;
+    }
+
     private static ConnectivityMetricsEvent makeEv(Event data) {
         ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent();
         ev.data = data;
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 01060ca..307d344 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -189,15 +189,11 @@
         "java/com/android/server/connectivity/AutodestructReference.java",
         "java/com/android/server/connectivity/ConnectivityConstants.java",
         "java/com/android/server/connectivity/DataConnectionStats.java",
-        "java/com/android/server/connectivity/DefaultNetworkMetrics.java",
         "java/com/android/server/connectivity/DnsManager.java",
-        "java/com/android/server/connectivity/IpConnectivityEventBuilder.java",
-        "java/com/android/server/connectivity/IpConnectivityMetrics.java",
         "java/com/android/server/connectivity/KeepaliveTracker.java",
         "java/com/android/server/connectivity/LingerMonitor.java",
         "java/com/android/server/connectivity/MockableSystemProperties.java",
         "java/com/android/server/connectivity/Nat464Xlat.java",
-        "java/com/android/server/connectivity/NetdEventListenerService.java",
         "java/com/android/server/connectivity/NetworkAgentInfo.java",
         "java/com/android/server/connectivity/NetworkDiagnostics.java",
         "java/com/android/server/connectivity/NetworkNotificationManager.java",
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 020c17a..0986b00 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -87,7 +87,6 @@
 import android.net.IConnectivityDiagnosticsCallback;
 import android.net.IConnectivityManager;
 import android.net.IDnsResolver;
-import android.net.IIpConnectivityMetrics;
 import android.net.INetd;
 import android.net.INetworkManagementEventObserver;
 import android.net.INetworkMonitor;
@@ -154,7 +153,6 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -927,14 +925,6 @@
                     "no IpConnectivityMetrics service");
         }
 
-        /**
-         * @see IpConnectivityMetrics
-         */
-        public IIpConnectivityMetrics getIpConnectivityMetrics() {
-            return IIpConnectivityMetrics.Stub.asInterface(
-                    ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
-        }
-
         public IBatteryStats getBatteryStatsService() {
             return BatteryStatsService.getService();
         }
@@ -2983,9 +2973,7 @@
             }
             if (valid != nai.lastValidated) {
                 if (wasDefault) {
-                    mDeps.getMetricsLogger()
-                            .defaultNetworkMetrics().logDefaultNetworkValidity(
-                            SystemClock.elapsedRealtime(), valid);
+                    mMetricsLog.logDefaultNetworkValidity(valid);
                 }
                 final int oldScore = nai.getCurrentScore();
                 nai.lastValidated = valid;
@@ -3413,7 +3401,9 @@
             // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence
             // whose timestamps tell how long it takes to recover a default network.
             long now = SystemClock.elapsedRealtime();
-            mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai);
+            mMetricsLog.logDefaultNetworkEvent(null, 0, false,
+                    null /* lp */, null /* nc */, nai.network, nai.getCurrentScore(),
+                    nai.linkProperties, nai.networkCapabilities);
         }
         notifyIfacesChangedForNetworkStats();
         // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
@@ -7167,9 +7157,28 @@
             updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork);
             // Notify system services of the new default.
             makeDefault(newDefaultNetwork);
+
             // Log 0 -> X and Y -> X default network transitions, where X is the new default.
-            mDeps.getMetricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(
-                    now, newDefaultNetwork, oldDefaultNetwork);
+            final Network network = (newDefaultNetwork != null) ? newDefaultNetwork.network : null;
+            final int score = (newDefaultNetwork != null) ? newDefaultNetwork.getCurrentScore() : 0;
+            final boolean validated = newDefaultNetwork != null && newDefaultNetwork.lastValidated;
+            final LinkProperties lp = (newDefaultNetwork != null)
+                    ? newDefaultNetwork.linkProperties : null;
+            final NetworkCapabilities nc = (newDefaultNetwork != null)
+                    ? newDefaultNetwork.networkCapabilities : null;
+
+            final Network prevNetwork = (oldDefaultNetwork != null)
+                    ? oldDefaultNetwork.network : null;
+            final int prevScore = (oldDefaultNetwork != null)
+                    ? oldDefaultNetwork.getCurrentScore() : 0;
+            final LinkProperties prevLp = (oldDefaultNetwork != null)
+                    ? oldDefaultNetwork.linkProperties : null;
+            final NetworkCapabilities prevNc = (oldDefaultNetwork != null)
+                    ? oldDefaultNetwork.networkCapabilities : null;
+
+            mMetricsLog.logDefaultNetworkEvent(network, score, validated, lp, nc,
+                    prevNetwork, prevScore, prevLp, prevNc);
+
             // Have a new default network, release the transition wakelock in
             scheduleReleaseNetworkTransitionWakelock();
         }
diff --git a/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java b/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java
index 995bb24..8cd1fd6 100644
--- a/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java
+++ b/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java
@@ -17,6 +17,8 @@
 package com.android.server.connectivity;
 
 import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.metrics.DefaultNetworkEvent;
 import android.os.SystemClock;
 
@@ -61,7 +63,7 @@
     private int mLastTransports;
 
     public DefaultNetworkMetrics() {
-        newDefaultNetwork(creationTimeMs, null);
+        newDefaultNetwork(creationTimeMs, null, 0, false, null, null);
     }
 
     public synchronized void listEvents(PrintWriter pw) {
@@ -117,13 +119,21 @@
         mCurrentDefaultNetwork.validatedMs += timeMs - mLastValidationTimeMs;
     }
 
-    public synchronized void logDefaultNetworkEvent(
-            long timeMs, NetworkAgentInfo newNai, NetworkAgentInfo oldNai) {
-        logCurrentDefaultNetwork(timeMs, oldNai);
-        newDefaultNetwork(timeMs, newNai);
+    /**
+     * Logs a default network event.
+     * @see {IpConnectivityLog#logDefaultNetworkEvent}.
+     */
+    public synchronized void logDefaultNetworkEvent(long timeMs, Network defaultNetwork, int score,
+            boolean validated, LinkProperties lp, NetworkCapabilities nc,
+            Network previousDefaultNetwork, int previousScore, LinkProperties previousLp,
+            NetworkCapabilities previousNc) {
+        logCurrentDefaultNetwork(timeMs, previousDefaultNetwork, previousScore, previousLp,
+                previousNc);
+        newDefaultNetwork(timeMs, defaultNetwork, score, validated, lp, nc);
     }
 
-    private void logCurrentDefaultNetwork(long timeMs, NetworkAgentInfo oldNai) {
+    private void logCurrentDefaultNetwork(long timeMs, Network network, int score,
+            LinkProperties lp, NetworkCapabilities nc) {
         if (mIsCurrentlyValid) {
             updateValidationTime(timeMs);
         }
@@ -131,10 +141,10 @@
         ev.updateDuration(timeMs);
         ev.previousTransports = mLastTransports;
         // oldNai is null if the system had no default network before the transition.
-        if (oldNai != null) {
+        if (network != null) {
             // The system acquired a new default network.
-            fillLinkInfo(ev, oldNai);
-            ev.finalScore = oldNai.getCurrentScore();
+            fillLinkInfo(ev, network, lp, nc);
+            ev.finalScore = score;
         }
         // Only change transport of the previous default network if the event currently logged
         // corresponds to an existing default network, and not to the absence of a default network.
@@ -147,14 +157,15 @@
         mEventsLog.append(ev);
     }
 
-    private void newDefaultNetwork(long timeMs, NetworkAgentInfo newNai) {
+    private void newDefaultNetwork(long timeMs, Network network, int score, boolean validated,
+            LinkProperties lp, NetworkCapabilities nc) {
         DefaultNetworkEvent ev = new DefaultNetworkEvent(timeMs);
         ev.durationMs = timeMs;
         // newNai is null if the system has no default network after the transition.
-        if (newNai != null) {
-            fillLinkInfo(ev, newNai);
-            ev.initialScore = newNai.getCurrentScore();
-            if (newNai.lastValidated) {
+        if (network != null) {
+            fillLinkInfo(ev, network, lp, nc);
+            ev.initialScore = score;
+            if (validated) {
                 mIsCurrentlyValid = true;
                 mLastValidationTimeMs = timeMs;
             }
@@ -164,10 +175,10 @@
         mCurrentDefaultNetwork = ev;
     }
 
-    private static void fillLinkInfo(DefaultNetworkEvent ev, NetworkAgentInfo nai) {
-        LinkProperties lp = nai.linkProperties;
-        ev.netId = nai.network().getNetId();
-        ev.transports |= BitUtils.packBits(nai.networkCapabilities.getTransportTypes());
+    private static void fillLinkInfo(DefaultNetworkEvent ev, Network network, LinkProperties lp,
+            NetworkCapabilities nc) {
+        ev.netId = network.getNetId();
+        ev.transports |= BitUtils.packBits(nc.getTransportTypes());
         ev.ipv4 |= lp.hasIpv4Address() && lp.hasIpv4DefaultRoute();
         ev.ipv6 |= lp.hasGlobalIpv6Address() && lp.hasIpv6DefaultRoute();
     }
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index b5d875d..1024556 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -20,11 +20,15 @@
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
 import android.net.INetdEventCallback;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.NetworkStack;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.IpConnectivityLog;
 import android.os.Binder;
 import android.os.Process;
+import android.os.SystemClock;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
@@ -122,8 +126,6 @@
 
     public IpConnectivityMetrics(Context ctx, ToIntFunction<Context> capacityGetter) {
         super(ctx);
-        // Load JNI libraries used by the IpConnectivityMetrics service and its dependencies
-        System.loadLibrary("service-connectivity");
         mCapacityGetter = capacityGetter;
         initBuffer();
     }
@@ -363,6 +365,21 @@
             }
             return mNetdListener.removeNetdEventCallback(callerType);
         }
+
+        @Override
+        public void logDefaultNetworkValidity(boolean valid) {
+            mDefaultNetworkMetrics.logDefaultNetworkValidity(SystemClock.elapsedRealtime(), valid);
+        }
+
+        @Override
+        public void logDefaultNetworkEvent(Network defaultNetwork, int score, boolean validated,
+                LinkProperties lp, NetworkCapabilities nc, Network previousDefaultNetwork,
+                int previousScore, LinkProperties previousLp, NetworkCapabilities previousNc) {
+            final long timeMs = SystemClock.elapsedRealtime();
+            mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs, defaultNetwork, score, validated,
+                    lp, nc,  previousDefaultNetwork, previousScore, previousLp, previousNc);
+        }
+
     };
 
     private static final ToIntFunction<Context> READ_BUFFER_SIZE = (ctx) -> {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d533848..4cd1348 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1222,8 +1222,7 @@
             }
 
             t.traceBegin("IpConnectivityMetrics");
-            mSystemServiceManager.startServiceFromJar(IP_CONNECTIVITY_METRICS_CLASS,
-                    CONNECTIVITY_SERVICE_APEX_PATH);
+            mSystemServiceManager.startService(IP_CONNECTIVITY_METRICS_CLASS);
             t.traceEnd();
 
             t.traceBegin("NetworkWatchlistService");
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 24b1343..7b93438 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -161,7 +161,6 @@
 import android.net.EthernetManager;
 import android.net.IConnectivityDiagnosticsCallback;
 import android.net.IDnsResolver;
-import android.net.IIpConnectivityMetrics;
 import android.net.INetd;
 import android.net.INetworkMonitor;
 import android.net.INetworkMonitorCallbacks;
@@ -359,7 +358,6 @@
     private HandlerThread mAlarmManagerThread;
     private TestNetIdManager mNetIdManager;
 
-    @Mock IIpConnectivityMetrics mIpConnectivityMetrics;
     @Mock IpConnectivityMetrics.Logger mMetricsService;
     @Mock DefaultNetworkMetrics mDefaultNetworkMetrics;
     @Mock DeviceIdleInternal mDeviceIdleInternal;
@@ -1373,7 +1371,6 @@
         doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any());
         doReturn(mMetricsService).when(deps).getMetricsLogger();
         doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
-        doReturn(mIpConnectivityMetrics).when(deps).getIpConnectivityMetrics();
         doReturn(mBatteryStatsService).when(deps).getBatteryStatsService();
         doAnswer(inv -> {
             mPolicyTracker = new WrappedMultinetworkPolicyTracker(
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 3a07166..8c5d1d6 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -124,6 +124,22 @@
         assertEquals("", output2);
     }
 
+    private void logDefaultNetworkEvent(long timeMs, NetworkAgentInfo nai,
+            NetworkAgentInfo oldNai) {
+        final Network network = (nai != null) ? nai.network() : null;
+        final int score = (nai != null) ? nai.getCurrentScore() : 0;
+        final boolean validated = (nai != null) ? nai.lastValidated : false;
+        final LinkProperties lp = (nai != null) ? nai.linkProperties : null;
+        final NetworkCapabilities nc = (nai != null) ? nai.networkCapabilities : null;
+
+        final Network prevNetwork = (oldNai != null) ? oldNai.network() : null;
+        final int prevScore = (oldNai != null) ? oldNai.getCurrentScore() : 0;
+        final LinkProperties prevLp = (oldNai != null) ? oldNai.linkProperties : null;
+        final NetworkCapabilities prevNc = (oldNai != null) ? oldNai.networkCapabilities : null;
+
+        mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs, network, score, validated,
+                lp, nc, prevNetwork, prevScore, prevLp, prevNc);
+    }
     @Test
     public void testDefaultNetworkEvents() throws Exception {
         final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR});
@@ -147,7 +163,7 @@
         for (NetworkAgentInfo[] pair : defaultNetworks) {
             timeMs += durationMs;
             durationMs += durationMs;
-            mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs, pair[1], pair[0]);
+            logDefaultNetworkEvent(timeMs, pair[1], pair[0]);
         }
 
         String want = String.join("\n",
@@ -331,8 +347,8 @@
         final long wifi = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_WIFI});
         NetworkAgentInfo cellNai = makeNai(100, 50, false, true, cell);
         NetworkAgentInfo wifiNai = makeNai(101, 60, true, false, wifi);
-        mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs + 200, cellNai, null);
-        mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(timeMs + 300, wifiNai, cellNai);
+        logDefaultNetworkEvent(timeMs + 200L, cellNai, null);
+        logDefaultNetworkEvent(timeMs + 300L, wifiNai, cellNai);
 
         String want = String.join("\n",
                 "dropped_events: 0",