Loading services/core/java/com/android/server/net/NetworkPolicyManagerService.java +61 −7 Original line number Diff line number Diff line Loading @@ -98,8 +98,6 @@ import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkTemplate.MATCH_CARRIER; import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.buildTemplateCarrierMetered; import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED; import static android.os.Trace.TRACE_TAG_NETWORK; import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED; Loading Loading @@ -168,7 +166,6 @@ import android.net.ConnectivityManager.NetworkCallback; import android.net.INetworkManagementEventObserver; import android.net.INetworkPolicyListener; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkIdentity; Loading Loading @@ -1344,7 +1341,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { }; /** * Check {@link NetworkPolicy} against current {@link INetworkStatsService} * Check {@link NetworkPolicy} against current {@link NetworkStatsManager} * to show visible notifications as needed. */ @GuardedBy("mNetworkPoliciesSecondLock") Loading Loading @@ -2341,6 +2338,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return policy; } /** * Template to match all metered carrier networks with the given IMSI. * * @hide */ public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) { Objects.requireNonNull(subscriberId); return new NetworkTemplate.Builder(MATCH_CARRIER) .setSubscriberIds(Set.of(subscriberId)) .setMeteredness(METERED_YES).build(); } /** * Update the given {@link NetworkPolicy} based on any carrier-provided * defaults via {@link SubscriptionPlan} or {@link CarrierConfigManager}. Loading Loading @@ -2744,7 +2753,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { out.startTag(null, TAG_NETWORK_POLICY); writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); final String subscriberId = template.getSubscriberId(); final String subscriberId = template.getSubscriberIds().isEmpty() ? null : template.getSubscriberIds().iterator().next(); if (subscriberId != null) { out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); } Loading Loading @@ -3121,7 +3131,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } // When two normalized templates conflict, prefer the most // restrictive policy policy.template = NetworkTemplate.normalize(policy.template, mMergedSubscriberIds); policy.template = normalizeTemplate(policy.template, mMergedSubscriberIds); final NetworkPolicy existing = mNetworkPolicy.get(policy.template); if (existing == null || existing.compareTo(policy) > 0) { if (existing != null) { Loading @@ -3132,6 +3142,46 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } /** * Examine the given template and normalize it. * We pick the "lowest" merged subscriber as the primary * for key purposes, and expand the template to match all other merged * subscribers. * * There can be multiple merged subscriberIds for multi-SIM devices. * * <p> * For example, given an incoming template matching B, and the currently * active merge set [A,B], we'd return a new template that primarily matches * A, but also matches B. */ private static NetworkTemplate normalizeTemplate(@NonNull NetworkTemplate template, @NonNull List<String[]> mergedList) { // Now there are several types of network which uses Subscriber Id to store network // information. For instance: // 1. A merged carrier wifi network which has TYPE_WIFI with a Subscriber Id. // 2. A typical cellular network could have TYPE_MOBILE with a Subscriber Id. if (template.getSubscriberIds().isEmpty()) return template; for (final String[] merged : mergedList) { // TODO: Handle incompatible subscriberIds if that happens in practice. for (final String subscriberId : template.getSubscriberIds()) { if (com.android.net.module.util.CollectionUtils.contains(merged, subscriberId)) { // Requested template subscriber is part of the merged group; return // a template that matches all merged subscribers. return new NetworkTemplate.Builder(template.getMatchRule()) .setWifiNetworkKeys(template.getWifiNetworkKeys()) .setSubscriberIds(Set.of(merged)) .setMeteredness(template.getMeteredness()) .build(); } } } return template; } @Override public void snoozeLimit(NetworkTemplate template) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); Loading Loading @@ -5583,7 +5633,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); NetworkTemplate templateCarrier = subscriber != null ? buildTemplateCarrierMetered(subscriber) : null; NetworkTemplate templateMobile = buildTemplateMobileAll(subscriber); NetworkTemplate templateMobile = subscriber != null ? new NetworkTemplate.Builder(MATCH_MOBILE) .setSubscriberIds(Set.of(subscriber)) .setMeteredness(android.net.NetworkStats.METERED_YES) .build() : null; for (NetworkPolicy policy : policies) { // All policies loaded from disk will be carrier templates, and setting will also only // set carrier templates, but we clear mobile templates just in case one is set by Loading services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +17 −11 Original line number Diff line number Diff line Loading @@ -51,10 +51,9 @@ import static android.net.NetworkPolicyManager.uidRulesToString; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.net.NetworkStats.METERED_NO; import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkTemplate.MATCH_CARRIER; import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.buildTemplateCarrierMetered; import static android.net.NetworkTemplate.buildTemplateWifi; import static android.net.TrafficStats.MB_IN_BYTES; import static android.net.NetworkTemplate.MATCH_WIFI; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED; import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT; Loading Loading @@ -205,6 +204,7 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; Loading @@ -229,10 +229,12 @@ public class NetworkPolicyManagerServiceTest { private static final int TEST_SUB_ID = 42; private static final Network TEST_NETWORK = mock(Network.class, CALLS_REAL_METHODS); private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_WIFI_NETWORK_KEY); private static NetworkTemplate sTemplateWifi = new NetworkTemplate.Builder(MATCH_WIFI) .setWifiNetworkKeys(Set.of(TEST_WIFI_NETWORK_KEY)).build(); private static NetworkTemplate sTemplateCarrierMetered = buildTemplateCarrierMetered(TEST_IMSI); new NetworkTemplate.Builder(MATCH_CARRIER) .setSubscriberIds(Set.of(TEST_IMSI)) .setMeteredness(METERED_YES).build(); /** * Path on assets where files used by {@link NetPolicyXml} are located. Loading Loading @@ -1160,11 +1162,12 @@ public class NetworkPolicyManagerServiceTest { mPolicyListener.expect().onMeteredIfacesChanged(any()); setNetworkPolicies(new NetworkPolicy( sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false)); sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, DataUnit.MEBIBYTES.toBytes(1), DataUnit.MEBIBYTES.toBytes(2), false)); mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512); DataUnit.MEBIBYTES.toBytes(2) - 512); } @Test Loading Loading @@ -1252,7 +1255,7 @@ public class NetworkPolicyManagerServiceTest { reset(mTelephonyManager, mNetworkManager, mNotifManager); TelephonyManager tmSub = expectMobileDefaults(); mService.snoozeLimit(NetworkTemplate.buildTemplateCarrierMetered(TEST_IMSI)); mService.snoozeLimit(sTemplateCarrierMetered); mService.updateNetworks(); verify(tmSub, atLeastOnce()).setPolicyDataEnabled(true); Loading Loading @@ -1955,7 +1958,7 @@ public class NetworkPolicyManagerServiceTest { assertEquals("Unexpected number of network policies", 1, policies.length); NetworkPolicy actualPolicy = policies[0]; assertEquals("Unexpected template match rule in network policies", NetworkTemplate.MATCH_WIFI, MATCH_WIFI, actualPolicy.template.getMatchRule()); assertEquals("Unexpected subscriberIds size in network policies", actualPolicy.template.getSubscriberIds().size(), 0); Loading Loading @@ -2026,7 +2029,10 @@ public class NetworkPolicyManagerServiceTest { private static NetworkPolicy buildFakeCarrierPolicy(int cycleDay, long warningBytes, long limitBytes, boolean inferred) { final NetworkTemplate template = buildTemplateCarrierMetered(FAKE_SUBSCRIBER_ID); // TODO: Refactor this to use sTemplateCarrierMetered. final NetworkTemplate template = new NetworkTemplate.Builder(MATCH_CARRIER) .setSubscriberIds(Set.of(FAKE_SUBSCRIBER_ID)) .setMeteredness(METERED_YES).build(); return new NetworkPolicy(template, cycleDay, TimeZone.getDefault().getID(), warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred); } Loading Loading
services/core/java/com/android/server/net/NetworkPolicyManagerService.java +61 −7 Original line number Diff line number Diff line Loading @@ -98,8 +98,6 @@ import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkTemplate.MATCH_CARRIER; import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.buildTemplateCarrierMetered; import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED; import static android.os.Trace.TRACE_TAG_NETWORK; import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED; Loading Loading @@ -168,7 +166,6 @@ import android.net.ConnectivityManager.NetworkCallback; import android.net.INetworkManagementEventObserver; import android.net.INetworkPolicyListener; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkIdentity; Loading Loading @@ -1344,7 +1341,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { }; /** * Check {@link NetworkPolicy} against current {@link INetworkStatsService} * Check {@link NetworkPolicy} against current {@link NetworkStatsManager} * to show visible notifications as needed. */ @GuardedBy("mNetworkPoliciesSecondLock") Loading Loading @@ -2341,6 +2338,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return policy; } /** * Template to match all metered carrier networks with the given IMSI. * * @hide */ public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) { Objects.requireNonNull(subscriberId); return new NetworkTemplate.Builder(MATCH_CARRIER) .setSubscriberIds(Set.of(subscriberId)) .setMeteredness(METERED_YES).build(); } /** * Update the given {@link NetworkPolicy} based on any carrier-provided * defaults via {@link SubscriptionPlan} or {@link CarrierConfigManager}. Loading Loading @@ -2744,7 +2753,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { out.startTag(null, TAG_NETWORK_POLICY); writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); final String subscriberId = template.getSubscriberId(); final String subscriberId = template.getSubscriberIds().isEmpty() ? null : template.getSubscriberIds().iterator().next(); if (subscriberId != null) { out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); } Loading Loading @@ -3121,7 +3131,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } // When two normalized templates conflict, prefer the most // restrictive policy policy.template = NetworkTemplate.normalize(policy.template, mMergedSubscriberIds); policy.template = normalizeTemplate(policy.template, mMergedSubscriberIds); final NetworkPolicy existing = mNetworkPolicy.get(policy.template); if (existing == null || existing.compareTo(policy) > 0) { if (existing != null) { Loading @@ -3132,6 +3142,46 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } /** * Examine the given template and normalize it. * We pick the "lowest" merged subscriber as the primary * for key purposes, and expand the template to match all other merged * subscribers. * * There can be multiple merged subscriberIds for multi-SIM devices. * * <p> * For example, given an incoming template matching B, and the currently * active merge set [A,B], we'd return a new template that primarily matches * A, but also matches B. */ private static NetworkTemplate normalizeTemplate(@NonNull NetworkTemplate template, @NonNull List<String[]> mergedList) { // Now there are several types of network which uses Subscriber Id to store network // information. For instance: // 1. A merged carrier wifi network which has TYPE_WIFI with a Subscriber Id. // 2. A typical cellular network could have TYPE_MOBILE with a Subscriber Id. if (template.getSubscriberIds().isEmpty()) return template; for (final String[] merged : mergedList) { // TODO: Handle incompatible subscriberIds if that happens in practice. for (final String subscriberId : template.getSubscriberIds()) { if (com.android.net.module.util.CollectionUtils.contains(merged, subscriberId)) { // Requested template subscriber is part of the merged group; return // a template that matches all merged subscribers. return new NetworkTemplate.Builder(template.getMatchRule()) .setWifiNetworkKeys(template.getWifiNetworkKeys()) .setSubscriberIds(Set.of(merged)) .setMeteredness(template.getMeteredness()) .build(); } } } return template; } @Override public void snoozeLimit(NetworkTemplate template) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); Loading Loading @@ -5583,7 +5633,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); NetworkTemplate templateCarrier = subscriber != null ? buildTemplateCarrierMetered(subscriber) : null; NetworkTemplate templateMobile = buildTemplateMobileAll(subscriber); NetworkTemplate templateMobile = subscriber != null ? new NetworkTemplate.Builder(MATCH_MOBILE) .setSubscriberIds(Set.of(subscriber)) .setMeteredness(android.net.NetworkStats.METERED_YES) .build() : null; for (NetworkPolicy policy : policies) { // All policies loaded from disk will be carrier templates, and setting will also only // set carrier templates, but we clear mobile templates just in case one is set by Loading
services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +17 −11 Original line number Diff line number Diff line Loading @@ -51,10 +51,9 @@ import static android.net.NetworkPolicyManager.uidRulesToString; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.net.NetworkStats.METERED_NO; import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkTemplate.MATCH_CARRIER; import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.buildTemplateCarrierMetered; import static android.net.NetworkTemplate.buildTemplateWifi; import static android.net.TrafficStats.MB_IN_BYTES; import static android.net.NetworkTemplate.MATCH_WIFI; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED; import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT; Loading Loading @@ -205,6 +204,7 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; Loading @@ -229,10 +229,12 @@ public class NetworkPolicyManagerServiceTest { private static final int TEST_SUB_ID = 42; private static final Network TEST_NETWORK = mock(Network.class, CALLS_REAL_METHODS); private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_WIFI_NETWORK_KEY); private static NetworkTemplate sTemplateWifi = new NetworkTemplate.Builder(MATCH_WIFI) .setWifiNetworkKeys(Set.of(TEST_WIFI_NETWORK_KEY)).build(); private static NetworkTemplate sTemplateCarrierMetered = buildTemplateCarrierMetered(TEST_IMSI); new NetworkTemplate.Builder(MATCH_CARRIER) .setSubscriberIds(Set.of(TEST_IMSI)) .setMeteredness(METERED_YES).build(); /** * Path on assets where files used by {@link NetPolicyXml} are located. Loading Loading @@ -1160,11 +1162,12 @@ public class NetworkPolicyManagerServiceTest { mPolicyListener.expect().onMeteredIfacesChanged(any()); setNetworkPolicies(new NetworkPolicy( sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false)); sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, DataUnit.MEBIBYTES.toBytes(1), DataUnit.MEBIBYTES.toBytes(2), false)); mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512); DataUnit.MEBIBYTES.toBytes(2) - 512); } @Test Loading Loading @@ -1252,7 +1255,7 @@ public class NetworkPolicyManagerServiceTest { reset(mTelephonyManager, mNetworkManager, mNotifManager); TelephonyManager tmSub = expectMobileDefaults(); mService.snoozeLimit(NetworkTemplate.buildTemplateCarrierMetered(TEST_IMSI)); mService.snoozeLimit(sTemplateCarrierMetered); mService.updateNetworks(); verify(tmSub, atLeastOnce()).setPolicyDataEnabled(true); Loading Loading @@ -1955,7 +1958,7 @@ public class NetworkPolicyManagerServiceTest { assertEquals("Unexpected number of network policies", 1, policies.length); NetworkPolicy actualPolicy = policies[0]; assertEquals("Unexpected template match rule in network policies", NetworkTemplate.MATCH_WIFI, MATCH_WIFI, actualPolicy.template.getMatchRule()); assertEquals("Unexpected subscriberIds size in network policies", actualPolicy.template.getSubscriberIds().size(), 0); Loading Loading @@ -2026,7 +2029,10 @@ public class NetworkPolicyManagerServiceTest { private static NetworkPolicy buildFakeCarrierPolicy(int cycleDay, long warningBytes, long limitBytes, boolean inferred) { final NetworkTemplate template = buildTemplateCarrierMetered(FAKE_SUBSCRIBER_ID); // TODO: Refactor this to use sTemplateCarrierMetered. final NetworkTemplate template = new NetworkTemplate.Builder(MATCH_CARRIER) .setSubscriberIds(Set.of(FAKE_SUBSCRIBER_ID)) .setMeteredness(METERED_YES).build(); return new NetworkPolicy(template, cycleDay, TimeZone.getDefault().getID(), warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred); } Loading