Merge "Add logs for changes in capabilities and score"
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index e7d049f..e07601f 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -2066,6 +2066,36 @@
}
/**
+ * Returns a short but human-readable string of updates from an older set of capabilities.
+ * @param old the old capabilities to diff from
+ * @return a string fit for logging differences, or null if no differences.
+ * this never returns the empty string.
+ * @hide
+ */
+ @Nullable
+ public String describeCapsDifferencesFrom(@Nullable final NetworkCapabilities old) {
+ final long oldCaps = null == old ? 0 : old.mNetworkCapabilities;
+ final long changed = oldCaps ^ mNetworkCapabilities;
+ if (0 == changed) return null;
+ // If the control reaches here, there are changes (additions, removals, or both) so
+ // the code below is guaranteed to add something to the string and can't return "".
+ final long removed = oldCaps & changed;
+ final long added = mNetworkCapabilities & changed;
+ final StringBuilder sb = new StringBuilder();
+ if (0 != removed) {
+ sb.append("-");
+ appendStringRepresentationOfBitMaskToStringBuilder(sb, removed,
+ NetworkCapabilities::capabilityNameOf, "-");
+ }
+ if (0 != added) {
+ sb.append("+");
+ appendStringRepresentationOfBitMaskToStringBuilder(sb, added,
+ NetworkCapabilities::capabilityNameOf, "+");
+ }
+ return sb.toString();
+ }
+
+ /**
* Checks that our requestable capabilities are the same as those of the given
* {@code NetworkCapabilities}.
*
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index d409d51..e732001 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -8008,6 +8008,10 @@
@NonNull final NetworkCapabilities nc) {
NetworkCapabilities newNc = mixInCapabilities(nai, nc);
if (Objects.equals(nai.networkCapabilities, newNc)) return;
+ final String differences = newNc.describeCapsDifferencesFrom(nai.networkCapabilities);
+ if (null != differences) {
+ Log.i(TAG, "Update capabilities for net " + nai.network + " : " + differences);
+ }
updateNetworkPermissions(nai, newNc);
final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
diff --git a/service/src/com/android/server/connectivity/FullScore.java b/service/src/com/android/server/connectivity/FullScore.java
index aec4a71..2303894 100644
--- a/service/src/com/android/server/connectivity/FullScore.java
+++ b/service/src/com/android/server/connectivity/FullScore.java
@@ -23,7 +23,10 @@
import static android.net.NetworkScore.KEEP_CONNECTED_NONE;
import static android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI;
+import static com.android.net.module.util.BitUtils.appendStringRepresentationOfBitMaskToStringBuilder;
+
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkScore;
@@ -333,6 +336,35 @@
+ 5 * mKeepConnectedReason;
}
+ /**
+ * Returns a short but human-readable string of updates from an older score.
+ * @param old the old capabilities to diff from
+ * @return a string fit for logging differences, or null if no differences.
+ * this method cannot return the empty string.
+ */
+ @Nullable
+ public String describeDifferencesFrom(@Nullable final FullScore old) {
+ final long oldPolicies = null == old ? 0 : old.mPolicies;
+ final long changed = oldPolicies ^ mPolicies;
+ if (0 == changed) return null;
+ // If the control reaches here, there are changes (additions, removals, or both) so
+ // the code below is guaranteed to add something to the string and can't return "".
+ final long removed = oldPolicies & changed;
+ final long added = mPolicies & changed;
+ final StringBuilder sb = new StringBuilder();
+ if (0 != removed) {
+ sb.append("-");
+ appendStringRepresentationOfBitMaskToStringBuilder(sb, removed,
+ FullScore::policyNameOf, "-");
+ }
+ if (0 != added) {
+ sb.append("+");
+ appendStringRepresentationOfBitMaskToStringBuilder(sb, added,
+ FullScore::policyNameOf, "+");
+ }
+ return sb.toString();
+ }
+
// Example output :
// Score(Policies : EVER_USER_SELECTED&IS_VALIDATED ; KeepConnected : )
@Override
diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
index 2e92d43..85282cb 100644
--- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -1003,9 +1003,7 @@
@NonNull final NetworkCapabilities nc) {
final NetworkCapabilities oldNc = networkCapabilities;
networkCapabilities = nc;
- mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, everValidated(),
- 0L != getAvoidUnvalidated(), yieldToBadWiFi(),
- 0L != mFirstEvaluationConcludedTime, isDestroyed());
+ updateScoreForNetworkAgentUpdate();
final NetworkMonitorManager nm = mNetworkMonitor;
if (nm != null) {
nm.notifyNetworkCapabilitiesChanged(nc);
@@ -1207,9 +1205,11 @@
* Mix-in the ConnectivityService-managed bits in the score.
*/
public void setScore(final NetworkScore score) {
+ final FullScore oldScore = mScore;
mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig,
everValidated(), 0L != getAvoidUnvalidated(), yieldToBadWiFi(),
0L != mFirstEvaluationConcludedTime, isDestroyed());
+ maybeLogDifferences(oldScore);
}
/**
@@ -1218,9 +1218,22 @@
* Call this after changing any data that might affect the score (e.g., agent config).
*/
public void updateScoreForNetworkAgentUpdate() {
+ final FullScore oldScore = mScore;
mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig,
everValidated(), 0L != getAvoidUnvalidated(), yieldToBadWiFi(),
0L != mFirstEvaluationConcludedTime, isDestroyed());
+ maybeLogDifferences(oldScore);
+ }
+
+ /**
+ * Prints score differences to logcat, if any.
+ * @param oldScore the old score. Differences from |oldScore| to |this| are logged, if any.
+ */
+ public void maybeLogDifferences(final FullScore oldScore) {
+ final String differences = mScore.describeDifferencesFrom(oldScore);
+ if (null != differences) {
+ Log.i(TAG, "Update score for net " + network + " : " + differences);
+ }
}
/**
diff --git a/tests/common/java/android/net/NetworkCapabilitiesTest.java b/tests/common/java/android/net/NetworkCapabilitiesTest.java
index c30e1d3..7b374d2 100644
--- a/tests/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/common/java/android/net/NetworkCapabilitiesTest.java
@@ -36,6 +36,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
@@ -1370,4 +1371,23 @@
assertEquals(expectedNcBuilder.build(), restrictedNc);
}
+
+ @Test
+ public void testDescribeCapsDifferences() throws Exception {
+ final NetworkCapabilities nc1 = new NetworkCapabilities.Builder()
+ .addCapability(NET_CAPABILITY_MMS)
+ .addCapability(NET_CAPABILITY_OEM_PAID)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build();
+ final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
+ .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL)
+ .addCapability(NET_CAPABILITY_SUPL)
+ .addCapability(NET_CAPABILITY_VALIDATED)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build();
+ assertEquals("-MMS-OEM_PAID+SUPL+VALIDATED+CAPTIVE_PORTAL",
+ nc2.describeCapsDifferencesFrom(nc1));
+ assertEquals("-SUPL-VALIDATED-CAPTIVE_PORTAL+MMS+OEM_PAID",
+ nc1.describeCapsDifferencesFrom(nc2));
+ }
}
diff --git a/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt b/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
index b39e960..3520c5b 100644
--- a/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
@@ -152,4 +152,16 @@
assertNotEquals(ns3, ns1)
assertFalse(ns1.equals(ns4))
}
+
+ @Test
+ fun testDescribeDifferences() {
+ val ns1 = FullScore((1L shl POLICY_EVER_EVALUATED) or (1L shl POLICY_IS_VALIDATED),
+ KEEP_CONNECTED_NONE)
+ val ns2 = FullScore((1L shl POLICY_IS_VALIDATED) or (1L shl POLICY_IS_VPN) or
+ (1L shl POLICY_IS_DESTROYED), KEEP_CONNECTED_NONE)
+ assertEquals("-EVER_EVALUATED+IS_DESTROYED+IS_VPN",
+ ns2.describeDifferencesFrom(ns1))
+ assertEquals("-IS_DESTROYED-IS_VPN+EVER_EVALUATED",
+ ns1.describeDifferencesFrom(ns2))
+ }
}