[BR06] Support check whether network is blocked by data saver
This change adds a DataSaverStatusTracker, which is a helper
class to continuously track data saver status through NPMS
public API and intents. ConnectivityManager#isUidNetworkingBlocked
would use this cached information along with bpf maps to decide
whether networking of an uid is blocked.
Test: atest FrameworksNetTests:android.net.connectivity.android.net.BpfNetMapsReaderTest
Test: atest ConnectivityCoverageTests:android.net.connectivity.android.net.ConnectivityManagerTest
Bug: 297836825
Change-Id: I7e13191759430f3ea1f4dec7facc02f16be7146d
diff --git a/framework/src/android/net/BpfNetMapsReader.java b/framework/src/android/net/BpfNetMapsReader.java
index 9bce9cd..37c58f0 100644
--- a/framework/src/android/net/BpfNetMapsReader.java
+++ b/framework/src/android/net/BpfNetMapsReader.java
@@ -17,6 +17,8 @@
package android.net;
import static android.net.BpfNetMapsConstants.CONFIGURATION_MAP_PATH;
+import static android.net.BpfNetMapsConstants.HAPPY_BOX_MATCH;
+import static android.net.BpfNetMapsConstants.PENALTY_BOX_MATCH;
import static android.net.BpfNetMapsConstants.UID_OWNER_MAP_PATH;
import static android.net.BpfNetMapsConstants.UID_RULES_CONFIGURATION_KEY;
import static android.net.BpfNetMapsUtils.getMatchByFirewallChain;
@@ -213,13 +215,16 @@
* Return whether the network is blocked by firewall chains for the given uid.
*
* @param uid The target uid.
+ * @param isNetworkMetered Whether the target network is metered.
+ * @param isDataSaverEnabled Whether the data saver is enabled.
*
* @return True if the network is blocked. Otherwise, false.
* @throws ServiceSpecificException if the read fails.
*
* @hide
*/
- public boolean isUidBlockedByFirewallChains(final int uid) {
+ public boolean isUidNetworkingBlocked(final int uid, boolean isNetworkMetered,
+ boolean isDataSaverEnabled) {
throwIfPreT("isUidBlockedByFirewallChains is not available on pre-T devices");
final long uidRuleConfig;
@@ -235,6 +240,13 @@
final boolean blockedByAllowChains = 0 != (uidRuleConfig & ~uidMatch & sMaskDropIfUnset);
final boolean blockedByDenyChains = 0 != (uidRuleConfig & uidMatch & sMaskDropIfSet);
- return blockedByAllowChains || blockedByDenyChains;
+ if (blockedByAllowChains || blockedByDenyChains) {
+ return true;
+ }
+
+ if (!isNetworkMetered) return false;
+ if ((uidMatch & PENALTY_BOX_MATCH) != 0) return true;
+ if ((uidMatch & HAPPY_BOX_MATCH) != 0) return false;
+ return isDataSaverEnabled;
}
}