Track interfaces and roaming changed event history

Currently netpolicy event log includes the meteredness changed
event but it's also called while the roaming changed. The
roaming event should be tracked as well so add roaming event
for it. Besides, it would be better to track the interfaces changed
so this change also adds interfaces event for tracking interfaces
changed history.

Bug: 237640200
Test: FrameworksNetTest
      adb shell dumpsys netpolicy
Change-Id: I788fb8896d3cd5b47916c687fde05ef7ad88456b
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index c963154..4a0a07b 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -38,6 +38,7 @@
 import android.app.ActivityManager.ProcessCapability;
 import android.net.NetworkPolicyManager;
 import android.os.UserHandle;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Slog;
 
@@ -79,6 +80,8 @@
     private static final int EVENT_APP_IDLE_WL_CHANGED = 14;
     private static final int EVENT_METERED_ALLOWLIST_CHANGED = 15;
     private static final int EVENT_METERED_DENYLIST_CHANGED = 16;
+    private static final int EVENT_ROAMING_CHANGED = 17;
+    private static final int EVENT_INTERFACES_CHANGED = 18;
 
     private final LogBuffer mNetworkBlockedBuffer = new LogBuffer(MAX_NETWORK_BLOCKED_LOG_SIZE);
     private final LogBuffer mUidStateChangeBuffer = new LogBuffer(MAX_LOG_SIZE);
@@ -265,6 +268,24 @@
         }
     }
 
+    void roamingChanged(int netId, boolean newRoaming) {
+        synchronized (mLock) {
+            if (LOGD || mDebugUid != INVALID_UID) {
+                Slog.d(TAG, getRoamingChangedLog(netId, newRoaming));
+            }
+            mEventsBuffer.roamingChanged(netId, newRoaming);
+        }
+    }
+
+    void interfacesChanged(int netId, ArraySet<String> newIfaces) {
+        synchronized (mLock) {
+            if (LOGD || mDebugUid != INVALID_UID) {
+                Slog.d(TAG, getInterfacesChangedLog(netId, newIfaces.toString()));
+            }
+            mEventsBuffer.interfacesChanged(netId, newIfaces.toString());
+        }
+    }
+
     void setDebugUid(int uid) {
         mDebugUid = uid;
     }
@@ -348,6 +369,14 @@
         return "metered-denylist for " + uid + " changed to " + added;
     }
 
+    private static String getRoamingChangedLog(int netId, boolean newRoaming) {
+        return "Roaming of netId=" + netId + " changed to " + newRoaming;
+    }
+
+    private static String getInterfacesChangedLog(int netId, String newIfaces) {
+        return "Interfaces of netId=" + netId + " changed to " + newIfaces;
+    }
+
     private static String getFirewallChainName(int chain) {
         switch (chain) {
             case FIREWALL_CHAIN_DOZABLE:
@@ -570,6 +599,28 @@
             data.timeStamp = System.currentTimeMillis();
         }
 
+        public void roamingChanged(int netId, boolean newRoaming) {
+            final Data data = getNextSlot();
+            if (data == null) return;
+
+            data.reset();
+            data.type = EVENT_ROAMING_CHANGED;
+            data.ifield1 = netId;
+            data.bfield1 = newRoaming;
+            data.timeStamp = System.currentTimeMillis();
+        }
+
+        public void interfacesChanged(int netId, String newIfaces) {
+            final Data data = getNextSlot();
+            if (data == null) return;
+
+            data.reset();
+            data.type = EVENT_INTERFACES_CHANGED;
+            data.ifield1 = netId;
+            data.sfield1 = newIfaces;
+            data.timeStamp = System.currentTimeMillis();
+        }
+
         public void reverseDump(IndentingPrintWriter pw) {
             final Data[] allData = toArray();
             for (int i = allData.length - 1; i >= 0; --i) {
@@ -621,6 +672,10 @@
                     return getMeteredAllowlistChangedLog(data.ifield1, data.bfield1);
                 case EVENT_METERED_DENYLIST_CHANGED:
                     return getMeteredDenylistChangedLog(data.ifield1, data.bfield1);
+                case EVENT_ROAMING_CHANGED:
+                    return getRoamingChangedLog(data.ifield1, data.bfield1);
+                case EVENT_INTERFACES_CHANGED:
+                    return getInterfacesChangedLog(data.ifield1, data.sfield1);
                 default:
                     return String.valueOf(data.type);
             }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 5d80a8f..261274f 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1382,8 +1382,17 @@
                 final boolean roamingChanged = updateCapabilityChange(
                         mNetworkRoaming, newRoaming, network);
 
-                if (meteredChanged || roamingChanged) {
+                final boolean shouldUpdateNetworkRules = meteredChanged || roamingChanged;
+
+                if (meteredChanged) {
                     mLogger.meterednessChanged(network.getNetId(), newMetered);
+                }
+
+                if (roamingChanged) {
+                    mLogger.roamingChanged(network.getNetId(), newRoaming);
+                }
+
+                if (shouldUpdateNetworkRules) {
                     updateNetworkRulesNL();
                 }
             }
@@ -1396,6 +1405,7 @@
                 final boolean ifacesChanged = updateNetworkToIfacesNL(network.getNetId(),
                         newIfaces);
                 if (ifacesChanged) {
+                    mLogger.interfacesChanged(network.getNetId(), newIfaces);
                     updateNetworkRulesNL();
                 }
             }