Merge "[TelephonyMainline] @hide @SystemApi and revisit them in S. - CarrierColumns"
diff --git a/api/current.txt b/api/current.txt
index ce04fae..f17eae1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -44680,6 +44680,38 @@
field public static final int PRIORITY_MED = 2; // 0x2
}
+ public final class BarringInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public android.telephony.BarringInfo.BarringServiceInfo getBarringServiceInfo(int);
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int BARRING_SERVICE_TYPE_CS_FALLBACK = 5; // 0x5
+ field public static final int BARRING_SERVICE_TYPE_CS_SERVICE = 0; // 0x0
+ field public static final int BARRING_SERVICE_TYPE_CS_VOICE = 2; // 0x2
+ field public static final int BARRING_SERVICE_TYPE_EMERGENCY = 8; // 0x8
+ field public static final int BARRING_SERVICE_TYPE_MMTEL_VIDEO = 7; // 0x7
+ field public static final int BARRING_SERVICE_TYPE_MMTEL_VOICE = 6; // 0x6
+ field public static final int BARRING_SERVICE_TYPE_MO_DATA = 4; // 0x4
+ field public static final int BARRING_SERVICE_TYPE_MO_SIGNALLING = 3; // 0x3
+ field public static final int BARRING_SERVICE_TYPE_PS_SERVICE = 1; // 0x1
+ field public static final int BARRING_SERVICE_TYPE_SMS = 9; // 0x9
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.BarringInfo> CREATOR;
+ }
+
+ public static final class BarringInfo.BarringServiceInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getBarringType();
+ method public int getConditionalBarringFactor();
+ method public int getConditionalBarringTimeSeconds();
+ method public boolean isBarred();
+ method public boolean isConditionallyBarred();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int BARRING_TYPE_CONDITIONAL = 1; // 0x1
+ field public static final int BARRING_TYPE_NONE = 0; // 0x0
+ field public static final int BARRING_TYPE_UNCONDITIONAL = 2; // 0x2
+ field public static final int BARRING_TYPE_UNKNOWN = -1; // 0xffffffff
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.BarringInfo.BarringServiceInfo> CREATOR;
+ }
+
public class CarrierConfigManager {
method @Nullable public android.os.PersistableBundle getConfig();
method @Nullable public android.os.PersistableBundle getConfigByComponentForSubId(@NonNull String, int);
@@ -45316,6 +45348,7 @@
method @Nullable public android.telephony.CellIdentity getCellIdentity();
method public int getDomain();
method public int getNrState();
+ method @Nullable public String getRegisteredPlmn();
method public int getTransportType();
method public boolean isRegistered();
method public boolean isRoaming();
@@ -45442,6 +45475,7 @@
ctor public PhoneStateListener();
ctor public PhoneStateListener(@NonNull java.util.concurrent.Executor);
method public void onActiveDataSubscriptionIdChanged(int);
+ method public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onCallDisconnectCauseChanged(int, int);
method public void onCallForwardingIndicatorChanged(boolean);
method public void onCallStateChanged(int, String);
@@ -45460,6 +45494,7 @@
method public void onSignalStrengthsChanged(android.telephony.SignalStrength);
method public void onUserMobileDataStateChanged(boolean);
field public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000
+ field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int LISTEN_BARRING_INFO = -2147483648; // 0x80000000
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000
field public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8
field public static final int LISTEN_CALL_STATE = 32; // 0x20
@@ -45482,6 +45517,7 @@
public final class PreciseDataConnectionState implements android.os.Parcelable {
method public int describeContents();
+ method @Nullable public android.telephony.data.ApnSetting getApnSetting();
method public int getLastCauseCode();
method @Nullable public android.net.LinkProperties getLinkProperties();
method public int getNetworkType();
diff --git a/api/system-current.txt b/api/system-current.txt
index 2b5d8cb..f03af6b 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1292,16 +1292,16 @@
package android.bluetooth {
public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void disableOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void enableOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void disableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void enableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothDevice getActiveDevice();
- method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@Nullable android.bluetooth.BluetoothDevice);
+ method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int getOptionalCodecsEnabled(@Nullable android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setCodecConfigPreference(@Nullable android.bluetooth.BluetoothDevice, @Nullable android.bluetooth.BluetoothCodecConfig);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int isOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int isOptionalCodecsSupported(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setCodecConfigPreference(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothCodecConfig);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setOptionalCodecsEnabled(@Nullable android.bluetooth.BluetoothDevice, int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int supportsOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice, int);
field public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0; // 0x0
field public static final int OPTIONAL_CODECS_PREF_DISABLED = 0; // 0x0
field public static final int OPTIONAL_CODECS_PREF_ENABLED = 1; // 0x1
@@ -1671,7 +1671,6 @@
field public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP";
field public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED";
field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED";
- field @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED";
field public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
field public static final String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS";
field public static final String EXTRA_CALLING_PACKAGE = "android.intent.extra.CALLING_PACKAGE";
@@ -8144,6 +8143,11 @@
field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0
}
+ public final class BarringInfo implements android.os.Parcelable {
+ ctor public BarringInfo();
+ method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy();
+ }
+
public final class CallAttributes implements android.os.Parcelable {
ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
method public int describeContents();
@@ -8819,6 +8823,7 @@
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index d46f368..c972571 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3098,6 +3098,15 @@
field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0
}
+ public final class BarringInfo implements android.os.Parcelable {
+ ctor public BarringInfo();
+ ctor public BarringInfo(@Nullable android.telephony.CellIdentity, @NonNull android.util.SparseArray<android.telephony.BarringInfo.BarringServiceInfo>);
+ }
+
+ public static final class BarringInfo.BarringServiceInfo implements android.os.Parcelable {
+ ctor public BarringInfo.BarringServiceInfo(int, boolean, int, int);
+ }
+
public final class CallQuality implements android.os.Parcelable {
ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean);
@@ -3184,6 +3193,7 @@
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index d8c653c6..b672a08 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -643,8 +643,9 @@
@SystemApi
@Nullable
@RequiresPermission(Manifest.permission.BLUETOOTH)
- public BluetoothCodecStatus getCodecStatus(@Nullable BluetoothDevice device) {
+ public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
+ verifyDeviceNotNull(device, "getCodecStatus");
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()) {
@@ -670,9 +671,14 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
- public void setCodecConfigPreference(@Nullable BluetoothDevice device,
- @Nullable BluetoothCodecConfig codecConfig) {
+ public void setCodecConfigPreference(@NonNull BluetoothDevice device,
+ @NonNull BluetoothCodecConfig codecConfig) {
if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
+ verifyDeviceNotNull(device, "setCodecConfigPreference");
+ if (codecConfig == null) {
+ Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
+ throw new IllegalArgumentException("codecConfig cannot be null");
+ }
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()) {
@@ -695,8 +701,9 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
- public void enableOptionalCodecs(@Nullable BluetoothDevice device) {
+ public void enableOptionalCodecs(@NonNull BluetoothDevice device) {
if (DBG) Log.d(TAG, "enableOptionalCodecs(" + device + ")");
+ verifyDeviceNotNull(device, "enableOptionalCodecs");
enableDisableOptionalCodecs(device, true);
}
@@ -709,8 +716,9 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
- public void disableOptionalCodecs(@Nullable BluetoothDevice device) {
+ public void disableOptionalCodecs(@NonNull BluetoothDevice device) {
if (DBG) Log.d(TAG, "disableOptionalCodecs(" + device + ")");
+ verifyDeviceNotNull(device, "disableOptionalCodecs");
enableDisableOptionalCodecs(device, false);
}
@@ -750,7 +758,8 @@
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
@OptionalCodecsSupportStatus
- public int supportsOptionalCodecs(@Nullable BluetoothDevice device) {
+ public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) {
+ verifyDeviceNotNull(device, "isOptionalCodecsSupported");
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
@@ -775,7 +784,8 @@
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
@OptionalCodecsPreferenceStatus
- public int getOptionalCodecsEnabled(@Nullable BluetoothDevice device) {
+ public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) {
+ verifyDeviceNotNull(device, "isOptionalCodecsEnabled");
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
@@ -800,8 +810,9 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
- public void setOptionalCodecsEnabled(@Nullable BluetoothDevice device,
+ public void setOptionalCodecsEnabled(@NonNull BluetoothDevice device,
@OptionalCodecsPreferenceStatus int value) {
+ verifyDeviceNotNull(device, "setOptionalCodecsEnabled");
try {
if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
@@ -854,6 +865,13 @@
return false;
}
+ private void verifyDeviceNotNull(BluetoothDevice device, String methodName) {
+ if (device == null) {
+ Log.e(TAG, methodName + ": device param is null");
+ throw new IllegalArgumentException("Device cannot be null");
+ }
+ }
+
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ba91014..467aa15 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3622,9 +3622,7 @@
* {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast.
* @hide
*/
- @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @SystemApi
+ @UnsupportedAppUsage
public static final String ACTION_USER_SWITCHED =
"android.intent.action.USER_SWITCHED";
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d8a97de..629de1d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -145,16 +145,6 @@
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
/**
- * A temporary hack until SUPL system can get off the legacy APIS.
- * They do too many network requests and the long list of apps listening
- * and waking due to the CONNECTIVITY_ACTION broadcast makes it expensive.
- * Use this broadcast intent instead for SUPL requests.
- * @hide
- */
- public static final String CONNECTIVITY_ACTION_SUPL =
- "android.net.conn.CONNECTIVITY_CHANGE_SUPL";
-
- /**
* The device has connected to a network that has presented a captive
* portal, which is blocking Internet connectivity. The user was presented
* with a notification that network sign in is required,
@@ -1517,84 +1507,6 @@
return null;
}
- /**
- * Guess what the network request was trying to say so that the resulting
- * network is accessible via the legacy (deprecated) API such as
- * requestRouteToHost.
- *
- * This means we should try to be fairly precise about transport and
- * capability but ignore things such as networkSpecifier.
- * If the request has more than one transport or capability it doesn't
- * match the old legacy requests (they selected only single transport/capability)
- * so this function cannot map the request to a single legacy type and
- * the resulting network will not be available to the legacy APIs.
- *
- * This code is only called from the requestNetwork API (L and above).
- *
- * Setting a legacy type causes CONNECTIVITY_ACTION broadcasts, which are expensive
- * because they wake up lots of apps - see http://b/23350688 . So we currently only
- * do this for SUPL requests, which are the only ones that we know need it. If
- * omitting these broadcasts causes unacceptable app breakage, then for backwards
- * compatibility we can send them:
- *
- * if (targetSdkVersion < Build.VERSION_CODES.M) && // legacy API unsupported >= M
- * targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP)) // requestNetwork not present < L
- *
- * TODO - This should be removed when the legacy APIs are removed.
- */
- private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
- if (netCap == null) {
- return TYPE_NONE;
- }
-
- if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- return TYPE_NONE;
- }
-
- // Do this only for SUPL, until GnssLocationProvider is fixed. http://b/25876485 .
- if (!netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
- // NOTE: if this causes app breakage, we should not just comment out this early return;
- // instead, we should make this early return conditional on the requesting app's target
- // SDK version, as described in the comment above.
- return TYPE_NONE;
- }
-
- String type = null;
- int result = TYPE_NONE;
-
- if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
- type = "enableCBS";
- result = TYPE_MOBILE_CBS;
- } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
- type = "enableIMS";
- result = TYPE_MOBILE_IMS;
- } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
- type = "enableFOTA";
- result = TYPE_MOBILE_FOTA;
- } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
- type = "enableDUN";
- result = TYPE_MOBILE_DUN;
- } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
- type = "enableSUPL";
- result = TYPE_MOBILE_SUPL;
- // back out this hack for mms as they no longer need this and it's causing
- // device slowdowns - b/23350688 (note, supl still needs this)
- //} else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
- // type = "enableMMS";
- // result = TYPE_MOBILE_MMS;
- } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- type = "enableHIPRI";
- result = TYPE_MOBILE_HIPRI;
- }
- if (type != null) {
- NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type);
- if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) {
- return result;
- }
- }
- return TYPE_NONE;
- }
-
private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
if (netCap == null) return TYPE_NONE;
if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
@@ -3894,9 +3806,8 @@
*/
public void requestNetwork(@NonNull NetworkRequest request,
@NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
- int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
CallbackHandler cbHandler = new CallbackHandler(handler);
- requestNetwork(request, networkCallback, 0, legacyType, cbHandler);
+ requestNetwork(request, networkCallback, 0, TYPE_NONE, cbHandler);
}
/**
@@ -3929,8 +3840,7 @@
public void requestNetwork(@NonNull NetworkRequest request,
@NonNull NetworkCallback networkCallback, int timeoutMs) {
checkTimeout(timeoutMs);
- int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
- requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler());
+ requestNetwork(request, networkCallback, timeoutMs, TYPE_NONE, getDefaultHandler());
}
/**
@@ -3955,9 +3865,8 @@
public void requestNetwork(@NonNull NetworkRequest request,
@NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) {
checkTimeout(timeoutMs);
- int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
CallbackHandler cbHandler = new CallbackHandler(handler);
- requestNetwork(request, networkCallback, timeoutMs, legacyType, cbHandler);
+ requestNetwork(request, networkCallback, timeoutMs, TYPE_NONE, cbHandler);
}
/**
diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java
index e9ea99f..6967084 100644
--- a/core/java/android/net/util/SocketUtils.java
+++ b/core/java/android/net/util/SocketUtils.java
@@ -66,6 +66,10 @@
/**
* Make socket address that packet sockets can bind to.
+ *
+ * @param protocol the layer 2 protocol of the packets to receive. One of the {@code ETH_P_*}
+ * constants in {@link android.system.OsConstants}.
+ * @param ifIndex the interface index on which packets will be received.
*/
@NonNull
public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex) {
@@ -78,6 +82,9 @@
/**
* Make a socket address that packet socket can send packets to.
* @deprecated Use {@link #makePacketSocketAddress(int, int, byte[])} instead.
+ *
+ * @param ifIndex the interface index on which packets will be sent.
+ * @param hwAddr the hardware address to which packets will be sent.
*/
@Deprecated
@NonNull
@@ -89,7 +96,12 @@
}
/**
- * Make a socket address that packet socket can send packets to.
+ * Make a socket address that a packet socket can send packets to.
+ *
+ * @param protocol the layer 2 protocol of the packets to send. One of the {@code ETH_P_*}
+ * constants in {@link android.system.OsConstants}.
+ * @param ifIndex the interface index on which packets will be sent.
+ * @param hwAddr the hardware address to which packets will be sent.
*/
@NonNull
public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex,
diff --git a/core/java/android/os/ConfigUpdate.java b/core/java/android/os/ConfigUpdate.java
index 590fbb3..a28f5fb 100644
--- a/core/java/android/os/ConfigUpdate.java
+++ b/core/java/android/os/ConfigUpdate.java
@@ -17,6 +17,8 @@
package android.os;
import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
/**
@@ -125,6 +127,7 @@
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.UPDATE_CONFIG)
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB =
"android.os.action.UPDATE_EMERGENCY_NUMBER_DB";
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index b7c6f68..2217ee3 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -4357,6 +4357,7 @@
* Indicates that whether the message has been broadcasted to the application.
* <P>Type: BOOLEAN</P>
*/
+ // TODO: deprecate this in S.
public static final String MESSAGE_BROADCASTED = "message_broadcasted";
/**
diff --git a/core/java/android/telephony/CellBroadcastIntents.java b/core/java/android/telephony/CellBroadcastIntents.java
index 921ad3c..e07f69a 100644
--- a/core/java/android/telephony/CellBroadcastIntents.java
+++ b/core/java/android/telephony/CellBroadcastIntents.java
@@ -46,7 +46,11 @@
/**
* Broadcast intent action for notifying area information has been updated. The information
- * can be retrieved by {@link CellBroadcastService#getCellBroadcastAreaInfo(int)}
+ * can be retrieved by {@link CellBroadcastService#getCellBroadcastAreaInfo(int)}. The
+ * associated SIM slot index of updated area information can be retrieved through the extra
+ * {@link SubscriptionManager#EXTRA_SLOT_INDEX}.
+ *
+ * @see SubscriptionManager#EXTRA_SLOT_INDEX
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_AREA_INFO_UPDATED =
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 1dca7fd..ab31d24 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -427,6 +427,17 @@
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
public static final int LISTEN_REGISTRATION_FAILURE = 0x40000000;
+ /**
+ * Listen for Barring Information for the current registered / camped cell.
+ *
+ * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
+ * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+ *
+ * @see #onBarringInfoChanged()
+ */
+ @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+ public static final int LISTEN_BARRING_INFO = 0x80000000;
+
/*
* Subscription used to listen to the phone state changes
* @hide
@@ -1036,6 +1047,20 @@
}
/**
+ * Report updated barring information for the current camped/registered cell.
+ *
+ * <p>Barring info is provided for all services applicable to the current camped/registered
+ * cell, for the registered PLMN and current access class/access category.
+ *
+ * @param barringInfo for all services on the current cell.
+ *
+ * @see android.telephony.BarringInfo
+ */
+ public void onBarringInfoChanged(@NonNull BarringInfo barringInfo) {
+ // default implementation empty
+ }
+
+ /**
* The callback methods need to be called on the handler thread where
* this object was created. If the binder did that for us it'd be nice.
*
@@ -1328,6 +1353,14 @@
cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode)));
// default implementation empty
}
+
+ public void onBarringInfoChanged(BarringInfo barringInfo) {
+ PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
+ if (psl == null) return;
+
+ Binder.withCleanCallingIdentity(
+ () -> mExecutor.execute(() -> psl.onBarringInfoChanged(barringInfo)));
+ }
}
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index c4b4c43..73cd708 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -729,4 +729,21 @@
} catch (RemoteException ex) {
}
}
+
+ /**
+ * Notify {@link BarringInfo} has changed for a specific subscription.
+ *
+ * @param slotIndex for the phone object that got updated barring info.
+ * @param subId for which the BarringInfo changed.
+ * @param barringInfo updated BarringInfo.
+ */
+ public void notifyBarringInfoChanged(
+ int slotIndex, int subId, @NonNull BarringInfo barringInfo) {
+ try {
+ sRegistry.notifyBarringInfoChanged(slotIndex, subId, barringInfo);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
}
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index d15f480..3d5dfbb 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -16,6 +16,7 @@
package com.android.internal.telephony;
+import android.telephony.BarringInfo;
import android.telephony.CallAttributes;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
@@ -66,4 +67,5 @@
void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo);
void onRegistrationFailed(in CellIdentity cellIdentity,
String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
+ void onBarringInfoChanged(in BarringInfo barringInfo);
}
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 3176f96..8667155 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -19,6 +19,7 @@
import android.content.Intent;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
+import android.telephony.BarringInfo;
import android.telephony.CallQuality;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
@@ -102,4 +103,5 @@
void notifyImsDisconnectCause(int subId, in ImsReasonInfo imsReasonInfo);
void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity,
String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
+ void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo);
}
diff --git a/media/java/android/media/tv/OWNERS b/media/java/android/media/tv/OWNERS
index 64c0bb5..a891154 100644
--- a/media/java/android/media/tv/OWNERS
+++ b/media/java/android/media/tv/OWNERS
@@ -3,3 +3,7 @@
shubang@google.com
quxiangfang@google.com
+# For android remote service
+per-file ITvRemoteServiceInput.aidl = file:/media/lib/tvremote/OWNERS
+per-file ITvRemoteProvider.aidl = file:/media/lib/tvremote/OWNERS
+
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index c9c847f..3c78560 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -218,24 +218,32 @@
}
public boolean supportsHighQualityAudio(BluetoothDevice device) {
- int support = mService.supportsOptionalCodecs(device);
+ BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
+ if (bluetoothDevice == null) {
+ return false;
+ }
+ int support = mService.isOptionalCodecsSupported(bluetoothDevice);
return support == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED;
}
public boolean isHighQualityAudioEnabled(BluetoothDevice device) {
- int enabled = mService.getOptionalCodecsEnabled(device);
+ BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
+ if (bluetoothDevice == null) {
+ return false;
+ }
+ int enabled = mService.isOptionalCodecsEnabled(bluetoothDevice);
if (enabled != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN) {
return enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED;
- } else if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED &&
- supportsHighQualityAudio(device)) {
+ } else if (getConnectionStatus(bluetoothDevice) != BluetoothProfile.STATE_CONNECTED
+ && supportsHighQualityAudio(bluetoothDevice)) {
// Since we don't have a stored preference and the device isn't connected, just return
// true since the default behavior when the device gets connected in the future would be
// to have optional codecs enabled.
return true;
}
BluetoothCodecConfig codecConfig = null;
- if (mService.getCodecStatus(device) != null) {
- codecConfig = mService.getCodecStatus(device).getCodecConfig();
+ if (mService.getCodecStatus(bluetoothDevice) != null) {
+ codecConfig = mService.getCodecStatus(bluetoothDevice).getCodecConfig();
}
if (codecConfig != null) {
return !codecConfig.isMandatoryCodec();
@@ -245,23 +253,28 @@
}
public void setHighQualityAudioEnabled(BluetoothDevice device, boolean enabled) {
+ BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
+ if (bluetoothDevice == null) {
+ return;
+ }
int prefValue = enabled
? BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED
: BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
- mService.setOptionalCodecsEnabled(device, prefValue);
- if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) {
+ mService.setOptionalCodecsEnabled(bluetoothDevice, prefValue);
+ if (getConnectionStatus(bluetoothDevice) != BluetoothProfile.STATE_CONNECTED) {
return;
}
if (enabled) {
- mService.enableOptionalCodecs(device);
+ mService.enableOptionalCodecs(bluetoothDevice);
} else {
- mService.disableOptionalCodecs(device);
+ mService.disableOptionalCodecs(bluetoothDevice);
}
}
public String getHighQualityAudioOptionLabel(BluetoothDevice device) {
+ BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
int unknownCodecId = R.string.bluetooth_profile_a2dp_high_quality_unknown_codec;
- if (!supportsHighQualityAudio(device)
+ if (bluetoothDevice == null || !supportsHighQualityAudio(device)
|| getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) {
return mContext.getString(unknownCodecId);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index bb9d42e..994a9b3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -611,8 +611,8 @@
* If a connect was attempted earlier without any UUID, we will do the connect now.
* Otherwise, allow the connect on UUID change.
*/
- if (!mProfiles.isEmpty()
- && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime())) {
+ if ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()) {
+ Log.d(TAG, "onUuidChanged: triggering connectAllEnabledProfiles");
connectAllEnabledProfiles();
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
index 414c39b..9afdd43c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
@@ -69,30 +69,31 @@
mProfile = new A2dpProfile(mContext, mDeviceManager, mProfileManager);
mServiceListener = mShadowBluetoothAdapter.getServiceListener();
mServiceListener.onServiceConnected(BluetoothProfile.A2DP, mBluetoothA2dp);
+ when(mBluetoothA2dp.getActiveDevice()).thenReturn(mDevice);
}
@Test
public void supportsHighQualityAudio() {
- when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
assertThat(mProfile.supportsHighQualityAudio(mDevice)).isTrue();
- when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
- when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);
assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
}
@Test
public void isHighQualityAudioEnabled() {
- when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
- when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
@@ -100,16 +101,16 @@
// then isHighQualityAudioEnabled() should return true or false based on whether optional
// codecs are supported. If the device is connected then we should ask it directly, but if
// the device isn't connected then rely on the stored pref about such support.
- when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);
when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
BluetoothProfile.STATE_DISCONNECTED);
- when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
- when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
@@ -151,14 +152,14 @@
// Most tests want to simulate optional codecs being supported by the device, so do that
// by default here.
- when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsSupported(any())).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
}
@Test
public void getLableCodecsNotSupported() {
setupLabelTest();
- when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+ when(mBluetoothA2dp.isOptionalCodecsSupported(any())).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(UNKNOWN_CODEC_LABEL);
}
diff --git a/packages/Tethering/res/values-mcc204-mnc04/strings.xml b/packages/Tethering/res/values-mcc204-mnc04/strings.xml
new file mode 100644
index 0000000..6bc2e2a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc204-mnc04/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+ <string name="no_upstream_notification_title">Tethering & Mobile Hotspot has no internet access</string>
+
+ <!-- String for cellular roaming notification title [CHAR LIMIT=200] -->
+ <string name="upstream_roaming_notification_title">Roaming</string>
+ <!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
+ <string name="upstream_roaming_notification_message">You will be charged on a per MB basis for all data sent or received while using this service outside the Verizon Network. Please check our website for current international rates. To minimize charges, visit My Verizon periodically to monitor your usage, check your device settings to confirm which devices are connected, and consider using alternate data connections when available</string>
+ <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] -->
+ <string name="upstream_roaming_notification_continue_button">Continue</string>
+</resources>
\ No newline at end of file
diff --git a/packages/Tethering/res/values-mcc310-mnc004/strings.xml b/packages/Tethering/res/values-mcc310-mnc004/strings.xml
new file mode 100644
index 0000000..6bc2e2a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+ <string name="no_upstream_notification_title">Tethering & Mobile Hotspot has no internet access</string>
+
+ <!-- String for cellular roaming notification title [CHAR LIMIT=200] -->
+ <string name="upstream_roaming_notification_title">Roaming</string>
+ <!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
+ <string name="upstream_roaming_notification_message">You will be charged on a per MB basis for all data sent or received while using this service outside the Verizon Network. Please check our website for current international rates. To minimize charges, visit My Verizon periodically to monitor your usage, check your device settings to confirm which devices are connected, and consider using alternate data connections when available</string>
+ <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] -->
+ <string name="upstream_roaming_notification_continue_button">Continue</string>
+</resources>
\ No newline at end of file
diff --git a/packages/Tethering/res/values-mcc311-mnc480/strings.xml b/packages/Tethering/res/values-mcc311-mnc480/strings.xml
new file mode 100644
index 0000000..6bc2e2a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+ <string name="no_upstream_notification_title">Tethering & Mobile Hotspot has no internet access</string>
+
+ <!-- String for cellular roaming notification title [CHAR LIMIT=200] -->
+ <string name="upstream_roaming_notification_title">Roaming</string>
+ <!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
+ <string name="upstream_roaming_notification_message">You will be charged on a per MB basis for all data sent or received while using this service outside the Verizon Network. Please check our website for current international rates. To minimize charges, visit My Verizon periodically to monitor your usage, check your device settings to confirm which devices are connected, and consider using alternate data connections when available</string>
+ <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] -->
+ <string name="upstream_roaming_notification_continue_button">Continue</string>
+</resources>
\ No newline at end of file
diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml
index ba98a66..d50884b 100644
--- a/packages/Tethering/res/values/strings.xml
+++ b/packages/Tethering/res/values/strings.xml
@@ -32,4 +32,14 @@
Internet" settings page. That is currently the tether_settings_title_all string. -->
<!-- String for tether notification channel name [CHAR LIMIT=200] -->
<string name="notification_channel_tethering_status">Hotspot & tethering status</string>
+
+ <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+ <string name="no_upstream_notification_title"></string>
+
+ <!-- String for cellular roaming notification title [CHAR LIMIT=200] -->
+ <string name="upstream_roaming_notification_title"></string>
+ <!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
+ <string name="upstream_roaming_notification_message"></string>
+ <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] -->
+ <string name="upstream_roaming_notification_continue_button"></string>
</resources>
\ No newline at end of file
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 4dbbd0d..c7ad3e4 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2233,14 +2233,9 @@
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
final NetworkInfo ni = intent.getParcelableExtra(
ConnectivityManager.EXTRA_NETWORK_INFO);
- if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) {
- intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- } else {
- BroadcastOptions opts = BroadcastOptions.makeBasic();
- opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
- options = opts.toBundle();
- }
+ final BroadcastOptions opts = BroadcastOptions.makeBasic();
+ opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
+ options = opts.toBundle();
final IBatteryStats bs = mDeps.getBatteryStatsService();
try {
bs.noteConnectivityChanged(intent.getIntExtra(
@@ -7944,10 +7939,13 @@
return false;
}
+ final Network[] underlyingNetworks;
synchronized (mVpns) {
- if (getVpnIfOwner(callbackUid) != null) {
- return true;
- }
+ final Vpn vpn = getVpnIfOwner(callbackUid);
+ underlyingNetworks = (vpn == null) ? null : vpn.getUnderlyingNetworks();
+ }
+ if (underlyingNetworks != null) {
+ if (Arrays.asList(underlyingNetworks).contains(nai.network)) return true;
}
// Administrator UIDs also contains the Owner UID
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index f45d54d..4586893 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -45,6 +45,7 @@
import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SrvccState;
+import android.telephony.BarringInfo;
import android.telephony.CallAttributes;
import android.telephony.CallQuality;
import android.telephony.CellIdentity;
@@ -258,6 +259,8 @@
private int[] mCallPreciseDisconnectCause;
+ private List<BarringInfo> mBarringInfo = null;
+
private boolean mCarrierNetworkChangeState = false;
private PhoneCapability mPhoneCapability = null;
@@ -451,6 +454,7 @@
cutListToSize(mCellInfo, mNumPhones);
cutListToSize(mImsReasonInfo, mNumPhones);
cutListToSize(mPreciseDataConnectionStates, mNumPhones);
+ cutListToSize(mBarringInfo, mNumPhones);
return;
}
@@ -483,6 +487,7 @@
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
mDisplayInfos[i] = null;
+ mBarringInfo.add(i, new BarringInfo());
}
}
@@ -541,6 +546,7 @@
mOutgoingCallEmergencyNumber = new EmergencyNumber[numPhones];
mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones];
mDisplayInfos = new DisplayInfo[numPhones];
+ mBarringInfo = new ArrayList<>();
for (int i = 0; i < numPhones; i++) {
mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
@@ -569,6 +575,7 @@
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
mDisplayInfos[i] = null;
+ mBarringInfo.add(i, new BarringInfo());
}
mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -1031,6 +1038,19 @@
remove(r.binder);
}
}
+ if ((events & PhoneStateListener.LISTEN_BARRING_INFO) != 0) {
+ BarringInfo barringInfo = mBarringInfo.get(phoneId);
+ BarringInfo biNoLocation = barringInfo != null
+ ? barringInfo.createLocationInfoSanitizedCopy() : null;
+ if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
+ try {
+ r.callback.onBarringInfoChanged(
+ checkFineLocationAccess(r, Build.VERSION_CODES.R)
+ ? barringInfo : biNoLocation);
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
}
}
} else {
@@ -2207,6 +2227,52 @@
}
}
+ /**
+ * Send a notification of changes to barring status to PhoneStateListener registrants.
+ *
+ * @param phoneId the phoneId
+ * @param subId the subId
+ * @param barringInfo a structure containing the complete updated barring info.
+ */
+ public void notifyBarringInfoChanged(int phoneId, int subId, @NonNull BarringInfo barringInfo) {
+ if (!checkNotifyPermission("notifyBarringInfo()")) {
+ return;
+ }
+ if (barringInfo == null) {
+ log("Received null BarringInfo for subId=" + subId + ", phoneId=" + phoneId);
+ mBarringInfo.set(phoneId, new BarringInfo());
+ return;
+ }
+
+ synchronized (mRecords) {
+ if (validatePhoneId(phoneId)) {
+ mBarringInfo.set(phoneId, barringInfo);
+ // Barring info is non-null
+ BarringInfo biNoLocation = barringInfo.createLocationInfoSanitizedCopy();
+ if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
+ for (Record r : mRecords) {
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_BARRING_INFO)
+ && idMatch(r.subId, subId, phoneId)) {
+ try {
+ if (DBG_LOC) {
+ log("notifyBarringInfo: mBarringInfo="
+ + barringInfo + " r=" + r);
+ }
+ r.callback.onBarringInfoChanged(
+ checkFineLocationAccess(r, Build.VERSION_CODES.R)
+ ? barringInfo : biNoLocation);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ }
+
+
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
@@ -2247,6 +2313,7 @@
pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i));
pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]);
pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]);
+ pw.println("mBarringInfo=" + mBarringInfo.get(i));
pw.decreaseIndent();
}
pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 54ab906e..ba4e11a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -343,7 +343,7 @@
*/
final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
- /** @see #computeCompatSmallestWidth(boolean, int, int, int, DisplayCutout) */
+ /** @see #computeCompatSmallestWidth(boolean, int, int, int) */
private final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
/**
@@ -1715,7 +1715,7 @@
config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, config.uiMode, dw,
- dh, displayInfo.displayCutout);
+ dh);
config.densityDpi = displayInfo.logicalDensityDpi;
config.colorMode =
@@ -1800,8 +1800,7 @@
mWmService.mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
}
- private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh,
- DisplayCutout displayCutout) {
+ private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh) {
mTmpDisplayMetrics.setTo(mDisplayMetrics);
final DisplayMetrics tmpDm = mTmpDisplayMetrics;
final int unrotDw, unrotDh;
@@ -1812,19 +1811,21 @@
unrotDw = dw;
unrotDh = dh;
}
- int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh,
- displayCutout);
- sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw,
- displayCutout);
- sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh,
- displayCutout);
- sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw,
- displayCutout);
+ int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw,
+ unrotDh);
+ sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh,
+ unrotDw);
+ sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw,
+ unrotDh);
+ sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh,
+ unrotDw);
return sw;
}
private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
- DisplayMetrics dm, int dw, int dh, DisplayCutout displayCutout) {
+ DisplayMetrics dm, int dw, int dh) {
+ final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
+ rotation).getDisplayCutout();
dm.noncompatWidthPixels = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
displayCutout);
dm.noncompatHeightPixels = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
@@ -1865,20 +1866,20 @@
return;
}
int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
- sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode,
- displayInfo.displayCutout);
- sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode,
- displayInfo.displayCutout);
- sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode,
- displayInfo.displayCutout);
- sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode,
- displayInfo.displayCutout);
+ sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode);
+ sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode);
+ sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode);
+ sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode);
outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
outConfig.screenLayout = sl;
}
private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh,
- int uiMode, DisplayCutout displayCutout) {
+ int uiMode) {
+ // Get the display cutout at this rotation.
+ final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
+ rotation).getDisplayCutout();
+
// Get the app screen size at this rotation.
int w = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayCutout);
int h = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayCutout);
diff --git a/telephony/OWNERS b/telephony/OWNERS
index 58a7ea0..628c480 100644
--- a/telephony/OWNERS
+++ b/telephony/OWNERS
@@ -1,18 +1,16 @@
set noparent
-tgunn@google.com
-breadley@google.com
-hallliu@google.com
-rgreenwalt@google.com
-mpq@google.com
amitmahajan@google.com
+breadley@google.com
fionaxu@google.com
jackyu@google.com
+hallliu@google.com
+rgreenwalt@google.com
+tgunn@google.com
jminjie@google.com
-satk@google.com
shuoq@google.com
refuhoo@google.com
-paulye@google.com
nazaninb@google.com
sarahchin@google.com
dbright@google.com
+xiaotonj@google.com
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 0325c36..85db35d 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -571,6 +571,19 @@
public @interface PreciseDisconnectCauses {
}
+ /**
+ * Carrier Privilege Status.
+ */
+ @IntDef(prefix = { "CARRIER_PRIVILEGE_STATUS_" }, value = {
+ TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS,
+ TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS,
+ TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED,
+ TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CarrierPrivilegeStatus {
+ }
+
@IntDef({
Connection.AUDIO_CODEC_NONE,
Connection.AUDIO_CODEC_AMR,
diff --git a/telephony/java/android/telephony/BarringInfo.aidl b/telephony/java/android/telephony/BarringInfo.aidl
new file mode 100644
index 0000000..50ddf6b
--- /dev/null
+++ b/telephony/java/android/telephony/BarringInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** @hide */
+package android.telephony;
+
+parcelable BarringInfo;
diff --git a/telephony/java/android/telephony/BarringInfo.java b/telephony/java/android/telephony/BarringInfo.java
new file mode 100644
index 0000000..92423a2
--- /dev/null
+++ b/telephony/java/android/telephony/BarringInfo.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Provides the barring configuration for a particular service type.
+ *
+ * Provides indication about the barring of a particular service for use. Certain barring types
+ * are only valid for certain technology families. Any service that does not have a barring
+ * configuration is unbarred by default.
+ */
+public final class BarringInfo implements Parcelable {
+
+ /**
+ * Barring Service Type
+ *
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "BARRING_SERVICE_TYPE_", value = {
+ BARRING_SERVICE_TYPE_CS_SERVICE,
+ BARRING_SERVICE_TYPE_PS_SERVICE,
+ BARRING_SERVICE_TYPE_CS_VOICE,
+ BARRING_SERVICE_TYPE_MO_SIGNALLING,
+ BARRING_SERVICE_TYPE_MO_DATA,
+ BARRING_SERVICE_TYPE_CS_FALLBACK,
+ BARRING_SERVICE_TYPE_MMTEL_VOICE,
+ BARRING_SERVICE_TYPE_MMTEL_VIDEO,
+ BARRING_SERVICE_TYPE_EMERGENCY,
+ BARRING_SERVICE_TYPE_SMS})
+ public @interface BarringServiceType {}
+
+ /* Applicabe to UTRAN */
+ /** Barring indicator for circuit-switched service; applicable to UTRAN */
+ public static final int BARRING_SERVICE_TYPE_CS_SERVICE =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_SERVICE;
+ /** Barring indicator for packet-switched service; applicable to UTRAN */
+ public static final int BARRING_SERVICE_TYPE_PS_SERVICE =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.PS_SERVICE;
+ /** Barring indicator for circuit-switched voice service; applicable to UTRAN */
+ public static final int BARRING_SERVICE_TYPE_CS_VOICE =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_VOICE;
+
+ /* Applicable to EUTRAN, NGRAN */
+ /** Barring indicator for mobile-originated signalling; applicable to EUTRAN and NGRAN */
+ public static final int BARRING_SERVICE_TYPE_MO_SIGNALLING =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_SIGNALLING;
+ /** Barring indicator for mobile-originated data traffic; applicable to EUTRAN and NGRAN */
+ public static final int BARRING_SERVICE_TYPE_MO_DATA =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_DATA;
+ /** Barring indicator for circuit-switched fallback for voice; applicable to EUTRAN and NGRAN */
+ public static final int BARRING_SERVICE_TYPE_CS_FALLBACK =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_FALLBACK;
+ /** Barring indicator for MMTEL (IMS) voice; applicable to EUTRAN and NGRAN */
+ public static final int BARRING_SERVICE_TYPE_MMTEL_VOICE =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VOICE;
+ /** Barring indicator for MMTEL (IMS) video; applicable to EUTRAN and NGRAN */
+ public static final int BARRING_SERVICE_TYPE_MMTEL_VIDEO =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VIDEO;
+
+ /* Applicable to UTRAN, EUTRAN, NGRAN */
+ /** Barring indicator for emergency services; applicable to UTRAN, EUTRAN, and NGRAN */
+ public static final int BARRING_SERVICE_TYPE_EMERGENCY =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.EMERGENCY;
+ /** Barring indicator for SMS sending; applicable to UTRAN, EUTRAN, and NGRAN */
+ public static final int BARRING_SERVICE_TYPE_SMS =
+ android.hardware.radio.V1_5.BarringInfo.ServiceType.SMS;
+
+ //TODO: add barring constants for Operator-Specific barring codes
+
+ /** Describe the current barring configuration of a cell */
+ public static final class BarringServiceInfo implements Parcelable {
+ /**
+ * Barring Type
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "BARRING_TYPE_", value =
+ {BARRING_TYPE_NONE,
+ BARRING_TYPE_UNCONDITIONAL,
+ BARRING_TYPE_CONDITIONAL,
+ BARRING_TYPE_UNKNOWN})
+ public @interface BarringType {}
+
+ /** Barring is inactive */
+ public static final int BARRING_TYPE_NONE =
+ android.hardware.radio.V1_5.BarringInfo.BarringType.NONE;
+ /** The service is barred */
+ public static final int BARRING_TYPE_UNCONDITIONAL =
+ android.hardware.radio.V1_5.BarringInfo.BarringType.UNCONDITIONAL;
+ /** The service may be barred based on additional factors */
+ public static final int BARRING_TYPE_CONDITIONAL =
+ android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL;
+
+ /** If a modem does not report barring info, then the barring type will be UNKNOWN */
+ public static final int BARRING_TYPE_UNKNOWN = -1;
+
+ private final @BarringType int mBarringType;
+
+ private final boolean mIsConditionallyBarred;
+ private final int mConditionalBarringFactor;
+ private final int mConditionalBarringTimeSeconds;
+
+ /** @hide */
+ public BarringServiceInfo(@BarringType int type) {
+ this(type, false, 0, 0);
+ }
+
+ /** @hide */
+ @TestApi
+ public BarringServiceInfo(@BarringType int barringType, boolean isConditionallyBarred,
+ int conditionalBarringFactor, int conditionalBarringTimeSeconds) {
+ mBarringType = barringType;
+ mIsConditionallyBarred = isConditionallyBarred;
+ mConditionalBarringFactor = conditionalBarringFactor;
+ mConditionalBarringTimeSeconds = conditionalBarringTimeSeconds;
+ }
+
+ public @BarringType int getBarringType() {
+ return mBarringType;
+ }
+
+ /**
+ * @return true if the conditional barring parameters have resulted in the service being
+ * barred; false if the service has either not been evaluated for conditional
+ * barring or has been evaluated and isn't barred.
+ */
+ public boolean isConditionallyBarred() {
+ return mIsConditionallyBarred;
+ }
+
+ /**
+ * @return the conditional barring factor as a percentage 0-100, which is the probability of
+ * a random device being barred for the service type.
+ */
+ public int getConditionalBarringFactor() {
+ return mConditionalBarringFactor;
+ }
+
+ /**
+ * @return the conditional barring time seconds, which is the interval between successive
+ * evaluations for conditional barring based on the barring factor.
+ */
+ @SuppressLint("MethodNameUnits")
+ public int getConditionalBarringTimeSeconds() {
+ return mConditionalBarringTimeSeconds;
+ }
+
+ /**
+ * Return whether a service is currently barred based on the BarringInfo
+ *
+ * @return true if the service is currently being barred, otherwise false
+ */
+ public boolean isBarred() {
+ return mBarringType == BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL
+ || (mBarringType == BarringServiceInfo.BARRING_TYPE_CONDITIONAL
+ && mIsConditionallyBarred);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mBarringType, mIsConditionallyBarred,
+ mConditionalBarringFactor, mConditionalBarringTimeSeconds);
+ }
+
+ @Override
+ public boolean equals(Object rhs) {
+ if (!(rhs instanceof BarringServiceInfo)) return false;
+
+ BarringServiceInfo other = (BarringServiceInfo) rhs;
+ return mBarringType == other.mBarringType
+ && mIsConditionallyBarred == other.mIsConditionallyBarred
+ && mConditionalBarringFactor == other.mConditionalBarringFactor
+ && mConditionalBarringTimeSeconds == other.mConditionalBarringTimeSeconds;
+ }
+
+ /** @hide */
+ public BarringServiceInfo(Parcel p) {
+ mBarringType = p.readInt();
+ mIsConditionallyBarred = p.readBoolean();
+ mConditionalBarringFactor = p.readInt();
+ mConditionalBarringTimeSeconds = p.readInt();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mBarringType);
+ dest.writeBoolean(mIsConditionallyBarred);
+ dest.writeInt(mConditionalBarringFactor);
+ dest.writeInt(mConditionalBarringTimeSeconds);
+ }
+
+ /* @inheritDoc */
+ public static final @NonNull Parcelable.Creator<BarringServiceInfo> CREATOR =
+ new Parcelable.Creator<BarringServiceInfo>() {
+ @Override
+ public BarringServiceInfo createFromParcel(Parcel source) {
+ return new BarringServiceInfo(source);
+ }
+
+ @Override
+ public BarringServiceInfo[] newArray(int size) {
+ return new BarringServiceInfo[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ }
+
+ private static final BarringServiceInfo BARRING_SERVICE_INFO_UNKNOWN =
+ new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_UNKNOWN);
+
+ private static final BarringServiceInfo BARRING_SERVICE_INFO_UNBARRED =
+ new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_NONE);
+
+ private CellIdentity mCellIdentity;
+
+ // A SparseArray potentially mapping each BarringService type to a BarringServiceInfo config
+ // that describes the current barring status of that particular service.
+ private SparseArray<BarringServiceInfo> mBarringServiceInfos;
+
+ /** @hide */
+ @TestApi
+ @SystemApi
+ public BarringInfo() {
+ mBarringServiceInfos = new SparseArray<>();
+ }
+
+ /**
+ * Constructor for new BarringInfo instances.
+ *
+ * @hide
+ */
+ @TestApi
+ public BarringInfo(@Nullable CellIdentity barringCellId,
+ @NonNull SparseArray<BarringServiceInfo> barringServiceInfos) {
+ mCellIdentity = barringCellId;
+ mBarringServiceInfos = barringServiceInfos;
+ }
+
+ /** @hide */
+ public static BarringInfo create(
+ @NonNull android.hardware.radio.V1_5.CellIdentity halBarringCellId,
+ @NonNull List<android.hardware.radio.V1_5.BarringInfo> halBarringInfos) {
+ CellIdentity ci = CellIdentity.create(halBarringCellId);
+ SparseArray<BarringServiceInfo> serviceInfos = new SparseArray<>();
+
+ for (android.hardware.radio.V1_5.BarringInfo halBarringInfo : halBarringInfos) {
+ if (halBarringInfo.barringType
+ == android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL) {
+ if (halBarringInfo.barringTypeSpecificInfo.getDiscriminator()
+ != android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo
+ .hidl_discriminator.conditional) {
+ // this is an error case where the barring info is conditional but the
+ // conditional barring fields weren't included
+ continue;
+ }
+ android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo
+ .Conditional conditionalInfo =
+ halBarringInfo.barringTypeSpecificInfo.conditional();
+ serviceInfos.put(
+ halBarringInfo.serviceType, new BarringServiceInfo(
+ halBarringInfo.barringType, // will always be CONDITIONAL here
+ conditionalInfo.isBarred,
+ conditionalInfo.factor,
+ conditionalInfo.timeSeconds));
+ } else {
+ // Barring type is either NONE or UNCONDITIONAL
+ serviceInfos.put(
+ halBarringInfo.serviceType, new BarringServiceInfo(
+ halBarringInfo.barringType, false, 0, 0));
+ }
+ }
+ return new BarringInfo(ci, serviceInfos);
+ }
+
+ /**
+ * Get the BarringServiceInfo for a specified service.
+ *
+ * @return a BarringServiceInfo struct describing the current barring status for a service
+ */
+ public @NonNull BarringServiceInfo getBarringServiceInfo(@BarringServiceType int service) {
+ BarringServiceInfo bsi = mBarringServiceInfos.get(service);
+ // If barring is reported but not for a particular service, then we report the barring
+ // type as UNKNOWN; if the modem reports barring info but doesn't report for a particular
+ // service then we can safely assume that the service isn't barred (for instance because
+ // that particular service isn't applicable to the current RAN).
+ return (bsi != null) ? bsi : mBarringServiceInfos.size() > 0
+ ? BARRING_SERVICE_INFO_UNBARRED : BARRING_SERVICE_INFO_UNKNOWN;
+ }
+
+ /** @hide */
+ @SystemApi
+ public @NonNull BarringInfo createLocationInfoSanitizedCopy() {
+ // The only thing that would need sanitizing is the CellIdentity
+ if (mCellIdentity == null) return this;
+
+ return new BarringInfo(mCellIdentity.sanitizeLocationInfo(), mBarringServiceInfos);
+ }
+
+ /** @hide */
+ public BarringInfo(Parcel p) {
+ mCellIdentity = p.readParcelable(CellIdentity.class.getClassLoader());
+ mBarringServiceInfos = p.readSparseArray(BarringServiceInfo.class.getClassLoader());
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeParcelable(mCellIdentity, flags);
+ dest.writeSparseArray(mBarringServiceInfos);
+ }
+
+ public static final @NonNull Parcelable.Creator<BarringInfo> CREATOR =
+ new Parcelable.Creator<BarringInfo>() {
+ @Override
+ public BarringInfo createFromParcel(Parcel source) {
+ return new BarringInfo(source);
+ }
+
+ @Override
+ public BarringInfo[] newArray(int size) {
+ return new BarringInfo[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = mCellIdentity != null ? mCellIdentity.hashCode() : 7;
+ for (int i = 0; i < mBarringServiceInfos.size(); i++) {
+ hash = hash + 15 * mBarringServiceInfos.keyAt(i);
+ hash = hash + 31 * mBarringServiceInfos.valueAt(i).hashCode();
+ }
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object rhs) {
+ if (!(rhs instanceof BarringInfo)) return false;
+
+ BarringInfo bi = (BarringInfo) rhs;
+
+ if (hashCode() != bi.hashCode()) return false;
+
+ if (mBarringServiceInfos.size() != bi.mBarringServiceInfos.size()) return false;
+
+ for (int i = 0; i < mBarringServiceInfos.size(); i++) {
+ if (mBarringServiceInfos.keyAt(i) != bi.mBarringServiceInfos.keyAt(i)) return false;
+ if (!Objects.equals(mBarringServiceInfos.valueAt(i),
+ bi.mBarringServiceInfos.valueAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "BarringInfo {mCellIdentity=" + mCellIdentity
+ + ", mBarringServiceInfos=" + mBarringServiceInfos + "}";
+ }
+}
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index d8a6551..3e901e2 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -25,6 +25,7 @@
import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation.NetworkType;
+import android.text.TextUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -214,6 +215,9 @@
@Nullable
private DataSpecificRegistrationInfo mDataSpecificInfo;
+ @NonNull
+ private String mRplmn;
+
/**
* @param domain Network domain. Must be a {@link Domain}. For transport type
* {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}.
@@ -234,13 +238,14 @@
* @param availableServices The list of the supported services.
* @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the
* information is not available.
+ * @param rplmn the registered plmn or the last plmn for attempted registration if reg failed.
*/
private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType,
@RegistrationState int registrationState,
@NetworkType int accessNetworkTechnology, int rejectCause,
boolean emergencyOnly,
@Nullable @ServiceType List<Integer> availableServices,
- @Nullable CellIdentity cellIdentity) {
+ @Nullable CellIdentity cellIdentity, @Nullable String rplmn) {
mDomain = domain;
mTransportType = transportType;
mRegistrationState = registrationState;
@@ -253,6 +258,7 @@
mCellIdentity = cellIdentity;
mEmergencyOnly = emergencyOnly;
mNrState = NR_STATE_NONE;
+ mRplmn = rplmn;
}
/**
@@ -263,11 +269,11 @@
int registrationState, int accessNetworkTechnology,
int rejectCause, boolean emergencyOnly,
@Nullable List<Integer> availableServices,
- @Nullable CellIdentity cellIdentity, boolean cssSupported,
- int roamingIndicator, int systemIsInPrl,
+ @Nullable CellIdentity cellIdentity, @Nullable String rplmn,
+ boolean cssSupported, int roamingIndicator, int systemIsInPrl,
int defaultRoamingIndicator) {
this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
- emergencyOnly, availableServices, cellIdentity);
+ emergencyOnly, availableServices, cellIdentity, rplmn);
mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator,
systemIsInPrl, defaultRoamingIndicator);
@@ -281,13 +287,13 @@
int registrationState, int accessNetworkTechnology,
int rejectCause, boolean emergencyOnly,
@Nullable List<Integer> availableServices,
- @Nullable CellIdentity cellIdentity, int maxDataCalls,
- boolean isDcNrRestricted, boolean isNrAvailable,
- boolean isEndcAvailable,
+ @Nullable CellIdentity cellIdentity, @Nullable String rplmn,
+ int maxDataCalls, boolean isDcNrRestricted,
+ boolean isNrAvailable, boolean isEndcAvailable,
LteVopsSupportInfo lteVopsSupportInfo,
boolean isUsingCarrierAggregation) {
this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
- emergencyOnly, availableServices, cellIdentity);
+ emergencyOnly, availableServices, cellIdentity, rplmn);
mDataSpecificInfo = new DataSpecificRegistrationInfo(
maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo,
isUsingCarrierAggregation);
@@ -310,6 +316,7 @@
mDataSpecificInfo = source.readParcelable(
DataSpecificRegistrationInfo.class.getClassLoader());
mNrState = source.readInt();
+ mRplmn = source.readString();
}
/**
@@ -343,6 +350,7 @@
mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo);
}
mNrState = nri.mNrState;
+ mRplmn = nri.mRplmn;
}
/**
@@ -395,6 +403,22 @@
}
/**
+ * Get the PLMN-ID for this Network Registration, also known as the RPLMN.
+ *
+ * <p>If the device is registered, this will return the registered PLMN-ID. If registration
+ * has failed, then this will return the PLMN ID of the last attempted registration. If the
+ * device is not registered, or if is registered to a non-3GPP radio technology, then this
+ * will return null.
+ *
+ * <p>See 3GPP TS 23.122 for further information about the Registered PLMN.
+ *
+ * @return the registered PLMN-ID or null.
+ */
+ @Nullable public String getRegisteredPlmn() {
+ return mRplmn;
+ }
+
+ /**
* @return {@code true} if registered on roaming network, {@code false} otherwise.
*/
public boolean isRoaming() {
@@ -590,6 +614,7 @@
.append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
.append(" dataSpecificInfo=").append(mDataSpecificInfo)
.append(" nrState=").append(nrStateToString(mNrState))
+ .append(" rRplmn=").append(mRplmn)
.append("}").toString();
}
@@ -597,7 +622,7 @@
public int hashCode() {
return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
- mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState);
+ mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn);
}
@Override
@@ -620,6 +645,7 @@
&& Objects.equals(mCellIdentity, other.mCellIdentity)
&& Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
&& Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
+ && TextUtils.equals(mRplmn, other.mRplmn)
&& mNrState == other.mNrState;
}
@@ -641,6 +667,7 @@
dest.writeParcelable(mVoiceSpecificInfo, 0);
dest.writeParcelable(mDataSpecificInfo, 0);
dest.writeInt(mNrState);
+ dest.writeString(mRplmn);
}
/**
@@ -741,6 +768,9 @@
@Nullable
private CellIdentity mCellIdentity;
+ @NonNull
+ private String mRplmn = "";
+
/**
* Default constructor for Builder.
*/
@@ -855,6 +885,18 @@
}
/**
+ * Set the registered PLMN.
+ *
+ * @param rplmn the registered plmn.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setRegisteredPlmn(@Nullable String rplmn) {
+ mRplmn = rplmn;
+ return this;
+ }
+
+ /**
* Build the NetworkRegistrationInfo.
* @return the NetworkRegistrationInfo object.
* @hide
@@ -863,7 +905,7 @@
public @NonNull NetworkRegistrationInfo build() {
return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
- mCellIdentity);
+ mCellIdentity, mRplmn);
}
}
}
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index 54c22ae..708adeb 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -265,10 +265,10 @@
/**
* Return the APN Settings for this data connection.
*
- * Returns the ApnSetting that was used to configure this data connection.
+ * @return the ApnSetting that was used to configure this data connection.
*/
// FIXME: This shouldn't be nullable; update once the ApnSetting is supplied correctly
- @Nullable ApnSetting getApnSetting() {
+ public @Nullable ApnSetting getApnSetting() {
return mApnSetting;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e595b10..5584d98 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -73,6 +73,7 @@
import android.telephony.Annotation.CallForwardingReason;
import android.telephony.Annotation.CallState;
import android.telephony.Annotation.CallWaitingStatus;
+import android.telephony.Annotation.CarrierPrivilegeStatus;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SimActivationState;
@@ -11115,8 +11116,6 @@
retVal = telephony.isDataEnabled(subId);
} catch (RemoteException e) {
Log.e(TAG, "Error isDataConnectionAllowed", e);
- } catch (NullPointerException e) {
- return false;
}
return retVal;
}
@@ -12351,7 +12350,7 @@
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public int getCarrierPrivilegeStatus(int uid) {
+ public @CarrierPrivilegeStatus int getCarrierPrivilegeStatus(int uid) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index a7d553b..9e466aea9 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -182,6 +182,25 @@
* {@link ImsCallProfile#DIALSTRING_USSD}
*/
public static final String EXTRA_DIALSTRING = "dialstring";
+ /**
+ * This extra holds call fail cause because of which redial is attempted.
+ * see {@link android.telephony.ims.ImsReasonInfo} {@code CODE_*}
+ * for possible values this extra can hold.
+ *
+ * @hide
+ */
+ public static final String EXTRA_RETRY_CALL_FAIL_REASON =
+ "android.telephony.ims.extra.RETRY_CALL_FAIL_REASON";
+ /**
+ * This extra holds call network type on which lower layers
+ * may try attempting redial.
+ * See {@link TelephonyManager} {@code NETWORK_TYPE_*}
+ * for possible values this extra can hold.
+ *
+ * @hide
+ */
+ public static final String EXTRA_RETRY_CALL_FAIL_NETWORKTYPE =
+ "android.telephony.ims.extra.RETRY_CALL_FAIL_NETWORKTYPE";
/**
* Values for EXTRA_OIR / EXTRA_CNAP
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 53ad70a..6fdc13e 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -492,6 +492,7 @@
int RIL_REQUEST_ENABLE_UICC_APPLICATIONS = 208;
int RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT = 209;
int RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS = 210;
+ int RIL_REQUEST_GET_BARRING_INFO = 211;
/* Responses begin */
int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
@@ -557,4 +558,5 @@
int RIL_UNSOL_EMERGENCY_NUMBER_LIST = 1102;
int RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED = 1103;
int RIL_UNSOL_REGISTRATION_FAILED = 1104;
+ int RIL_UNSOL_BARRING_INFO_CHANGED = 1105;
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 9dc0a62..51eaf66 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -25,7 +25,6 @@
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL;
import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE;
import static android.net.ConnectivityManager.NETID_UNSET;
@@ -308,6 +307,8 @@
private static final long TIMESTAMP = 1234L;
+ private static final int NET_ID = 110;
+
private static final String CLAT_PREFIX = "v4-";
private static final String MOBILE_IFNAME = "test_rmnet_data0";
private static final String WIFI_IFNAME = "test_wlan0";
@@ -1017,6 +1018,7 @@
private int mVpnType = VpnManager.TYPE_VPN_SERVICE;
private VpnInfo mVpnInfo;
+ private Network[] mUnderlyingNetworks;
public MockVpn(int userId) {
super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService,
@@ -1106,9 +1108,21 @@
return super.getVpnInfo();
}
- private void setVpnInfo(VpnInfo vpnInfo) {
+ private synchronized void setVpnInfo(VpnInfo vpnInfo) {
mVpnInfo = vpnInfo;
}
+
+ @Override
+ public synchronized Network[] getUnderlyingNetworks() {
+ if (mUnderlyingNetworks != null) return mUnderlyingNetworks;
+
+ return super.getUnderlyingNetworks();
+ }
+
+ /** Don't override behavior for {@link Vpn#setUnderlyingNetworks}. */
+ private synchronized void overrideUnderlyingNetworks(Network[] underlyingNetworks) {
+ mUnderlyingNetworks = underlyingNetworks;
+ }
}
private void mockVpn(int uid) {
@@ -1375,7 +1389,6 @@
@NonNull final Predicate<Intent> filter) {
final ConditionVariable cv = new ConditionVariable();
final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION);
- intentFilter.addAction(CONNECTIVITY_ACTION_SUPL);
final BroadcastReceiver receiver = new BroadcastReceiver() {
private int remaining = count;
public void onReceive(Context context, Intent intent) {
@@ -1423,56 +1436,28 @@
final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL,
ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST);
- // Send request and check that the legacy broadcast for SUPL is sent correctly.
+ // File request, withdraw it and make sure no broadcast is sent
+ final ConditionVariable cv2 = registerConnectivityBroadcast(1);
final TestNetworkCallback callback = new TestNetworkCallback();
- final ConditionVariable cv2 = registerConnectivityBroadcastThat(1,
- intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL);
mCm.requestNetwork(legacyRequest, callback);
callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
- waitFor(cv2);
-
- // File another request, withdraw it and make sure no broadcast is sent
- final ConditionVariable cv3 = registerConnectivityBroadcast(1);
- final TestNetworkCallback callback2 = new TestNetworkCallback();
- mCm.requestNetwork(legacyRequest, callback2);
- callback2.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
- mCm.unregisterNetworkCallback(callback2);
- assertFalse(cv3.block(800)); // 800ms long enough to at least flake if this is sent
+ mCm.unregisterNetworkCallback(callback);
+ assertFalse(cv2.block(800)); // 800ms long enough to at least flake if this is sent
// As the broadcast did not fire, the receiver was not unregistered. Do this now.
mServiceContext.clearRegisteredReceivers();
- // Withdraw the request and check that the broadcast for disconnection is sent.
- final ConditionVariable cv4 = registerConnectivityBroadcastThat(1, intent ->
- !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected()
- && intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL);
- mCm.unregisterNetworkCallback(callback);
- waitFor(cv4);
-
- // Re-file the request and expect the connected broadcast again
- final ConditionVariable cv5 = registerConnectivityBroadcastThat(1,
- intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL);
- final TestNetworkCallback callback3 = new TestNetworkCallback();
- mCm.requestNetwork(legacyRequest, callback3);
- callback3.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
- waitFor(cv5);
-
- // Disconnect the network and expect two disconnected broadcasts, one for SUPL and one
- // for mobile. Use a small hack to check that both have been sent, but the order is
- // not contractual.
+ // Disconnect the network and expect mobile disconnected broadcast. Use a small hack to
+ // check that has been sent.
final AtomicBoolean vanillaAction = new AtomicBoolean(false);
- final AtomicBoolean suplAction = new AtomicBoolean(false);
- final ConditionVariable cv6 = registerConnectivityBroadcastThat(2, intent -> {
+ final ConditionVariable cv3 = registerConnectivityBroadcastThat(1, intent -> {
if (intent.getAction().equals(CONNECTIVITY_ACTION)) {
vanillaAction.set(true);
- } else if (intent.getAction().equals(CONNECTIVITY_ACTION_SUPL)) {
- suplAction.set(true);
}
return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected();
});
mCellNetworkAgent.disconnect();
- waitFor(cv6);
+ waitFor(cv3);
assertTrue(vanillaAction.get());
- assertTrue(suplAction.get());
}
@Test
@@ -6851,9 +6836,10 @@
@Test
public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception {
+ final Network network = new Network(NET_ID);
final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo(
- null, null, null, null, null, new NetworkCapabilities(), 0,
+ null, null, network, null, null, new NetworkCapabilities(), 0,
mServiceContext, null, null, mService, null, null, null, 0);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
@@ -6866,11 +6852,19 @@
info.ownerUid = Process.myUid();
info.vpnIface = "interface";
mMockVpn.setVpnInfo(info);
+ mMockVpn.overrideUnderlyingNetworks(new Network[] {network});
assertTrue(
"Active VPN permission not applied",
mService.checkConnectivityDiagnosticsPermissions(
Process.myPid(), Process.myUid(), naiWithoutUid,
mContext.getOpPackageName()));
+
+ mMockVpn.overrideUnderlyingNetworks(null);
+ assertFalse(
+ "VPN shouldn't receive callback on non-underlying network",
+ mService.checkConnectivityDiagnosticsPermissions(
+ Process.myPid(), Process.myUid(), naiWithoutUid,
+ mContext.getOpPackageName()));
}
@Test