diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java index 70fe5d677b4f..123c55c27d1c 100644 --- a/core/java/android/net/NetworkPolicy.java +++ b/core/java/android/net/NetworkPolicy.java @@ -18,8 +18,11 @@ package android.net; import static android.net.NetworkStats.METERED_ALL; import static android.net.NetworkStats.METERED_YES; +import static android.net.NetworkTemplate.MATCH_BLUETOOTH; import static android.net.NetworkTemplate.MATCH_CARRIER; +import static android.net.NetworkTemplate.MATCH_ETHERNET; import static android.net.NetworkTemplate.MATCH_MOBILE; +import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT; import android.annotation.NonNull; @@ -324,7 +327,7 @@ public class NetworkPolicy implements Parcelable, Comparable { @NonNull private byte[] getNetworkTemplateBytesForBackup() throws IOException { - if (!template.isPersistable()) { + if (!isTemplatePersistable(this.template)) { Log.wtf(TAG, "Trying to backup non-persistable template: " + this); } @@ -378,4 +381,28 @@ public class NetworkPolicy implements Parcelable, Comparable { "Restored network template contains unknown match rule " + matchRule, e); } } + + /** + * Check if the template can be persisted into disk. + */ + public static boolean isTemplatePersistable(@NonNull NetworkTemplate template) { + switch (template.getMatchRule()) { + case MATCH_BLUETOOTH: + case MATCH_ETHERNET: + return true; + case MATCH_CARRIER: + case MATCH_MOBILE: + return !template.getSubscriberIds().isEmpty(); + case MATCH_WIFI: + if (Objects.equals(template.getWifiNetworkKey(), null) + && template.getSubscriberIds().isEmpty()) { + return false; + } + return true; + default: + // Don't allow persistable for unknown types or legacy types such as + // MATCH_MOBILE_WILDCARD, MATCH_PROXY, etc. + return false; + } + } } diff --git a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt index d936cad15689..121caef87f6f 100644 --- a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt +++ b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt @@ -16,6 +16,10 @@ package android.net +import android.net.NetworkTemplate.MATCH_BLUETOOTH +import android.net.NetworkTemplate.MATCH_ETHERNET +import android.net.NetworkTemplate.MATCH_MOBILE +import android.net.NetworkTemplate.MATCH_WIFI import android.text.format.Time.TIMEZONE_UTC import androidx.test.runner.AndroidJUnit4 import org.junit.Test @@ -24,6 +28,8 @@ import java.io.ByteArrayInputStream import java.io.DataInputStream import java.time.ZoneId import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue private const val TEST_IMSI1 = "TESTIMSI1" private const val TEST_SSID1 = "TESTISSID1" @@ -53,4 +59,26 @@ class NetworkPolicyTest { val restored = NetworkPolicy.getNetworkPolicyFromBackup(stream) assertEquals(policy, restored) } + + @Test + fun testIsTemplatePersistable() { + listOf(MATCH_MOBILE, MATCH_WIFI).forEach { + // Verify wildcard templates cannot be persistable. + assertFalse(NetworkPolicy.isTemplatePersistable(NetworkTemplate.Builder(it).build())) + + // Verify mobile/wifi templates can be persistable if the Subscriber Id is supplied. + assertTrue(NetworkPolicy.isTemplatePersistable(NetworkTemplate.Builder(it) + .setSubscriberIds(setOf(TEST_IMSI1)).build())) + } + + // Verify bluetooth and ethernet templates can be persistable without any other + // field is supplied. + listOf(MATCH_BLUETOOTH, MATCH_ETHERNET).forEach { + assertTrue(NetworkPolicy.isTemplatePersistable(NetworkTemplate.Builder(it).build())) + } + + // Verify wifi template can be persistable if the Wifi Network Key is supplied. + assertTrue(NetworkPolicy.isTemplatePersistable(NetworkTemplate.Builder(MATCH_WIFI) + .setWifiNetworkKey(TEST_SSID1).build())) + } } \ No newline at end of file diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java index 7dd04c5d42b9..d85291318fa4 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java @@ -559,30 +559,6 @@ public final class NetworkTemplate implements Parcelable { } } - /** - * Check if the template can be persisted into disk. - * - * @hide - */ - // TODO: Move to the NetworkPolicy. - public boolean isPersistable() { - switch (mMatchRule) { - case MATCH_MOBILE_WILDCARD: - case MATCH_WIFI_WILDCARD: - return false; - case MATCH_CARRIER: - return mSubscriberId != null; - case MATCH_WIFI: - if (Objects.equals(mNetworkId, WIFI_NETWORK_KEY_ALL) - && mSubscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL) { - return false; - } - return true; - default: - return true; - } - } - /** * Get match rule of the template. See {@code MATCH_*}. */ diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 5de5fd3cc79c..dee69e02b371 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -2456,7 +2456,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { networkId, templateMeteredness, NetworkStats.ROAMING_ALL, NetworkStats.DEFAULT_NETWORK_ALL, NetworkTemplate.NETWORK_TYPE_ALL, NetworkTemplate.OEM_MANAGED_ALL, subscriberIdMatchRule); - if (template.isPersistable()) { + if (NetworkPolicy.isTemplatePersistable(template)) { mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule, warningBytes, limitBytes, lastWarningSnooze, lastLimitSnooze, metered, inferred)); @@ -2663,7 +2663,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (int i = 0; i < mNetworkPolicy.size(); i++) { final NetworkPolicy policy = mNetworkPolicy.valueAt(i); final NetworkTemplate template = policy.template; - if (!template.isPersistable()) continue; + if (!NetworkPolicy.isTemplatePersistable(template)) continue; out.startTag(null, TAG_NETWORK_POLICY); writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule());