diff options
24 files changed, 495 insertions, 197 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 09c58ae51abf..6321aaa225b4 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -9453,7 +9453,9 @@ package android.provider { field public static final int MATCH_ALL_APN_SET_ID = -1; // 0xffffffff field public static final String MAX_CONNECTIONS = "max_conns"; field public static final String MODEM_PERSIST = "modem_cognitive"; - field public static final String MTU = "mtu"; + field @Deprecated public static final String MTU = "mtu"; + field public static final String MTU_V4 = "mtu_v4"; + field public static final String MTU_V6 = "mtu_v6"; field public static final int NO_APN_SET_ID = 0; // 0x0 field public static final String TIME_LIMIT_FOR_MAX_CONNECTIONS = "max_conns_time"; field public static final int UNEDITED = 0; // 0x0 diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java index 858819e15abc..2a8ff5185085 100644 --- a/core/java/android/bluetooth/BluetoothUuid.java +++ b/core/java/android/bluetooth/BluetoothUuid.java @@ -189,7 +189,7 @@ public final class BluetoothUuid { @NonNull @SystemApi public static final ParcelUuid CAP = - ParcelUuid.fromString("EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE"); + ParcelUuid.fromString("00001853-0000-1000-8000-00805F9B34FB"); /** @hide */ @NonNull @SystemApi diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java index b18e9be28eb5..fab692cba2f6 100644 --- a/core/java/android/net/Ikev2VpnProfile.java +++ b/core/java/android/net/Ikev2VpnProfile.java @@ -142,8 +142,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { boolean isBypassable, boolean isMetered, int maxMtu, - boolean restrictToTestNetworks) { - super(type); + boolean restrictToTestNetworks, + boolean excludeLocalRoutes) { + super(type, excludeLocalRoutes); checkNotNull(serverAddr, MISSING_PARAM_MSG_TMPL, "Server address"); checkNotNull(userIdentity, MISSING_PARAM_MSG_TMPL, "User Identity"); @@ -403,7 +404,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { && mIsBypassable == other.mIsBypassable && mIsMetered == other.mIsMetered && mMaxMtu == other.mMaxMtu - && mIsRestrictedToTestNetworks == other.mIsRestrictedToTestNetworks; + && mIsRestrictedToTestNetworks == other.mIsRestrictedToTestNetworks + && mExcludeLocalRoutes == other.mExcludeLocalRoutes; } /** @@ -417,7 +419,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @NonNull public VpnProfile toVpnProfile() throws IOException, GeneralSecurityException { final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */, - mIsRestrictedToTestNetworks); + mIsRestrictedToTestNetworks, mExcludeLocalRoutes); profile.type = mType; profile.server = mServerAddr; profile.ipsecIdentifier = mUserIdentity; @@ -518,6 +520,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { throw new IllegalArgumentException("Invalid auth method set"); } + builder.setExcludeLocalRoutes(profile.excludeLocalRoutes); + return builder.build(); } @@ -657,6 +661,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { private boolean mIsMetered = true; private int mMaxMtu = PlatformVpnProfile.MAX_MTU_DEFAULT; private boolean mIsRestrictedToTestNetworks = false; + private boolean mExcludeLocalRoutes = false; /** * Creates a new builder with the basic parameters of an IKEv2/IPsec VPN. @@ -902,6 +907,18 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { } /** + * Sets whether the local traffic is exempted from the VPN. + * + * @hide TODO(184750836): unhide once the implementation is completed + */ + @NonNull + @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) + public Builder setExcludeLocalRoutes(boolean excludeLocalRoutes) { + mExcludeLocalRoutes = excludeLocalRoutes; + return this; + } + + /** * Validates, builds and provisions the VpnProfile. * * @throws IllegalArgumentException if any of the required keys or values were invalid @@ -924,7 +941,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { mIsBypassable, mIsMetered, mMaxMtu, - mIsRestrictedToTestNetworks); + mIsRestrictedToTestNetworks, + mExcludeLocalRoutes); } } } diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java index d7e18573819a..8b3d49ef4964 100644 --- a/core/java/android/net/NetworkPolicy.java +++ b/core/java/android/net/NetworkPolicy.java @@ -369,11 +369,13 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { try { final NetworkTemplate.Builder builder = new NetworkTemplate.Builder(matchRule) - .setWifiNetworkKey(wifiNetworkKey) .setMeteredness(metered); if (subscriberId != null) { builder.setSubscriberIds(Set.of(subscriberId)); } + if (wifiNetworkKey != null) { + builder.setWifiNetworkKeys(Set.of(wifiNetworkKey)); + } return builder.build(); } catch (IllegalArgumentException e) { throw new BackupUtils.BadVersionException( @@ -393,7 +395,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { case MATCH_MOBILE: return !template.getSubscriberIds().isEmpty(); case MATCH_WIFI: - if (Objects.equals(template.getWifiNetworkKey(), null) + if (template.getWifiNetworkKeys().isEmpty() && template.getSubscriberIds().isEmpty()) { return false; } diff --git a/core/java/android/net/PlatformVpnProfile.java b/core/java/android/net/PlatformVpnProfile.java index 445ec91e4f46..777a90c8985c 100644 --- a/core/java/android/net/PlatformVpnProfile.java +++ b/core/java/android/net/PlatformVpnProfile.java @@ -66,15 +66,30 @@ public abstract class PlatformVpnProfile { @PlatformVpnType protected final int mType; /** @hide */ - PlatformVpnProfile(@PlatformVpnType int type) { + protected final boolean mExcludeLocalRoutes; + + /** @hide */ + PlatformVpnProfile(@PlatformVpnType int type, boolean excludeLocalRoutes) { mType = type; + mExcludeLocalRoutes = excludeLocalRoutes; } + /** Returns the profile integer type. */ @PlatformVpnType public final int getType() { return mType; } + + /** + * Returns if the local traffic is exempted from the VPN. + * + * @hide TODO(184750836): unhide once the implementation is completed + */ + public final boolean getExcludeLocalRoutes() { + return mExcludeLocalRoutes; + } + /** Returns a type string describing the VPN profile type */ @NonNull public final String getTypeString() { diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index 0adc00e56bf1..1b2646549dce 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -3758,6 +3758,25 @@ public final class Telephony { public static final String NETWORK_TYPE_BITMASK = "network_type_bitmask"; /** + * Lingering radio technology (network type) bitmask. + * To check what values can be contained, refer to the NETWORK_TYPE_ constants in + * {@link android.telephony.TelephonyManager}. + * Bitmask for a radio tech R is (1 << (R - 1)) + * <P>Type: INTEGER (long)</P> + * @hide + */ + public static final String LINGERING_NETWORK_TYPE_BITMASK = + "lingering_network_type_bitmask"; + + /** + * Sets whether the PDU session brought up by this APN should always be on. + * See 3GPP TS 23.501 section 5.6.13 + * <P>Type: INTEGER</P> + * @hide + */ + public static final String ALWAYS_ON = "always_on"; + + /** * MVNO type: * {@code SPN (Service Provider Name), IMSI, GID (Group Identifier Level 1)}. * <P>Type: TEXT</P> @@ -3835,11 +3854,31 @@ public final class Telephony { * connected, in bytes. * <p>Type: INTEGER </p> * @hide + * @deprecated use {@link #MTU_V4} or {@link #MTU_V6} instead */ @SystemApi + @Deprecated public static final String MTU = "mtu"; /** + * The MTU (maximum transmit unit) size of the mobile interface for IPv4 to which the APN is + * connected, in bytes. + * <p>Type: INTEGER </p> + * @hide + */ + @SystemApi + public static final String MTU_V4 = "mtu_v4"; + + /** + * The MTU (maximum transmit unit) size of the mobile interface for IPv6 to which the APN is + * connected, in bytes. + * <p>Type: INTEGER </p> + * @hide + */ + @SystemApi + public static final String MTU_V6 = "mtu_v6"; + + /** * APN edit status. APN could be added/edited/deleted by a user or carrier. * see all possible returned APN edit status. * <ul> diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java index 13274c6f27ee..29c7796d8660 100644 --- a/core/java/android/service/autofill/AutofillService.java +++ b/core/java/android/service/autofill/AutofillService.java @@ -465,7 +465,7 @@ import com.android.internal.os.IResultReceiver; * <p>Prior to Android {@link android.os.Build.VERSION_CODES#P}, the metrics covered just the * scenarios where the service knew how to autofill an activity, but Android * {@link android.os.Build.VERSION_CODES#P} introduced a new mechanism called field classification, - * which allows the service to dinamically classify the meaning of fields based on the existing user + * which allows the service to dynamically classify the meaning of fields based on the existing user * data known by the service. * * <p>Typically, field classification can be used to detect fields that can be autofilled with diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index 5f84b5a92305..d8dc1436128e 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -143,17 +143,24 @@ public final class VpnProfile implements Cloneable, Parcelable { public boolean areAuthParamsInline = false; // 23 public final boolean isRestrictedToTestNetworks; // 24 + public final boolean excludeLocalRoutes; // 25 + // Helper fields. @UnsupportedAppUsage public transient boolean saveLogin = false; public VpnProfile(String key) { - this(key, false); + this(key, false, false); } public VpnProfile(String key, boolean isRestrictedToTestNetworks) { + this(key, isRestrictedToTestNetworks, false); + } + + public VpnProfile(String key, boolean isRestrictedToTestNetworks, boolean excludeLocalRoutes) { this.key = key; this.isRestrictedToTestNetworks = isRestrictedToTestNetworks; + this.excludeLocalRoutes = excludeLocalRoutes; } @UnsupportedAppUsage @@ -183,6 +190,7 @@ public final class VpnProfile implements Cloneable, Parcelable { maxMtu = in.readInt(); areAuthParamsInline = in.readBoolean(); isRestrictedToTestNetworks = in.readBoolean(); + excludeLocalRoutes = in.readBoolean(); } /** @@ -230,6 +238,7 @@ public final class VpnProfile implements Cloneable, Parcelable { out.writeInt(maxMtu); out.writeBoolean(areAuthParamsInline); out.writeBoolean(isRestrictedToTestNetworks); + out.writeBoolean(excludeLocalRoutes); } /** @@ -249,8 +258,9 @@ public final class VpnProfile implements Cloneable, Parcelable { // 14-19: Standard profile, with option for serverCert, proxy // 24: Standard profile with serverCert, proxy and platform-VPN parameters // 25: Standard profile with platform-VPN parameters and isRestrictedToTestNetworks + // 26: Standard profile with platform-VPN parameters and excludeLocalRoutes if ((values.length < 14 || values.length > 19) - && values.length != 24 && values.length != 25) { + && values.length != 24 && values.length != 25 && values.length != 26) { return null; } @@ -261,7 +271,15 @@ public final class VpnProfile implements Cloneable, Parcelable { isRestrictedToTestNetworks = false; } - VpnProfile profile = new VpnProfile(key, isRestrictedToTestNetworks); + final boolean excludeLocalRoutes; + if (values.length >= 26) { + excludeLocalRoutes = Boolean.parseBoolean(values[25]); + } else { + excludeLocalRoutes = false; + } + + VpnProfile profile = new VpnProfile(key, isRestrictedToTestNetworks, + excludeLocalRoutes); profile.name = values[0]; profile.type = Integer.parseInt(values[1]); if (profile.type < 0 || profile.type > TYPE_MAX) { @@ -371,6 +389,8 @@ public final class VpnProfile implements Cloneable, Parcelable { builder.append(VALUE_DELIMITER).append(areAuthParamsInline); builder.append(VALUE_DELIMITER).append(isRestrictedToTestNetworks); + builder.append(VALUE_DELIMITER).append(excludeLocalRoutes); + return builder.toString().getBytes(StandardCharsets.UTF_8); } @@ -451,7 +471,7 @@ public final class VpnProfile implements Cloneable, Parcelable { key, type, server, username, password, dnsServers, searchDomains, routes, mppe, l2tpSecret, ipsecIdentifier, ipsecSecret, ipsecUserCert, ipsecCaCert, ipsecServerCert, proxy, mAllowedAlgorithms, isBypassable, isMetered, maxMtu, areAuthParamsInline, - isRestrictedToTestNetworks); + isRestrictedToTestNetworks, excludeLocalRoutes); } /** Checks VPN profiles for interior equality. */ @@ -484,7 +504,8 @@ public final class VpnProfile implements Cloneable, Parcelable { && isMetered == other.isMetered && maxMtu == other.maxMtu && areAuthParamsInline == other.areAuthParamsInline - && isRestrictedToTestNetworks == other.isRestrictedToTestNetworks; + && isRestrictedToTestNetworks == other.isRestrictedToTestNetworks + && excludeLocalRoutes == other.excludeLocalRoutes; } @NonNull diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index a13111143b0e..0f98b74441a7 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -228,8 +228,7 @@ static const char* PROFILE_BOOT_CLASS_PATH = "profilebootclasspath"; // TODO: Rename the server-level flag or remove. static const char* ENABLE_JITZYGOTE_IMAGE = "enable_apex_image"; // Flag to pass to the runtime when using the JIT Zygote image. -static const char* kJitZygoteImageOption = - "-Ximage:boot.art:/nonx/boot-framework.art!/system/etc/boot-image.prof"; +static const char* kJitZygoteImageOption = "-Xforcejitzygote"; // Feature flag name for disabling lock profiling. static const char* DISABLE_LOCK_PROFILING = "disable_lock_profiling"; @@ -983,9 +982,9 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p "--instruction-set-features=", "-Xcompiler-option"); /* - * When running with debug.generate-debug-info, add --generate-debug-info to - * the compiler options so that both JITted code and the boot image extension, - * if it is compiled on device, will include native debugging information. + * When running with debug.generate-debug-info, add --generate-debug-info to the compiler + * options so that both JITted code and the boot image, if it is compiled on device, will + * include native debugging information. */ property_get("debug.generate-debug-info", propBuf, ""); bool generate_debug_info = (strcmp(propBuf, "true") == 0); @@ -1008,7 +1007,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p property_get("dalvik.vm.extra-opts", extraOptsBuf, ""); parseExtraOpts(extraOptsBuf, NULL); - // Extra options for boot image extension generation. + // Extra options for boot image generation. if (skip_compilation) { addOption("-Xnoimage-dex2oat"); } else { @@ -1031,8 +1030,8 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p parseCompilerOption("dalvik.vm.image-dex2oat-cpu-set", dex2oatCpuSetImageBuf, "--cpu-set=", "-Ximage-compiler-option"); - // The runtime may compile a boot image extension, when necessary, not using installd. - // Thus, we need to pass the instruction-set-features/variant as an image-compiler-option. + // The runtime may compile a boot image, when necessary, not using installd. Thus, we need + // to pass the instruction-set-features/variant as an image-compiler-option. // Note: it is OK to reuse the buffer, as the values are exactly the same between // * compiler-option, used for runtime compilation (DexClassLoader) // * image-compiler-option, used for boot-image compilation on device diff --git a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt index 121caef87f6f..3c8f90c9c0f8 100644 --- a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt +++ b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt @@ -32,14 +32,14 @@ import kotlin.test.assertFalse import kotlin.test.assertTrue private const val TEST_IMSI1 = "TESTIMSI1" -private const val TEST_SSID1 = "TESTISSID1" +private const val TEST_WIFI_NETWORK_KEY1 = "TESTKEY1" @RunWith(AndroidJUnit4::class) class NetworkPolicyTest { @Test fun testTemplateBackupRestore() { assertPolicyBackupRestore(createTestPolicyForTemplate( - NetworkTemplate.buildTemplateWifi(TEST_SSID1))) + NetworkTemplate.buildTemplateWifi(TEST_WIFI_NETWORK_KEY1))) assertPolicyBackupRestore(createTestPolicyForTemplate( NetworkTemplate.buildTemplateMobileAll(TEST_IMSI1))) assertPolicyBackupRestore(createTestPolicyForTemplate( @@ -79,6 +79,6 @@ class NetworkPolicyTest { // Verify wifi template can be persistable if the Wifi Network Key is supplied. assertTrue(NetworkPolicy.isTemplatePersistable(NetworkTemplate.Builder(MATCH_WIFI) - .setWifiNetworkKey(TEST_SSID1).build())) + .setWifiNetworkKeys(setOf(TEST_WIFI_NETWORK_KEY1)).build())) } -}
\ No newline at end of file +} diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java index 875c6f52d9b2..77495646ea0c 100644 --- a/media/java/android/media/JetPlayer.java +++ b/media/java/android/media/JetPlayer.java @@ -31,35 +31,33 @@ import java.lang.ref.WeakReference; /** * JetPlayer provides access to JET content playback and control. - * - * <p>Please refer to the JET Creator User Manual for a presentation of the JET interactive - * music concept and how to use the JetCreator tool to create content to be player by JetPlayer. - * + * + * <p>Please refer to the + * <a href="https://developer.android.com/guide/topics/media/jet/jetcreator_manual">JET Creator User + * Manual</a> for a presentation of the JET interactive music concept and how to use the JetCreator + * tool to create content to be player by JetPlayer. + * * <p>Use of the JetPlayer class is based around the playback of a number of JET segments * sequentially added to a playback FIFO queue. The rendering of the MIDI content stored in each * segment can be dynamically affected by two mechanisms: * <ul> - * <li>tracks in a segment can be muted or unmuted at any moment, individually or through - * a mask (to change the mute state of multiple tracks at once)</li> - * <li>parts of tracks in a segment can be played at predefined points in the segment, in order - * to maintain synchronization with the other tracks in the segment. This is achieved through - * the notion of "clips", which can be triggered at any time, but that will play only at the - * right time, as authored in the corresponding JET file.</li> + * <li>Tracks in a segment can be muted or unmuted at any moment, individually or through a mask + * (to change the mute state of multiple tracks at once). + * <li>Parts of tracks in a segment can be played at predefined points in the segment, in order to + * maintain synchronization with the other tracks in the segment. This is achieved through the + * notion of "clips", which can be triggered at any time, but that will play only at the right + * time, as authored in the corresponding JET file. * </ul> - * As a result of the rendering and playback of the JET segments, the user of the JetPlayer instance - * can receive notifications from the JET engine relative to: + * + * <p>As a result of the rendering and playback of the JET segments, the user of the JetPlayer + * instance can receive notifications from the JET engine relative to: * <ul> - * <li>the playback state,</li> - * <li>the number of segments left to play in the queue,</li> - * <li>application controller events (CC80-83) to mark points in the MIDI segments.</li> + * <li>Playback state + * <li>Number of segments left to play in the queue + * <li>Application controller events (CC80-83) to mark points in the MIDI segments * </ul> - * Use {@link #getJetPlayer()} to construct a JetPlayer instance. JetPlayer is a singleton class. - * </p> * - * <div class="special reference"> - * <h3>Developer Guides</h3> - * <p>For more information about how to use JetPlayer, read the - * <a href="{@docRoot}guide/topics/media/jetplayer.html">JetPlayer</a> developer guide.</p></div> + * <p>Use {@link #getJetPlayer()} to construct a JetPlayer instance. JetPlayer is a singleton class. */ public class JetPlayer { @@ -140,7 +138,7 @@ public class JetPlayer //------------------------ /** * Factory method for the JetPlayer class. - * @return the singleton JetPlayer instance + * @return the singleton JetPlayer instance. */ public static JetPlayer getJetPlayer() { if (singletonRef == null) { @@ -203,7 +201,8 @@ public class JetPlayer // Getters //------------------------ /** - * Returns the maximum number of simultaneous MIDI tracks supported by JetPlayer + * Gets the maximum number of simultaneous MIDI tracks supported by JetPlayer. + * @return the maximum number of simultaneous MIDI tracks supported by JetPlayer. */ public static int getMaxTracks() { return JetPlayer.MAXTRACKS; @@ -459,10 +458,9 @@ public class JetPlayer //------------------------ /** * Sets the listener JetPlayer notifies when a JET event is generated by the rendering and - * playback engine. - * Notifications will be received in the same thread as the one in which the JetPlayer - * instance was created. - * @param listener + * playback engine. Notifications are received in the same thread as the one in which the + * JetPlayer instance was created. + * @param listener the listener that will be notified when a JET event is generated. */ public void setEventListener(OnJetEventListener listener) { setEventListener(listener, null); @@ -470,10 +468,9 @@ public class JetPlayer /** * Sets the listener JetPlayer notifies when a JET event is generated by the rendering and - * playback engine. - * Use this method to receive JET events in the Handler associated with another - * thread than the one in which you created the JetPlayer instance. - * @param listener + * playback engine. Use this method to receive JET events in the Handler associated with + * another thread than the one in which you created the JetPlayer instance. + * @param listener the listener that will be notified when a JET event is generated. * @param handler the Handler that will receive the event notification messages. */ public void setEventListener(OnJetEventListener listener, Handler handler) { diff --git a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java index 82c72ab1de7e..a316b8a617b7 100644 --- a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java +++ b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java @@ -138,6 +138,7 @@ public class NetworkStatsManager { mContext = context; mService = service; setPollOnOpen(true); + setAugmentWithSubscriptionPlan(true); } /** @hide */ @@ -169,16 +170,44 @@ public class NetworkStatsManager { } } - /** @hide */ - public Bucket querySummaryForDevice(NetworkTemplate template, - long startTime, long endTime) throws SecurityException, RemoteException { - Bucket bucket = null; - NetworkStats stats = new NetworkStats(mContext, template, mFlags, startTime, endTime, - mService); - bucket = stats.getDeviceSummaryForNetwork(); - - stats.close(); - return bucket; + /** + * Query network usage statistics summaries. + * + * Result is summarised data usage for the whole + * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and + * roaming. This means the bucket's start and end timestamp will be the same as the + * 'startTime' and 'endTime' arguments. State is going to be + * {@link NetworkStats.Bucket#STATE_ALL}, uid {@link NetworkStats.Bucket#UID_ALL}, + * tag {@link NetworkStats.Bucket#TAG_NONE}, + * default network {@link NetworkStats.Bucket#DEFAULT_NETWORK_ALL}, + * metered {@link NetworkStats.Bucket#METERED_ALL}, + * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}. + * This may take a long time, and apps should avoid calling this on their main thread. + * + * @param template Template used to match networks. See {@link NetworkTemplate}. + * @param startTime Start of period, in milliseconds since the Unix epoch, see + * {@link java.lang.System#currentTimeMillis}. + * @param endTime End of period, in milliseconds since the Unix epoch, see + * {@link java.lang.System#currentTimeMillis}. + * @return Bucket Summarised data usage. + * + * @hide + */ + @NonNull + @WorkerThread + // @SystemApi(client = MODULE_LIBRARIES) + public Bucket querySummaryForDevice(@NonNull NetworkTemplate template, + long startTime, long endTime) { + try { + NetworkStats stats = + new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); + Bucket bucket = stats.getDeviceSummaryForNetwork(); + stats.close(); + return bucket; + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + return null; // To make the compiler happy. } /** @@ -322,14 +351,37 @@ public class NetworkStatsManager { return querySummary(template, startTime, endTime); } - /** @hide */ - public NetworkStats querySummary(NetworkTemplate template, long startTime, - long endTime) throws SecurityException, RemoteException { - NetworkStats result; - result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); - result.startSummaryEnumeration(); - - return result; + /** + * Query network usage statistics summaries. + * + * The results will only include traffic made by UIDs belonging to the calling user profile. + * The results are aggregated over time, so that all buckets will have the same start and + * end timestamps as the passed arguments. Not aggregated over state, uid, default network, + * metered, or roaming. + * This may take a long time, and apps should avoid calling this on their main thread. + * + * @param template Template used to match networks. See {@link NetworkTemplate}. + * @param startTime Start of period, in milliseconds since the Unix epoch, see + * {@link java.lang.System#currentTimeMillis}. + * @param endTime End of period, in milliseconds since the Unix epoch, see + * {@link java.lang.System#currentTimeMillis}. + * @return Statistics which is described above. + * @hide + */ + @Nullable + // @SystemApi(client = MODULE_LIBRARIES) + @WorkerThread + public NetworkStats querySummary(@NonNull NetworkTemplate template, long startTime, + long endTime) throws SecurityException { + try { + NetworkStats result = + new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); + result.startSummaryEnumeration(); + return result; + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + return null; // To make the compiler happy. } /** diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java index eb8f43e3d073..8f1115e065dd 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java @@ -21,7 +21,6 @@ import static android.net.ConnectivityManager.TYPE_WIFI; import android.annotation.Nullable; import android.content.Context; import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; import android.service.NetworkIdentityProto; import android.telephony.Annotation.NetworkType; import android.util.proto.ProtoOutputStream; @@ -228,11 +227,11 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { final int oemManaged = getOemBitfield(snapshot.getNetworkCapabilities()); if (legacyType == TYPE_WIFI) { - networkId = snapshot.getNetworkCapabilities().getSsid(); - if (networkId == null) { - final WifiManager wifi = context.getSystemService(WifiManager.class); - final WifiInfo info = wifi.getConnectionInfo(); - networkId = info != null ? info.getSSID() : null; + final TransportInfo transportInfo = snapshot.getNetworkCapabilities() + .getTransportInfo(); + if (transportInfo instanceof WifiInfo) { + final WifiInfo info = (WifiInfo) transportInfo; + networkId = info != null ? info.getCurrentNetworkKey() : null; } } diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java index 9fa777d27c87..659ad06039b8 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java @@ -35,7 +35,6 @@ import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkStats.ROAMING_ALL; import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_YES; -import static android.net.wifi.WifiInfo.sanitizeSsid; import android.annotation.IntDef; import android.annotation.NonNull; @@ -57,6 +56,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -213,11 +213,14 @@ public final class NetworkTemplate implements Parcelable { public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId, @NetworkType int ratType, int metered) { if (TextUtils.isEmpty(subscriberId)) { - return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null, null, - metered, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL, + return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null /* subscriberId */, + null /* matchSubscriberIds */, + new String[0] /* matchWifiNetworkKeys */, metered, ROAMING_ALL, + DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL, NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT); } - return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[]{subscriberId}, null, + return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[] { subscriberId }, + new String[0] /* matchWifiNetworkKeys */, metered, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL, NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT); } @@ -235,7 +238,7 @@ public final class NetworkTemplate implements Parcelable { /** * Template to match all metered {@link ConnectivityManager#TYPE_WIFI} networks, - * regardless of SSID. + * regardless of key of the wifi network. * * @hide */ @@ -255,33 +258,40 @@ public final class NetworkTemplate implements Parcelable { /** * Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the - * given SSID. + * given key of the wifi network. * + * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getCurrentNetworkKey()} + * to know details about the key. * @hide */ - public static NetworkTemplate buildTemplateWifi(@NonNull String networkId) { - Objects.requireNonNull(networkId); + public static NetworkTemplate buildTemplateWifi(@NonNull String wifiNetworkKey) { + Objects.requireNonNull(wifiNetworkKey); return new NetworkTemplate(MATCH_WIFI, null /* subscriberId */, new String[] { null } /* matchSubscriberIds */, - networkId, METERED_ALL, ROAMING_ALL, + new String[] { wifiNetworkKey }, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL, NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL); } /** - * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks with the given SSID, - * and IMSI. + * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks with the given + * key of the wifi network and IMSI. * - * Call with {@link #WIFI_NETWORK_KEY_ALL} for {@code networkId} to get result regardless - * of SSID. + * Call with {@link #WIFI_NETWORK_KEY_ALL} for {@code wifiNetworkKey} to get result regardless + * of key of the wifi network. + * + * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getCurrentNetworkKey()} + * to know details about the key. + * @param subscriberId the IMSI associated to this wifi network. * * @hide */ - public static NetworkTemplate buildTemplateWifi(@Nullable String networkId, + public static NetworkTemplate buildTemplateWifi(@Nullable String wifiNetworkKey, @Nullable String subscriberId) { return new NetworkTemplate(MATCH_WIFI, subscriberId, new String[] { subscriberId }, - networkId, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL, + wifiNetworkKey != null + ? new String[] { wifiNetworkKey } : new String[0], + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL, NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT); } @@ -324,7 +334,9 @@ public final class NetworkTemplate implements Parcelable { public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) { Objects.requireNonNull(subscriberId); return new NetworkTemplate(MATCH_CARRIER, subscriberId, - new String[] { subscriberId }, null /* networkId */, METERED_YES, ROAMING_ALL, + new String[] { subscriberId }, + new String[0] /* matchWifiNetworkKeys */, + METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL, NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT); } @@ -342,8 +354,8 @@ public final class NetworkTemplate implements Parcelable { */ private final String[] mMatchSubscriberIds; - // TODO: Change variable name to match the Api surface. - private final String mNetworkId; + @NonNull + private final String[] mMatchWifiNetworkKeys; // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*. private final int mMetered; @@ -377,18 +389,19 @@ public final class NetworkTemplate implements Parcelable { /** @hide */ // TODO: Deprecate this constructor, mark it @UnsupportedAppUsage(maxTargetSdk = S) @UnsupportedAppUsage - public NetworkTemplate(int matchRule, String subscriberId, String networkId) { - this(matchRule, subscriberId, new String[] { subscriberId }, networkId); + public NetworkTemplate(int matchRule, String subscriberId, String wifiNetworkKey) { + this(matchRule, subscriberId, new String[] { subscriberId }, wifiNetworkKey); } /** @hide */ public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds, - String networkId) { + String wifiNetworkKey) { // Older versions used to only match MATCH_MOBILE and MATCH_MOBILE_WILDCARD templates // to metered networks. It is now possible to match mobile with any meteredness, but // in order to preserve backward compatibility of @UnsupportedAppUsage methods, this //constructor passes METERED_YES for these types. - this(matchRule, subscriberId, matchSubscriberIds, networkId, + this(matchRule, subscriberId, matchSubscriberIds, + wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0], (matchRule == MATCH_MOBILE || matchRule == MATCH_MOBILE_WILDCARD) ? METERED_YES : METERED_ALL , ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL, NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT); @@ -397,23 +410,25 @@ public final class NetworkTemplate implements Parcelable { /** @hide */ // TODO: Remove it after updating all of the caller. public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds, - String networkId, int metered, int roaming, int defaultNetwork, int subType, + String wifiNetworkKey, int metered, int roaming, int defaultNetwork, int subType, int oemManaged) { - this(matchRule, subscriberId, matchSubscriberIds, networkId, metered, roaming, - defaultNetwork, subType, oemManaged, + this(matchRule, subscriberId, matchSubscriberIds, + wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0], + metered, roaming, defaultNetwork, subType, oemManaged, NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT); } /** @hide */ public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds, - String networkId, int metered, int roaming, int defaultNetwork, int subType, - int oemManaged, int subscriberIdMatchRule) { + String[] matchWifiNetworkKeys, int metered, int roaming, + int defaultNetwork, int subType, int oemManaged, int subscriberIdMatchRule) { + Objects.requireNonNull(matchWifiNetworkKeys); mMatchRule = matchRule; mSubscriberId = subscriberId; // TODO: Check whether mMatchSubscriberIds = null or mMatchSubscriberIds = {null} when // mSubscriberId is null mMatchSubscriberIds = matchSubscriberIds; - mNetworkId = networkId; + mMatchWifiNetworkKeys = matchWifiNetworkKeys; mMetered = metered; mRoaming = roaming; mDefaultNetwork = defaultNetwork; @@ -431,7 +446,7 @@ public final class NetworkTemplate implements Parcelable { mMatchRule = in.readInt(); mSubscriberId = in.readString(); mMatchSubscriberIds = in.createStringArray(); - mNetworkId = in.readString(); + mMatchWifiNetworkKeys = in.createStringArray(); mMetered = in.readInt(); mRoaming = in.readInt(); mDefaultNetwork = in.readInt(); @@ -445,7 +460,7 @@ public final class NetworkTemplate implements Parcelable { dest.writeInt(mMatchRule); dest.writeString(mSubscriberId); dest.writeStringArray(mMatchSubscriberIds); - dest.writeString(mNetworkId); + dest.writeStringArray(mMatchWifiNetworkKeys); dest.writeInt(mMetered); dest.writeInt(mRoaming); dest.writeInt(mDefaultNetwork); @@ -471,9 +486,7 @@ public final class NetworkTemplate implements Parcelable { builder.append(", matchSubscriberIds=").append( Arrays.toString(NetworkIdentityUtils.scrubSubscriberIds(mMatchSubscriberIds))); } - if (mNetworkId != null) { - builder.append(", networkId=").append(mNetworkId); - } + builder.append(", matchWifiNetworkKeys=").append(Arrays.toString(mMatchWifiNetworkKeys)); if (mMetered != METERED_ALL) { builder.append(", metered=").append(NetworkStats.meteredToString(mMetered)); } @@ -497,8 +510,8 @@ public final class NetworkTemplate implements Parcelable { @Override public int hashCode() { - return Objects.hash(mMatchRule, mSubscriberId, mNetworkId, mMetered, mRoaming, - mDefaultNetwork, mSubType, mOemManaged, mSubscriberIdMatchRule); + return Objects.hash(mMatchRule, mSubscriberId, Arrays.hashCode(mMatchWifiNetworkKeys), + mMetered, mRoaming, mDefaultNetwork, mSubType, mOemManaged, mSubscriberIdMatchRule); } @Override @@ -507,13 +520,13 @@ public final class NetworkTemplate implements Parcelable { final NetworkTemplate other = (NetworkTemplate) obj; return mMatchRule == other.mMatchRule && Objects.equals(mSubscriberId, other.mSubscriberId) - && Objects.equals(mNetworkId, other.mNetworkId) && mMetered == other.mMetered && mRoaming == other.mRoaming && mDefaultNetwork == other.mDefaultNetwork && mSubType == other.mSubType && mOemManaged == other.mOemManaged - && mSubscriberIdMatchRule == other.mSubscriberIdMatchRule; + && mSubscriberIdMatchRule == other.mSubscriberIdMatchRule + && Arrays.equals(mMatchWifiNetworkKeys, other.mMatchWifiNetworkKeys); } return false; } @@ -579,14 +592,22 @@ public final class NetworkTemplate implements Parcelable { */ @Nullable public String getWifiNetworkKey() { - return mNetworkId; + return CollectionUtils.isEmpty(mMatchWifiNetworkKeys) ? null : mMatchWifiNetworkKeys[0]; + } + + /** + * Get set of Wifi Network Keys of the template. + */ + @Nullable + public Set<String> getWifiNetworkKeys() { + return new ArraySet<>(Arrays.asList(mMatchWifiNetworkKeys)); } /** @hide */ // TODO: Remove this and replace all callers with {@link #getWifiNetworkKey()}. @Nullable public String getNetworkId() { - return mNetworkId; + return getWifiNetworkKey(); } /** @@ -707,16 +728,21 @@ public final class NetworkTemplate implements Parcelable { } /** - * Check if network with matching SSID. Returns true when the SSID matches, or when - * {@code mNetworkId} is {@code WIFI_NETWORK_KEY_ALL}. + * Check if network matches key of the wifi network. + * Returns true when the key matches, or when {@code mMatchWifiNetworkKeys} is + * empty. + * + * @param wifiNetworkKey key of the wifi network. see {@link WifiInfo#getCurrentNetworkKey()} + * to know details about the key. */ - private boolean matchesWifiNetworkId(@Nullable String networkId) { - return Objects.equals(mNetworkId, WIFI_NETWORK_KEY_ALL) - || Objects.equals(sanitizeSsid(mNetworkId), sanitizeSsid(networkId)); + private boolean matchesWifiNetworkKey(@NonNull String wifiNetworkKey) { + Objects.requireNonNull(wifiNetworkKey); + return CollectionUtils.isEmpty(mMatchWifiNetworkKeys) + || CollectionUtils.contains(mMatchWifiNetworkKeys, wifiNetworkKey); } /** - * Check if mobile network with matching IMSI. + * Check if mobile network matches IMSI. */ private boolean matchesMobile(NetworkIdentity ident) { if (ident.mType == TYPE_WIMAX) { @@ -814,7 +840,7 @@ public final class NetworkTemplate implements Parcelable { switch (ident.mType) { case TYPE_WIFI: return matchesSubscriberId(ident.mSubscriberId) - && matchesWifiNetworkId(ident.mNetworkId); + && matchesWifiNetworkKey(ident.mNetworkId); default: return false; } @@ -956,8 +982,10 @@ public final class NetworkTemplate implements Parcelable { if (CollectionUtils.contains(merged, template.mSubscriberId)) { // Requested template subscriber is part of the merge group; return // a template that matches all merged subscribers. + final String[] matchWifiNetworkKeys = template.mMatchWifiNetworkKeys; return new NetworkTemplate(template.mMatchRule, merged[0], merged, - template.mNetworkId); + CollectionUtils.isEmpty(matchWifiNetworkKeys) + ? null : matchWifiNetworkKeys[0]); } } @@ -984,9 +1012,10 @@ public final class NetworkTemplate implements Parcelable { private final int mMatchRule; // Use a SortedSet to provide a deterministic order when fetching the first one. @NonNull - private final SortedSet<String> mMatchSubscriberIds = new TreeSet<>(); - @Nullable - private String mWifiNetworkKey; + private final SortedSet<String> mMatchSubscriberIds = + new TreeSet<>(Comparator.nullsFirst(Comparator.naturalOrder())); + @NonNull + private final SortedSet<String> mMatchWifiNetworkKeys = new TreeSet<>(); // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*. private int mMetered; @@ -1006,7 +1035,6 @@ public final class NetworkTemplate implements Parcelable { assertRequestableMatchRule(matchRule); // Initialize members with default values. mMatchRule = matchRule; - mWifiNetworkKey = WIFI_NETWORK_KEY_ALL; mMetered = METERED_ALL; mRoaming = ROAMING_ALL; mDefaultNetwork = DEFAULT_NETWORK_ALL; @@ -1030,15 +1058,28 @@ public final class NetworkTemplate implements Parcelable { } /** - * Set the Wifi Network Key. + * Set the Wifi Network Keys. Calling this function with an empty set represents + * the intention of matching any Wifi Network Key. * - * @param wifiNetworkKey the Wifi Network Key, see {@link WifiInfo#getCurrentNetworkKey()}. - * Or null to match all networks. + * @param wifiNetworkKeys the list of Wifi Network Key, + * see {@link WifiInfo#getCurrentNetworkKey()}. + * Or an empty list to match all networks. + * Note that {@code getCurrentNetworkKey()} might get null key + * when wifi disconnects. However, the caller should never invoke + * this function with a null Wifi Network Key since such statistics + * never exists. * @return this builder. */ @NonNull - public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) { - mWifiNetworkKey = wifiNetworkKey; + public Builder setWifiNetworkKeys(@NonNull Set<String> wifiNetworkKeys) { + Objects.requireNonNull(wifiNetworkKeys); + for (String key : wifiNetworkKeys) { + if (key == null) { + throw new IllegalArgumentException("Null is not a valid key"); + } + } + mMatchWifiNetworkKeys.clear(); + mMatchWifiNetworkKeys.addAll(wifiNetworkKeys); return this; } @@ -1122,9 +1163,17 @@ public final class NetworkTemplate implements Parcelable { } private void assertRequestableParameters() { + validateWifiNetworkKeys(); // TODO: Check all the input are legitimate. } + private void validateWifiNetworkKeys() { + if (mMatchRule != MATCH_WIFI && !mMatchWifiNetworkKeys.isEmpty()) { + throw new IllegalArgumentException("Trying to build non wifi match rule: " + + mMatchRule + " with wifi network keys"); + } + } + /** * For backward compatibility, deduce match rule to a wildcard match rule * if the Subscriber Ids are empty. @@ -1133,7 +1182,7 @@ public final class NetworkTemplate implements Parcelable { if (mMatchRule == MATCH_MOBILE && mMatchSubscriberIds.isEmpty()) { return MATCH_MOBILE_WILDCARD; } else if (mMatchRule == MATCH_WIFI && mMatchSubscriberIds.isEmpty() - && mWifiNetworkKey == WIFI_NETWORK_KEY_ALL) { + && mMatchWifiNetworkKeys.isEmpty()) { return MATCH_WIFI_WILDCARD; } return mMatchRule; @@ -1153,8 +1202,8 @@ public final class NetworkTemplate implements Parcelable { return new NetworkTemplate(getWildcardDeducedMatchRule(), mMatchSubscriberIds.isEmpty() ? null : mMatchSubscriberIds.iterator().next(), mMatchSubscriberIds.toArray(new String[0]), - mWifiNetworkKey, mMetered, mRoaming, mDefaultNetwork, mRatType, mOemManaged, - subscriberIdMatchRule); + mMatchWifiNetworkKeys.toArray(new String[0]), mMetered, mRoaming, + mDefaultNetwork, mRatType, mOemManaged, subscriberIdMatchRule); } } } diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java index 4fd62c1ad585..a3de9e4ba797 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java @@ -655,8 +655,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public INetworkStatsSession openSession() { - // NOTE: if callers want to get non-augmented data, they should go - // through the public API return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null); } @@ -876,8 +874,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) { assertSystemReady(); - // NOTE: if callers want to get non-augmented data, they should go - // through the public API return internalGetSummaryForNetwork(template, NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end, NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes(); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java index 36d9cf83120a..cc56a212aea1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java @@ -68,7 +68,7 @@ public class CsipDeviceManager { } for (Map.Entry<Integer, ParcelUuid> entry: groupIdMap.entrySet()) { - if (entry.getValue().equals(BluetoothUuid.BASE_UUID)) { + if (entry.getValue().equals(BluetoothUuid.CAP)) { return entry.getKey(); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java index 334792048105..5e2f31010900 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java @@ -338,7 +338,7 @@ public class LocalBluetoothProfileManager { .getGroupUuidMapByDevice(cachedDevice.getDevice()); if (groupIdMap != null) { for (Map.Entry<Integer, ParcelUuid> entry: groupIdMap.entrySet()) { - if (entry.getValue().equals(BluetoothUuid.BASE_UUID)) { + if (entry.getValue().equals(BluetoothUuid.CAP)) { cachedDevice.setGroupId(entry.getKey()); break; } diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java index 18c38c5a6494..011ca0b38e5d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java @@ -32,7 +32,6 @@ import android.net.INetworkStatsSession; import android.net.NetworkPolicy; import android.net.NetworkPolicyManager; import android.net.NetworkTemplate; -import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -172,7 +171,7 @@ public class DataUsageController { return bucket.getRxBytes() + bucket.getTxBytes(); } Log.w(TAG, "Failed to get data usage, no entry data"); - } catch (RemoteException e) { + } catch (RuntimeException e) { Log.w(TAG, "Failed to get data usage, remote call failed"); } return -1L; diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java index 787dc55e60f4..42e710080983 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java @@ -18,7 +18,6 @@ package com.android.settingslib.net; import android.app.usage.NetworkStats; import android.content.Context; -import android.os.RemoteException; import android.util.Log; import java.util.ArrayList; @@ -54,7 +53,7 @@ public class NetworkCycleChartDataLoader .setTotalUsage(total); mData.add(builder.build()); } - } catch (RemoteException e) { + } catch (RuntimeException e) { Log.e(TAG, "Exception querying network detail.", e); } } @@ -85,7 +84,7 @@ public class NetworkCycleChartDataLoader if (bucket != null) { usage = bucket.getRxBytes() + bucket.getTxBytes(); } - } catch (RemoteException e) { + } catch (RuntimeException e) { Log.e(TAG, "Exception querying network detail.", e); } data.add(new NetworkCycleData.Builder() diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java index ed093629686c..54d5c3d63a5d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java @@ -20,7 +20,6 @@ import android.app.usage.NetworkStats; import android.app.usage.NetworkStatsManager; import android.content.Context; import android.net.NetworkTemplate; -import android.os.RemoteException; import android.util.Log; import androidx.loader.content.AsyncTaskLoader; @@ -55,7 +54,7 @@ public class NetworkStatsSummaryLoader extends AsyncTaskLoader<NetworkStats> { public NetworkStats loadInBackground() { try { return mNetworkStatsManager.querySummary(mNetworkTemplate, mStart, mEnd); - } catch (RemoteException e) { + } catch (RuntimeException e) { Log.e(TAG, "Exception querying network detail.", e); return null; } diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 8860a8164109..450e9881bef2 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -1850,6 +1850,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mEnable = true; + if (isBle == 0) { + persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); + } + // Use service interface to get the exact state try { mBluetoothLock.readLock().lock(); @@ -1863,7 +1867,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } else { Slog.w(TAG, "BT Enable in BLE_ON State, going to ON"); mBluetooth.onLeServiceUp(mContext.getAttributionSource()); - persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); } break; case BluetoothAdapter.STATE_BLE_TURNING_ON: diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index c315b5c43dea..2ca057d02278 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -2025,7 +2025,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (final NetworkStateSnapshot snapshot : snapshots) { mNetIdToSubId.put(snapshot.getNetwork().getNetId(), parseSubId(snapshot)); - // Policies matched by NPMS only match by subscriber ID or by ssid. Thus subtype + // Policies matched by NPMS only match by subscriber ID or by network ID. Thus subtype // in the object created here is never used and its value doesn't matter, so use // NETWORK_TYPE_UNKNOWN. final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot, @@ -2455,7 +2455,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } final NetworkTemplate.Builder builder = new NetworkTemplate.Builder(templateType) - .setWifiNetworkKey(networkId) .setMeteredness(templateMeteredness); if (subscriberIdMatchRule == NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT) { @@ -2463,6 +2462,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { ids.add(subscriberId); builder.setSubscriberIds(ids); } + if (networkId != null) { + builder.setWifiNetworkKeys(Set.of(networkId)); + } final NetworkTemplate template = builder.build(); if (NetworkPolicy.isTemplatePersistable(template)) { mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule, @@ -2613,35 +2615,39 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * into {@link WifiConfiguration}. */ private void upgradeWifiMeteredOverride() { - final ArrayMap<String, Boolean> wifiNetworkIds = new ArrayMap<>(); + final ArrayMap<String, Boolean> wifiNetworkKeys = new ArrayMap<>(); synchronized (mNetworkPoliciesSecondLock) { for (int i = 0; i < mNetworkPolicy.size();) { final NetworkPolicy policy = mNetworkPolicy.valueAt(i); if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI && !policy.inferred) { mNetworkPolicy.removeAt(i); - wifiNetworkIds.put(policy.template.getNetworkId(), policy.metered); + final Set<String> keys = policy.template.getWifiNetworkKeys(); + wifiNetworkKeys.put(keys.isEmpty() ? null : keys.iterator().next(), + policy.metered); } else { i++; } } } - if (wifiNetworkIds.isEmpty()) { + if (wifiNetworkKeys.isEmpty()) { return; } final WifiManager wm = mContext.getSystemService(WifiManager.class); final List<WifiConfiguration> configs = wm.getConfiguredNetworks(); for (int i = 0; i < configs.size(); ++i) { final WifiConfiguration config = configs.get(i); - final String networkId = resolveNetworkId(config); - final Boolean metered = wifiNetworkIds.get(networkId); - if (metered != null) { - Slog.d(TAG, "Found network " + networkId + "; upgrading metered hint"); - config.meteredOverride = metered - ? WifiConfiguration.METERED_OVERRIDE_METERED - : WifiConfiguration.METERED_OVERRIDE_NOT_METERED; - wm.updateNetwork(config); + for (String key : config.getAllPersistableNetworkKeys()) { + final Boolean metered = wifiNetworkKeys.get(key); + if (metered != null) { + Slog.d(TAG, "Found network " + key + "; upgrading metered hint"); + config.meteredOverride = metered + ? WifiConfiguration.METERED_OVERRIDE_METERED + : WifiConfiguration.METERED_OVERRIDE_NOT_METERED; + wm.updateNetwork(config); + break; + } } } @@ -2683,9 +2689,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { ? NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL : NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT; writeIntAttribute(out, ATTR_SUBSCRIBER_ID_MATCH_RULE, subscriberIdMatchRule); - final String networkId = template.getNetworkId(); - if (networkId != null) { - out.attribute(null, ATTR_NETWORK_ID, networkId); + if (!template.getWifiNetworkKeys().isEmpty()) { + out.attribute(null, ATTR_NETWORK_ID, + template.getWifiNetworkKeys().iterator().next()); } writeIntAttribute(out, ATTR_TEMPLATE_METERED, template.getMeteredness()); diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index eda05bf3f214..b811e28a3f71 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -129,6 +129,7 @@ import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.TelephonyNetworkSpecifier; +import android.net.wifi.WifiInfo; import android.os.Binder; import android.os.Handler; import android.os.INetworkManagementService; @@ -226,13 +227,13 @@ public class NetworkPolicyManagerServiceTest { private static final long TEST_START = 1194220800000L; private static final String TEST_IFACE = "test0"; - private static final String TEST_SSID = "AndroidAP"; + private static final String TEST_WIFI_NETWORK_KEY = "TestWifiNetworkKey"; private static final String TEST_IMSI = "310210"; 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_SSID); + private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_WIFI_NETWORK_KEY); private static NetworkTemplate sTemplateCarrierMetered = buildTemplateCarrierMetered(TEST_IMSI); @@ -2096,10 +2097,13 @@ public class NetworkPolicyManagerServiceTest { } private static NetworkStateSnapshot buildWifi() { + WifiInfo mockWifiInfo = mock(WifiInfo.class); + when(mockWifiInfo.makeCopy(anyLong())).thenReturn(mockWifiInfo); + when(mockWifiInfo.getCurrentNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY); final LinkProperties prop = new LinkProperties(); prop.setInterfaceName(TEST_IFACE); final NetworkCapabilities networkCapabilities = new NetworkCapabilities.Builder() - .addTransportType(TRANSPORT_WIFI).setSsid(TEST_SSID).build(); + .addTransportType(TRANSPORT_WIFI).setTransportInfo(mockWifiInfo).build(); return new NetworkStateSnapshot(TEST_NETWORK, networkCapabilities, prop, null /*subscriberId*/, TYPE_WIFI); } diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index 1ef04be8f242..d6dce25d931f 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -328,8 +328,6 @@ public class ApnSetting implements Parcelable { @SystemApi public static final String TYPE_XCAP_STRING = "xcap"; - - /** * APN type for Virtual SIM service. * @@ -506,27 +504,21 @@ public class ApnSetting implements Parcelable { private final int mRoamingProtocol; private final int mMtuV4; private final int mMtuV6; - private final boolean mCarrierEnabled; - - private final int mNetworkTypeBitmask; - + private final @TelephonyManager.NetworkTypeBitMask int mNetworkTypeBitmask; + private final @TelephonyManager.NetworkTypeBitMask long mLingeringNetworkTypeBitmask; private final int mProfileId; - private final boolean mPersistent; private final int mMaxConns; private final int mWaitTime; private final int mMaxConnsTime; - private final int mMvnoType; private final String mMvnoMatchData; - private final int mApnSetId; - private boolean mPermanentFailed = false; private final int mCarrierId; - private final int mSkip464Xlat; + private final boolean mAlwaysOn; /** * Returns the MTU size of the IPv4 mobile interface to which the APN connected. Note this value @@ -843,20 +835,37 @@ public class ApnSetting implements Parcelable { } /** - * Returns a bitmask describing the Radio Technologies(Network Types) which this APN may use. + * Returns a bitmask describing the Radio Technologies (Network Types) which this APN may use. * * NetworkType bitmask is calculated from NETWORK_TYPE defined in {@link TelephonyManager}. * * Examples of Network Types include {@link TelephonyManager#NETWORK_TYPE_UNKNOWN}, * {@link TelephonyManager#NETWORK_TYPE_GPRS}, {@link TelephonyManager#NETWORK_TYPE_EDGE}. * - * @return a bitmask describing the Radio Technologies(Network Types) + * @return a bitmask describing the Radio Technologies (Network Types) or 0 if it is undefined. */ public int getNetworkTypeBitmask() { return mNetworkTypeBitmask; } /** + * Returns a bitmask describing the Radio Technologies (Network Types) that should not be torn + * down if it exists or brought up if it already exists for this APN. + * + * NetworkType bitmask is calculated from NETWORK_TYPE defined in {@link TelephonyManager}. + * + * Examples of Network Types include {@link TelephonyManager#NETWORK_TYPE_UNKNOWN}, + * {@link TelephonyManager#NETWORK_TYPE_GPRS}, {@link TelephonyManager#NETWORK_TYPE_EDGE}. + * + * @return a bitmask describing the Radio Technologies (Network Types) that should linger + * or 0 if it is undefined. + * @hide + */ + public @TelephonyManager.NetworkTypeBitMask long getLingeringNetworkTypeBitmask() { + return mLingeringNetworkTypeBitmask; + } + + /** * Returns the MVNO match type for this APN. * * @see Builder#setMvnoType(int) @@ -888,6 +897,18 @@ public class ApnSetting implements Parcelable { return mSkip464Xlat; } + /** + * Returns whether User Plane resources have to be activated during every transition from + * CM-IDLE mode to CM-CONNECTED state for this APN + * See 3GPP TS 23.501 section 5.6.13 + * + * @return True if the PDU session for this APN should always be on and false otherwise + * @hide + */ + public boolean isAlwaysOn() { + return mAlwaysOn; + } + private ApnSetting(Builder builder) { this.mEntryName = builder.mEntryName; this.mApnName = builder.mApnName; @@ -912,6 +933,7 @@ public class ApnSetting implements Parcelable { this.mMtuV6 = builder.mMtuV6; this.mCarrierEnabled = builder.mCarrierEnabled; this.mNetworkTypeBitmask = builder.mNetworkTypeBitmask; + this.mLingeringNetworkTypeBitmask = builder.mLingeringNetworkTypeBitmask; this.mProfileId = builder.mProfileId; this.mPersistent = builder.mModemCognitive; this.mMaxConns = builder.mMaxConns; @@ -922,6 +944,7 @@ public class ApnSetting implements Parcelable { this.mApnSetId = builder.mApnSetId; this.mCarrierId = builder.mCarrierId; this.mSkip464Xlat = builder.mSkip464Xlat; + this.mAlwaysOn = builder.mAlwaysOn; } /** @@ -938,6 +961,10 @@ public class ApnSetting implements Parcelable { networkTypeBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask(bearerBitmask); } + int mtuV4 = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU_V4)); + if (mtuV4 == -1) { + mtuV4 = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)); + } return new Builder() .setId(cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID))) @@ -972,6 +999,8 @@ public class ApnSetting implements Parcelable { .setCarrierEnabled(cursor.getInt(cursor.getColumnIndexOrThrow( Telephony.Carriers.CARRIER_ENABLED)) == 1) .setNetworkTypeBitmask(networkTypeBitmask) + .setLingeringNetworkTypeBitmask(cursor.getInt(cursor.getColumnIndexOrThrow( + Carriers.LINGERING_NETWORK_TYPE_BITMASK))) .setProfileId(cursor.getInt( cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID))) .setModemCognitive(cursor.getInt(cursor.getColumnIndexOrThrow( @@ -982,8 +1011,8 @@ public class ApnSetting implements Parcelable { cursor.getColumnIndexOrThrow(Telephony.Carriers.WAIT_TIME_RETRY))) .setMaxConnsTime(cursor.getInt(cursor.getColumnIndexOrThrow( Telephony.Carriers.TIME_LIMIT_FOR_MAX_CONNECTIONS))) - .setMtuV4(cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU))) - .setMtuV6(UNSET_MTU) // TODO: Add corresponding support in telephony provider + .setMtuV4(mtuV4) + .setMtuV6(cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU_V6))) .setMvnoType(getMvnoTypeIntFromString( cursor.getString(cursor.getColumnIndexOrThrow( Telephony.Carriers.MVNO_TYPE)))) @@ -994,6 +1023,7 @@ public class ApnSetting implements Parcelable { .setCarrierId(cursor.getInt( cursor.getColumnIndexOrThrow(Telephony.Carriers.CARRIER_ID))) .setSkip464Xlat(cursor.getInt(cursor.getColumnIndexOrThrow(Carriers.SKIP_464XLAT))) + .setAlwaysOn(cursor.getInt(cursor.getColumnIndexOrThrow(Carriers.ALWAYS_ON)) == 1) .buildWithoutCheck(); } @@ -1019,6 +1049,7 @@ public class ApnSetting implements Parcelable { .setRoamingProtocol(apn.mRoamingProtocol) .setCarrierEnabled(apn.mCarrierEnabled) .setNetworkTypeBitmask(apn.mNetworkTypeBitmask) + .setLingeringNetworkTypeBitmask(apn.mLingeringNetworkTypeBitmask) .setProfileId(apn.mProfileId) .setModemCognitive(apn.mPersistent) .setMaxConns(apn.mMaxConns) @@ -1031,6 +1062,7 @@ public class ApnSetting implements Parcelable { .setApnSetId(apn.mApnSetId) .setCarrierId(apn.mCarrierId) .setSkip464Xlat(apn.mSkip464Xlat) + .setAlwaysOn(apn.mAlwaysOn) .buildWithoutCheck(); } @@ -1069,9 +1101,11 @@ public class ApnSetting implements Parcelable { sb.append(", ").append(mMvnoMatchData); sb.append(", ").append(mPermanentFailed); sb.append(", ").append(mNetworkTypeBitmask); + sb.append(", ").append(mLingeringNetworkTypeBitmask); sb.append(", ").append(mApnSetId); sb.append(", ").append(mCarrierId); sb.append(", ").append(mSkip464Xlat); + sb.append(", ").append(mAlwaysOn); return sb.toString(); } @@ -1136,8 +1170,9 @@ public class ApnSetting implements Parcelable { return Objects.hash(mApnName, mProxyAddress, mProxyPort, mMmsc, mMmsProxyAddress, mMmsProxyPort, mUser, mPassword, mAuthType, mApnTypeBitmask, mId, mOperatorNumeric, mProtocol, mRoamingProtocol, mMtuV4, mMtuV6, mCarrierEnabled, mNetworkTypeBitmask, - mProfileId, mPersistent, mMaxConns, mWaitTime, mMaxConnsTime, mMvnoType, - mMvnoMatchData, mApnSetId, mCarrierId, mSkip464Xlat); + mLingeringNetworkTypeBitmask, mProfileId, mPersistent, mMaxConns, mWaitTime, + mMaxConnsTime, mMvnoType, mMvnoMatchData, mApnSetId, mCarrierId, mSkip464Xlat, + mAlwaysOn); } @Override @@ -1174,9 +1209,11 @@ public class ApnSetting implements Parcelable { && Objects.equals(mMvnoType, other.mMvnoType) && Objects.equals(mMvnoMatchData, other.mMvnoMatchData) && Objects.equals(mNetworkTypeBitmask, other.mNetworkTypeBitmask) + && Objects.equals(mLingeringNetworkTypeBitmask, other.mLingeringNetworkTypeBitmask) && Objects.equals(mApnSetId, other.mApnSetId) && Objects.equals(mCarrierId, other.mCarrierId) - && Objects.equals(mSkip464Xlat, other.mSkip464Xlat); + && Objects.equals(mSkip464Xlat, other.mSkip464Xlat) + && Objects.equals(mAlwaysOn, other.mAlwaysOn); } /** @@ -1210,6 +1247,7 @@ public class ApnSetting implements Parcelable { && Objects.equals(mPassword, other.mPassword) && Objects.equals(mAuthType, other.mAuthType) && Objects.equals(mApnTypeBitmask, other.mApnTypeBitmask) + && Objects.equals(mLingeringNetworkTypeBitmask, other.mLingeringNetworkTypeBitmask) && (isDataRoaming || Objects.equals(mProtocol, other.mProtocol)) && (!isDataRoaming || Objects.equals(mRoamingProtocol, other.mRoamingProtocol)) && Objects.equals(mCarrierEnabled, other.mCarrierEnabled) @@ -1224,7 +1262,8 @@ public class ApnSetting implements Parcelable { && Objects.equals(mMvnoMatchData, other.mMvnoMatchData) && Objects.equals(mApnSetId, other.mApnSetId) && Objects.equals(mCarrierId, other.mCarrierId) - && Objects.equals(mSkip464Xlat, other.mSkip464Xlat); + && Objects.equals(mSkip464Xlat, other.mSkip464Xlat) + && Objects.equals(mAlwaysOn, other.mAlwaysOn); } /** @@ -1304,9 +1343,13 @@ public class ApnSetting implements Parcelable { apnValue.put(Telephony.Carriers.CARRIER_ENABLED, mCarrierEnabled); apnValue.put(Telephony.Carriers.MVNO_TYPE, getMvnoTypeStringFromInt(mMvnoType)); apnValue.put(Telephony.Carriers.NETWORK_TYPE_BITMASK, mNetworkTypeBitmask); + apnValue.put(Telephony.Carriers.LINGERING_NETWORK_TYPE_BITMASK, + mLingeringNetworkTypeBitmask); + apnValue.put(Telephony.Carriers.MTU_V4, mMtuV4); + apnValue.put(Telephony.Carriers.MTU_V6, mMtuV6); apnValue.put(Telephony.Carriers.CARRIER_ID, mCarrierId); apnValue.put(Telephony.Carriers.SKIP_464XLAT, mSkip464Xlat); - + apnValue.put(Telephony.Carriers.ALWAYS_ON, mAlwaysOn); return apnValue; } @@ -1510,6 +1553,31 @@ public class ApnSetting implements Parcelable { return ServiceState.bitmaskHasTech(mNetworkTypeBitmask, networkType); } + /** + * Check if this APN setting can support the given lingering network + * + * @param networkType The lingering network type + * @return {@code true} if this APN setting can support the given lingering network. + * + * @hide + */ + public boolean canSupportLingeringNetworkType(@NetworkType int networkType) { + if (networkType == 0) { + return canSupportNetworkType(networkType); + } + // Do a special checking for GSM. In reality, GSM is a voice only network type and can never + // be used for data. We allow it here because in some DSDS corner cases, on the non-DDS + // sub, modem reports data rat unknown. In that case if voice is GSM and this APN supports + // GPRS or EDGE, this APN setting should be selected. + if (networkType == TelephonyManager.NETWORK_TYPE_GSM + && (mLingeringNetworkTypeBitmask & (TelephonyManager.NETWORK_TYPE_BITMASK_GPRS + | TelephonyManager.NETWORK_TYPE_BITMASK_EDGE)) != 0) { + return true; + } + + return ServiceState.bitmaskHasTech((int) mLingeringNetworkTypeBitmask, networkType); + } + // Implement Parcelable. @Override /** @hide */ @@ -1537,6 +1605,7 @@ public class ApnSetting implements Parcelable { dest.writeInt(mRoamingProtocol); dest.writeBoolean(mCarrierEnabled); dest.writeInt(mNetworkTypeBitmask); + dest.writeLong(mLingeringNetworkTypeBitmask); dest.writeInt(mProfileId); dest.writeBoolean(mPersistent); dest.writeInt(mMaxConns); @@ -1549,6 +1618,7 @@ public class ApnSetting implements Parcelable { dest.writeInt(mApnSetId); dest.writeInt(mCarrierId); dest.writeInt(mSkip464Xlat); + dest.writeBoolean(mAlwaysOn); } private static ApnSetting readFromParcel(Parcel in) { @@ -1570,6 +1640,7 @@ public class ApnSetting implements Parcelable { .setRoamingProtocol(in.readInt()) .setCarrierEnabled(in.readBoolean()) .setNetworkTypeBitmask(in.readInt()) + .setLingeringNetworkTypeBitmask(in.readLong()) .setProfileId(in.readInt()) .setModemCognitive(in.readBoolean()) .setMaxConns(in.readInt()) @@ -1582,6 +1653,7 @@ public class ApnSetting implements Parcelable { .setApnSetId(in.readInt()) .setCarrierId(in.readInt()) .setSkip464Xlat(in.readInt()) + .setAlwaysOn(in.readBoolean()) .buildWithoutCheck(); } @@ -1649,7 +1721,8 @@ public class ApnSetting implements Parcelable { private int mRoamingProtocol = UNSPECIFIED_INT; private int mMtuV4; private int mMtuV6; - private int mNetworkTypeBitmask; + private @TelephonyManager.NetworkTypeBitMask int mNetworkTypeBitmask; + private @TelephonyManager.NetworkTypeBitMask long mLingeringNetworkTypeBitmask; private boolean mCarrierEnabled; private int mProfileId; private boolean mModemCognitive; @@ -1661,6 +1734,7 @@ public class ApnSetting implements Parcelable { private int mApnSetId; private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; private int mSkip464Xlat = Carriers.SKIP_464XLAT_DEFAULT; + private boolean mAlwaysOn; /** * Default constructor for Builder. @@ -2012,6 +2086,19 @@ public class ApnSetting implements Parcelable { } /** + * Sets lingering Radio Technology (Network Type) for this APN. + * + * @param lingeringNetworkTypeBitmask the Radio Technology (Network Type) that should linger + * @hide + */ + @NonNull + public Builder setLingeringNetworkTypeBitmask(@TelephonyManager.NetworkTypeBitMask + long lingeringNetworkTypeBitmask) { + this.mLingeringNetworkTypeBitmask = lingeringNetworkTypeBitmask; + return this; + } + + /** * Sets the MVNO match type for this APN. * * @param mvnoType the MVNO match type to set for this APN @@ -2048,6 +2135,18 @@ public class ApnSetting implements Parcelable { } /** + * Sets whether the PDU session brought up by this APN should always be on. + * See 3GPP TS 23.501 section 5.6.13 + * + * @param alwaysOn the always on status to set for this APN + * @hide + */ + public Builder setAlwaysOn(boolean alwaysOn) { + this.mAlwaysOn = alwaysOn; + return this; + } + + /** * Builds {@link ApnSetting} from this builder. * * @return {@code null} if {@link #setApnName(String)} or {@link #setEntryName(String)} |