summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp48
-rw-r--r--Android.mk2
-rw-r--r--ApiDocs.bp5
-rw-r--r--StubLibraries.bp16
-rw-r--r--apex/Android.bp18
-rw-r--r--apex/sdkextensions/framework/Android.bp6
-rw-r--r--api/current.txt47
-rwxr-xr-xapi/system-current.txt92
-rw-r--r--api/system-lint-baseline.txt6
-rw-r--r--api/test-current.txt35
-rw-r--r--cmds/idmap2/idmap2/Create.cpp2
-rw-r--r--cmds/idmap2/idmap2/Dump.cpp2
-rw-r--r--cmds/idmap2/tests/Idmap2BinaryTests.cpp1
-rw-r--r--cmds/incidentd/src/Section.cpp4
-rw-r--r--config/preloaded-classes1
-rw-r--r--core/java/android/app/ActivityManager.java2
-rw-r--r--core/java/android/app/LoadedApk.java5
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java37
-rw-r--r--core/java/android/bluetooth/BluetoothHearingAid.java10
-rw-r--r--core/java/android/content/Context.java2
-rw-r--r--core/java/android/content/pm/PackageInstaller.java78
-rw-r--r--core/java/android/content/pm/PackageManager.java2
-rw-r--r--core/java/android/net/InvalidPacketException.java9
-rw-r--r--core/java/android/net/KeepalivePacketData.java49
-rw-r--r--core/java/android/net/LinkProperties.java16
-rw-r--r--core/java/android/net/NattKeepalivePacketData.java22
-rw-r--r--core/java/android/net/Network.java86
-rw-r--r--core/java/android/net/NetworkCapabilities.java436
-rw-r--r--core/java/android/net/OWNERS2
-rw-r--r--core/java/android/net/RouteInfo.java31
-rw-r--r--core/java/android/net/http/OWNERS2
-rw-r--r--core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl3
-rw-r--r--core/java/android/telephony/PhoneStateListener.java1
-rw-r--r--core/java/android/telephony/SubscriptionPlan.java39
-rw-r--r--core/java/android/telephony/TelephonyRegistryManager.java87
-rw-r--r--core/jni/android_app_admin_SecurityLog.cpp9
-rw-r--r--core/jni/android_util_EventLog.cpp5
-rw-r--r--core/proto/android/stats/dnsresolver/dns_resolver.proto141
-rw-r--r--core/res/res/values/public.xml9
-rw-r--r--core/res/res/values/strings.xml232
-rw-r--r--data/etc/hiddenapi-package-whitelist.xml3
-rw-r--r--libs/androidfw/OWNERS2
-rw-r--r--media/java/android/media/AudioManager.java1
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java8
-rw-r--r--packages/SystemUI/OWNERS7
-rw-r--r--packages/Tethering/common/TetheringLib/Android.bp1
-rw-r--r--packages/Tethering/common/TetheringLib/api/system-current.txt1
-rw-r--r--packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java25
-rw-r--r--packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java15
-rw-r--r--packages/Tethering/src/android/net/ip/IpServer.java32
-rw-r--r--packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java85
-rw-r--r--packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java86
-rw-r--r--packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java1
-rw-r--r--packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java12
-rw-r--r--packages/Tethering/tests/integration/Android.bp42
-rw-r--r--packages/Tethering/tests/integration/AndroidManifest.xml29
-rw-r--r--packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java459
-rw-r--r--packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java8
-rw-r--r--packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringNotificationUpdaterTest.kt262
-rw-r--r--packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java33
-rw-r--r--services/Android.bp12
-rw-r--r--services/core/Android.bp4
-rw-r--r--services/core/java/com/android/server/AppStateTracker.java14
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java302
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java78
-rw-r--r--services/core/java/com/android/server/ExplicitHealthCheckController.java7
-rw-r--r--services/core/java/com/android/server/IpSecService.java57
-rw-r--r--services/core/java/com/android/server/LocationManagerService.java4
-rw-r--r--services/core/java/com/android/server/NativeDaemonConnector.java3
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java3
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java20
-rw-r--r--services/core/java/com/android/server/SystemServerInitThreadPool.java1
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java57
-rw-r--r--services/core/java/com/android/server/Watchdog.java1
-rw-r--r--services/core/java/com/android/server/accounts/TokenCache.java2
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java3
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java1
-rw-r--r--services/core/java/com/android/server/connectivity/KeepaliveTracker.java10
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkNotificationManager.java12
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java51
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java45
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java93
-rw-r--r--services/core/java/com/android/server/wm/OWNERS1
-rw-r--r--services/java/com/android/server/SystemServer.java2
-rw-r--r--services/net/java/android/net/TcpKeepalivePacketData.java38
-rw-r--r--services/net/java/android/net/util/KeepalivePacketDataUtil.java13
-rwxr-xr-xtelecomm/java/android/telecom/Call.java11
-rw-r--r--telecomm/java/android/telecom/ParcelableCallAnalytics.java23
-rw-r--r--telecomm/java/android/telecom/PhoneAccount.java6
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java58
-rw-r--r--telephony/common/com/android/internal/telephony/CarrierAppUtils.java3
-rw-r--r--telephony/common/com/android/internal/telephony/GsmAlphabet.java10
-rw-r--r--telephony/common/com/google/android/mms/util/SqliteWrapper.java3
-rw-r--r--telephony/java/android/service/carrier/CarrierService.java8
-rw-r--r--telephony/java/android/telephony/Annotation.java42
-rw-r--r--telephony/java/android/telephony/CallForwardingInfo.java57
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java9
-rw-r--r--telephony/java/android/telephony/CellIdentityLte.java44
-rw-r--r--telephony/java/android/telephony/CellIdentityNr.java35
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthCdma.java2
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthGsm.java2
-rw-r--r--telephony/java/android/telephony/DataSpecificRegistrationInfo.java1
-rw-r--r--telephony/java/android/telephony/ImsManager.java20
-rw-r--r--telephony/java/android/telephony/NetworkRegistrationInfo.java3
-rw-r--r--telephony/java/android/telephony/PreciseDataConnectionState.java1
-rw-r--r--telephony/java/android/telephony/RadioAccessFamily.java48
-rw-r--r--telephony/java/android/telephony/ServiceState.java1
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java176
-rw-r--r--telephony/java/android/telephony/ims/ImsCallProfile.java12
-rw-r--r--telephony/java/android/telephony/ims/ImsCallSessionListener.java80
-rw-r--r--telephony/java/android/telephony/ims/ImsException.java9
-rw-r--r--telephony/java/android/telephony/ims/ImsMmTelManager.java5
-rw-r--r--telephony/java/android/telephony/ims/ImsRcsManager.java38
-rw-r--r--telephony/java/android/telephony/ims/ImsUtListener.java8
-rw-r--r--telephony/java/android/telephony/ims/ProvisioningManager.java26
-rw-r--r--telephony/java/android/telephony/ims/RcsUceAdapter.java24
-rw-r--r--telephony/java/android/telephony/ims/RegistrationManager.java6
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl5
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java7
-rw-r--r--telephony/java/com/android/ims/ImsConfig.java5
-rw-r--r--tests/net/common/java/android/net/LinkPropertiesTest.java70
-rw-r--r--tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt50
-rw-r--r--tests/net/common/java/android/net/NetworkCapabilitiesTest.java12
-rw-r--r--tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java37
-rw-r--r--tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt2
-rw-r--r--tests/net/java/android/net/TcpKeepalivePacketDataTest.java8
-rw-r--r--tests/net/java/com/android/server/IpSecServiceParameterizedTest.java6
-rw-r--r--tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java4
-rw-r--r--tests/net/java/com/android/server/IpSecServiceTest.java11
130 files changed, 3339 insertions, 1197 deletions
diff --git a/Android.bp b/Android.bp
index 8c2d236ec076..c9ae9bad7deb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -524,42 +524,9 @@ java_library {
],
}
-java_library {
- name: "framework-annotation-proc",
- defaults: ["framework-defaults"],
- srcs: [":framework-all-sources"],
- libs: [
- "app-compat-annotations",
- "unsupportedappusage",
- ],
- installable: false,
- plugins: [
- "compat-changeid-annotation-processor",
- ],
-}
-
platform_compat_config {
- name: "framework-platform-compat-config",
- src: ":framework-annotation-proc",
-}
-
-// A library including just UnsupportedAppUsage.java classes.
-//
-// Provided for target so that libraries can use it without depending on
-// the whole of framework or the core platform API.
-//
-// Built for host so that the annotation processor can also use this annotation.
-java_library {
- name: "unsupportedappusage-annotation",
- host_supported: true,
- srcs: [
- "core/java/android/annotation/IntDef.java",
- ],
- static_libs: [
- "art.module.api.annotations",
- ],
-
- sdk_version: "core_current",
+ name: "framework-platform-compat-config",
+ src: ":framework-minus-apex",
}
// A temporary build target that is conditionally included on the bootclasspath if
@@ -646,6 +613,7 @@ filegroup {
srcs: [
"core/java/android/annotation/StringDef.java",
"core/java/android/net/annotations/PolicyDirection.java",
+ "core/java/com/android/internal/util/HexDump.java",
"core/java/com/android/internal/util/IState.java",
"core/java/com/android/internal/util/State.java",
"core/java/com/android/internal/util/StateMachine.java",
@@ -1021,16 +989,6 @@ aidl_mapping {
output: "framework-aidl-mappings.txt",
}
-genrule {
- name: "framework-annotation-proc-index",
- srcs: [":framework-annotation-proc"],
- cmd: "unzip -qp $(in) unsupportedappusage/unsupportedappusage_index.csv > $(out)",
- out: ["unsupportedappusage_index.csv"],
- dist: {
- targets: ["droidcore"],
- },
-}
-
filegroup {
name: "framework-cellbroadcast-shared-srcs",
srcs: [
diff --git a/Android.mk b/Android.mk
index 09f2c40e7202..aea0c951052f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -42,6 +42,8 @@ $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE))
$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE):apistubs/android/public/api/android.txt)
$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_API_FILE):apistubs/android/system/api/android.txt)
$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE):apistubs/android/test/api/android.txt)
+$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_MODULE_LIB_API_FILE):apistubs/android/module-lib/api/android.txt)
+$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_SERVER_API_FILE):apistubs/android/system-server/api/android.txt)
# sdk.atree needs to copy the whole dir: $(OUT_DOCS)/offline-sdk to the final zip.
# So keep offline-sdk-timestamp target here, and unzip offline-sdk-docs.zip to
diff --git a/ApiDocs.bp b/ApiDocs.bp
index b7e364690d03..7fd116886e7a 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -65,8 +65,9 @@ stubs_defaults {
"test-base/src/**/*.java",
":opt-telephony-srcs",
":opt-net-voip-srcs",
- ":core-current-stubs-source",
- ":core_public_api_files",
+ ":art-module-public-api-stubs-source",
+ ":conscrypt-module-public-api-stubs-source",
+ ":android_icu4j_public_api_files",
"test-mock/src/**/*.java",
"test-runner/src/**/*.java",
],
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 9a52cf69ef3d..f0810713f39f 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -47,8 +47,9 @@ stubs_defaults {
"core/java/**/*.logtags",
":opt-telephony-srcs",
":opt-net-voip-srcs",
- ":core-current-stubs-source",
- ":core_public_api_files",
+ ":art-module-public-api-stubs-source",
+ ":conscrypt-module-public-api-stubs-source",
+ ":android_icu4j_public_api_files",
],
libs: ["framework-internal-utils"],
installable: false,
@@ -187,6 +188,7 @@ droidstubs {
droidstubs {
name: "module-lib-api",
defaults: ["metalava-full-api-stubs-default"],
+ api_tag_name: "MODULE_LIB",
arg_files: ["core/res/AndroidManifest.xml"],
args: metalava_framework_docs_args + module_libs,
check_api: {
@@ -227,16 +229,18 @@ droidstubs {
java_defaults {
name: "framework-stubs-default",
libs: [ "stub-annotations" ],
- static_libs: [ "private-stub-annotations-jar" ],
+ static_libs: [
+ "private-stub-annotations-jar",
+
+ // License notices from art module
+ "art-notices-for-framework-stubs-jar",
+ ],
sdk_version: "core_current",
errorprone: {
javacflags: [
"-XepDisableAllChecks",
],
},
- java_resources: [
- ":notices-for-framework-stubs",
- ],
system_modules: "none",
java_version: "1.8",
compile_dex: true,
diff --git a/apex/Android.bp b/apex/Android.bp
index 19439401a7fb..a6461f39d553 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -66,6 +66,24 @@ stubs_defaults {
},
}
+java_defaults {
+ name: "framework-module-stubs-lib-defaults-publicapi",
+ installable: false,
+ sdk_version: "module_current",
+}
+
+java_defaults {
+ name: "framework-module-stubs-lib-defaults-systemapi",
+ installable: false,
+ sdk_version: "module_current",
+}
+
+java_defaults {
+ name: "framework-module-stubs-lib-defaults-module_libs_api",
+ installable: false,
+ sdk_version: "module_current",
+}
+
// The defaults for module_libs comes in two parts - defaults for API checks
// and defaults for stub generation. This is because we want the API txt
// files to *only* include the module_libs_api, but the stubs to include
diff --git a/apex/sdkextensions/framework/Android.bp b/apex/sdkextensions/framework/Android.bp
index 86f4ab7c1128..707113b9672c 100644
--- a/apex/sdkextensions/framework/Android.bp
+++ b/apex/sdkextensions/framework/Android.bp
@@ -86,7 +86,7 @@ droidstubs {
java_library {
name: "framework-sdkextensions-stubs-publicapi",
srcs: [":framework-sdkextensions-stubs-srcs-publicapi"],
- sdk_version: "current",
+ defaults: ["framework-module-stubs-lib-defaults-publicapi"],
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/sdkextensions", // sdkextensions SDK
@@ -96,7 +96,7 @@ java_library {
java_library {
name: "framework-sdkextensions-stubs-systemapi",
srcs: [":framework-sdkextensions-stubs-srcs-systemapi"],
- sdk_version: "system_current",
+ defaults: ["framework-module-stubs-lib-defaults-systemapi"],
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/sdkextensions", // sdkextensions SDK
@@ -106,7 +106,7 @@ java_library {
java_library {
name: "framework-sdkextensions-stubs-module_libs_api",
srcs: [":framework-sdkextensions-stubs-srcs-module_libs_api"],
- sdk_version: "system_current",
+ defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/sdkextensions", // sdkextensions SDK
diff --git a/api/current.txt b/api/current.txt
index 4b2323ee966d..a5b88b381e79 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11405,7 +11405,8 @@ package android.content.pm {
public class PackageInstaller {
method public void abandonSession(int);
method public int createSession(@NonNull android.content.pm.PackageInstaller.SessionParams) throws java.io.IOException;
- method @Nullable public android.content.pm.PackageInstaller.SessionInfo getActiveStagedSession();
+ method @Deprecated @Nullable public android.content.pm.PackageInstaller.SessionInfo getActiveStagedSession();
+ method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getActiveStagedSessions();
method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllSessions();
method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getMySessions();
method @Nullable public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int);
@@ -11490,11 +11491,13 @@ package android.content.pm {
method @NonNull public String getStagedSessionErrorMessage();
method public long getUpdatedMillis();
method @NonNull public android.os.UserHandle getUser();
+ method public boolean hasParentSessionId();
method public boolean isActive();
method public boolean isCommitted();
method public boolean isMultiPackage();
method public boolean isSealed();
method public boolean isStaged();
+ method public boolean isStagedSessionActive();
method public boolean isStagedSessionApplied();
method public boolean isStagedSessionFailed();
method public boolean isStagedSessionReady();
@@ -29143,9 +29146,6 @@ package android.net {
public final class NetworkCapabilities implements android.os.Parcelable {
ctor public NetworkCapabilities();
ctor public NetworkCapabilities(android.net.NetworkCapabilities);
- method @NonNull public android.net.NetworkCapabilities addCapability(int);
- method @NonNull public android.net.NetworkCapabilities addTransportType(int);
- method public void clearAll();
method public int describeContents();
method public int getLinkDownstreamBandwidthKbps();
method public int getLinkUpstreamBandwidthKbps();
@@ -29155,13 +29155,6 @@ package android.net {
method @Nullable public android.net.TransportInfo getTransportInfo();
method public boolean hasCapability(int);
method public boolean hasTransport(int);
- method @NonNull public android.net.NetworkCapabilities removeCapability(int);
- method @NonNull public android.net.NetworkCapabilities setCapability(int, boolean);
- method @NonNull public android.net.NetworkCapabilities setLinkDownstreamBandwidthKbps(int);
- method @NonNull public android.net.NetworkCapabilities setLinkUpstreamBandwidthKbps(int);
- method @NonNull public android.net.NetworkCapabilities setNetworkSpecifier(@NonNull android.net.NetworkSpecifier);
- method @NonNull public android.net.NetworkCapabilities setOwnerUid(int);
- method @NonNull public android.net.NetworkCapabilities setSignalStrength(int);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11
@@ -44724,12 +44717,9 @@ package android.telephony {
field public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
field public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
field public static final String IMSI_KEY_AVAILABILITY_INT = "imsi_key_availability_int";
- field public static final String KEY_5G_ICON_CONFIGURATION_STRING = "5g_icon_configuration_string";
- field public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT = "5g_icon_display_grace_period_sec_int";
field public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrp_thresholds_int_array";
field public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrq_thresholds_int_array";
field public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY = "5g_nr_sssinr_thresholds_int_array";
- field public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = "5g_watchdog_time_long";
field public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
field public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
field public static final String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -44922,7 +44912,6 @@ package android.telephony {
field public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
field public static final String KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL = "show_blocking_pay_phone_option_bool";
field public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool";
- field public static final String KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING = "show_carrier_data_icon_pattern_string";
field public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
field public static final String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool";
field public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL = "show_ims_registration_status_bool";
@@ -45014,7 +45003,7 @@ package android.telephony {
public final class CellIdentityLte extends android.telephony.CellIdentity {
method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
- method @NonNull public java.util.List<java.lang.Integer> getBands();
+ method @NonNull public int[] getBands();
method public int getBandwidth();
method public int getCi();
method @Nullable public android.telephony.ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo();
@@ -45032,7 +45021,7 @@ package android.telephony {
public final class CellIdentityNr extends android.telephony.CellIdentity {
method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
- method @NonNull public java.util.List<java.lang.Integer> getBands();
+ method @NonNull public int[] getBands();
method @Nullable public String getMccString();
method @Nullable public String getMncString();
method public long getNci();
@@ -45347,7 +45336,6 @@ package android.telephony {
method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
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();
@@ -45874,7 +45862,7 @@ package android.telephony {
method public long getDataLimitBytes();
method public long getDataUsageBytes();
method public long getDataUsageTime();
- method @Nullable public int[] getNetworkTypes();
+ method @NonNull public int[] getNetworkTypes();
method @Nullable public CharSequence getSummary();
method @Nullable public CharSequence getTitle();
method public void writeToParcel(android.os.Parcel, int);
@@ -45894,7 +45882,7 @@ package android.telephony {
method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
- method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@Nullable int[]);
+ method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@NonNull int[]);
method public android.telephony.SubscriptionPlan.Builder setSummary(@Nullable CharSequence);
method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence);
}
@@ -46000,6 +45988,7 @@ package android.telephony {
method public boolean setLine1NumberForDisplay(String, String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setNetworkSelectionModeAutomatic();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(String, boolean);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(@NonNull String, boolean, int);
method public boolean setOperatorBrandOverride(String);
method public boolean setPreferredNetworkTypeToGlobal();
method public void setPreferredOpportunisticDataSubscription(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
@@ -46527,6 +46516,7 @@ package android.telephony.ims {
public class ImsManager {
method @NonNull public android.telephony.ims.ImsMmTelManager getImsMmTelManager(int);
+ method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int);
field public static final String ACTION_WFC_IMS_REGISTRATION_ERROR = "android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR";
field public static final String EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE = "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_MESSAGE";
field public static final String EXTRA_WFC_REGISTRATION_FAILURE_TITLE = "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_TITLE";
@@ -46555,6 +46545,15 @@ package android.telephony.ims {
method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
}
+ public class ImsRcsManager implements android.telephony.ims.RegistrationManager {
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter();
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
+ field public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN = "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
+ }
+
public final class ImsReasonInfo implements android.os.Parcelable {
ctor public ImsReasonInfo(int, int, @Nullable String);
method public int describeContents();
@@ -46738,6 +46737,10 @@ package android.telephony.ims {
field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2
}
+ public class RcsUceAdapter {
+ method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException;
+ }
+
public interface RegistrationManager {
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
@@ -46752,8 +46755,8 @@ package android.telephony.ims {
ctor public RegistrationManager.RegistrationCallback();
method public void onRegistered(int);
method public void onRegistering(int);
- method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
- method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
+ method public void onTechnologyChangeFailed(int, @NonNull android.telephony.ims.ImsReasonInfo);
+ method public void onUnregistered(@NonNull android.telephony.ims.ImsReasonInfo);
}
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 9144b3d97fd1..6ab5b1ed25e2 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -229,9 +229,6 @@ package android {
public static final class R.array {
field public static final int config_keySystemUuidMapping = 17235973; // 0x1070005
- field public static final int config_restrictedPreinstalledCarrierApps = 17235975; // 0x1070007
- field public static final int config_sms_enabled_locking_shift_tables = 17235977; // 0x1070009
- field public static final int config_sms_enabled_single_shift_tables = 17235976; // 0x1070008
field public static final int simColors = 17235974; // 0x1070006
}
@@ -279,7 +276,6 @@ package android {
field public static final int config_helpIntentNameKey = 17039390; // 0x104001e
field public static final int config_helpPackageNameKey = 17039387; // 0x104001b
field public static final int config_helpPackageNameValue = 17039388; // 0x104001c
- field public static final int low_memory = 17039397; // 0x1040025
}
public static final class R.style {
@@ -324,7 +320,6 @@ package android.app {
method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public static void setPersistentVrThread(int);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean switchUser(@NonNull android.os.UserHandle);
method public void unregisterHomeVisibilityObserver(@NonNull android.app.HomeVisibilityObserver);
- method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
}
public static interface ActivityManager.OnUidImportanceListener {
@@ -1542,7 +1537,6 @@ package android.content {
field public static final String EUICC_CARD_SERVICE = "euicc_card";
field public static final String HDMI_CONTROL_SERVICE = "hdmi_control";
field public static final String NETD_SERVICE = "netd";
- field public static final String NETWORK_POLICY_SERVICE = "netpolicy";
field public static final String NETWORK_SCORE_SERVICE = "network_score";
field public static final String OEM_LOCK_SERVICE = "oem_lock";
field public static final String PERMISSION_SERVICE = "permission";
@@ -4405,10 +4399,10 @@ package android.net {
public class InvalidPacketException extends java.lang.Exception {
ctor public InvalidPacketException(int);
+ method public int getError();
field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
- field public final int error;
}
public final class IpConfiguration implements android.os.Parcelable {
@@ -4462,12 +4456,12 @@ package android.net {
}
public class KeepalivePacketData {
- ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[]) throws android.net.InvalidPacketException;
+ ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull byte[]) throws android.net.InvalidPacketException;
+ method @NonNull public java.net.InetAddress getDstAddress();
+ method public int getDstPort();
method @NonNull public byte[] getPacket();
- field @NonNull public final java.net.InetAddress dstAddress;
- field public final int dstPort;
- field @NonNull public final java.net.InetAddress srcAddress;
- field public final int srcPort;
+ method @NonNull public java.net.InetAddress getSrcAddress();
+ method public int getSrcPort();
}
public class LinkAddress implements android.os.Parcelable {
@@ -4540,8 +4534,8 @@ package android.net {
public class Network implements android.os.Parcelable {
ctor public Network(@NonNull android.net.Network);
+ method public int getNetId();
method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
- field public final int netId;
}
public abstract class NetworkAgent {
@@ -4590,18 +4584,33 @@ package android.net {
public final class NetworkCapabilities implements android.os.Parcelable {
method @NonNull public int[] getAdministratorUids();
- method @Nullable public String getSSID();
+ method @Nullable public String getSsid();
method @NonNull public int[] getTransportTypes();
method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
- method @NonNull public android.net.NetworkCapabilities setAdministratorUids(@NonNull int[]);
- method @NonNull public android.net.NetworkCapabilities setRequestorPackageName(@NonNull String);
- method @NonNull public android.net.NetworkCapabilities setRequestorUid(int);
- method @NonNull public android.net.NetworkCapabilities setSSID(@Nullable String);
- method @NonNull public android.net.NetworkCapabilities setTransportInfo(@NonNull android.net.TransportInfo);
field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18
}
+ public static class NetworkCapabilities.Builder {
+ ctor public NetworkCapabilities.Builder();
+ ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
+ method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
+ method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
+ method @NonNull public android.net.NetworkCapabilities build();
+ method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
+ method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
+ method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
+ method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int);
+ method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setOwnerUid(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
+ method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
+ }
+
public class NetworkKey implements android.os.Parcelable {
ctor public NetworkKey(android.net.WifiKey);
method @Nullable public static android.net.NetworkKey createFromScanResult(@Nullable android.net.wifi.ScanResult);
@@ -4795,7 +4804,6 @@ package android.net {
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
@@ -8014,27 +8022,6 @@ package android.telephony {
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
}
- public final class CallForwardingInfo implements android.os.Parcelable {
- ctor public CallForwardingInfo(int, int, @Nullable String, int);
- method public int describeContents();
- method @Nullable public String getNumber();
- method public int getReason();
- method public int getStatus();
- method public int getTimeoutSeconds();
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallForwardingInfo> CREATOR;
- field public static final int REASON_ALL = 4; // 0x4
- field public static final int REASON_ALL_CONDITIONAL = 5; // 0x5
- field public static final int REASON_BUSY = 1; // 0x1
- field public static final int REASON_NOT_REACHABLE = 3; // 0x3
- field public static final int REASON_NO_REPLY = 2; // 0x2
- field public static final int REASON_UNCONDITIONAL = 0; // 0x0
- field public static final int STATUS_ACTIVE = 1; // 0x1
- field public static final int STATUS_FDN_CHECK_FAILURE = 2; // 0x2
- field public static final int STATUS_INACTIVE = 0; // 0x0
- field public static final int STATUS_NOT_SUPPORTED = 4; // 0x4
- field public static final int STATUS_UNKNOWN_ERROR = 3; // 0x3
- }
-
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);
@@ -8522,7 +8509,6 @@ package android.telephony {
public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
- method public boolean isUsingCarrierAggregation();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
}
@@ -8744,7 +8730,6 @@ package android.telephony {
method public void onRadioPowerStateChanged(int);
method public void onSrvccStateChanged(int);
method public void onVoiceActivationStateChanged(int);
- field @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH = 512; // 0x200
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
@@ -8775,7 +8760,6 @@ package android.telephony {
}
public final class PreciseDataConnectionState implements android.os.Parcelable {
- ctor public PreciseDataConnectionState(int, int, int, @NonNull String, @Nullable android.net.LinkProperties, int, @Nullable android.telephony.data.ApnSetting);
method @Deprecated @NonNull public String getDataConnectionApn();
method @Deprecated public int getDataConnectionApnTypeBitMask();
method @Deprecated public int getDataConnectionFailCause();
@@ -8888,7 +8872,6 @@ package android.telephony {
method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
- method public int getNrFrequencyRange();
method @Nullable public String getOperatorAlphaLongRaw();
method @Nullable public String getOperatorAlphaShortRaw();
method @NonNull public static android.telephony.ServiceState newFromBundle(@NonNull android.os.Bundle);
@@ -9120,8 +9103,6 @@ package android.telephony {
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes();
- method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CallForwardingInfo getCallForwarding(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCallWaitingStatus();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -9204,15 +9185,12 @@ package android.telephony {
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAlwaysAllowMmsData(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallForwarding(@NonNull android.telephony.CallForwardingInfo);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallWaitingStatus(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(@NonNull String, int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
@@ -9246,10 +9224,6 @@ package android.telephony {
field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
- field public static final int CALL_WAITING_STATUS_ACTIVE = 1; // 0x1
- field public static final int CALL_WAITING_STATUS_INACTIVE = 2; // 0x2
- field public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; // 0x4
- field public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; // 0x3
field public static final int CARD_POWER_DOWN = 0; // 0x0
field public static final int CARD_POWER_UP = 1; // 0x1
field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2
@@ -9716,7 +9690,7 @@ package android.telephony.ims {
method public int getEmergencyServiceCategories();
method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
- method @Nullable public android.os.Bundle getProprietaryCallExtras();
+ method @NonNull public android.os.Bundle getProprietaryCallExtras();
method public int getRestrictCause();
method public int getServiceType();
method public static int getVideoStateFromCallType(int);
@@ -9877,7 +9851,6 @@ package android.telephony.ims {
}
public class ImsManager {
- method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int);
field public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION";
}
@@ -9905,10 +9878,6 @@ package android.telephony.ims {
ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
}
- public class ImsRcsManager implements android.telephony.ims.RegistrationManager {
- method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter();
- }
-
public final class ImsReasonInfo implements android.os.Parcelable {
field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service";
}
@@ -10177,8 +10146,8 @@ package android.telephony.ims {
field public static final int KEY_RCS_CAPABILITY_DISCOVERY_ENABLED = 17; // 0x11
field public static final int KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC = 23; // 0x17
field public static final int KEY_RCS_MAX_NUM_ENTRIES_IN_RCL = 22; // 0x16
+ field public static final int KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC = 16; // 0x10
field public static final int KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS = 21; // 0x15
- field public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16; // 0x10
field public static final int KEY_RCS_PUBLISH_TIMER_SEC = 15; // 0xf
field public static final int KEY_REGISTRATION_DOMAIN_NAME = 12; // 0xc
field public static final int KEY_REGISTRATION_RETRY_BASE_TIME_SEC = 33; // 0x21
@@ -10285,7 +10254,6 @@ package android.telephony.ims {
}
public class RcsUceAdapter {
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
}
diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt
index d2b3a6446346..306b8afaadae 100644
--- a/api/system-lint-baseline.txt
+++ b/api/system-lint-baseline.txt
@@ -165,12 +165,6 @@ PublicTypedef: android.content.integrity.Formula.Tag: Don't expose @IntDef: @Tag
PublicTypedef: android.content.integrity.Rule.Effect: Don't expose @IntDef: @Effect must be hidden.
-ResourceValueFieldName: android.R.array#config_sms_enabled_locking_shift_tables:
- Expected resource name in `android.R.array` to be in the `fooBarBaz` style, was `config_sms_enabled_locking_shift_tables`
-ResourceValueFieldName: android.R.array#config_sms_enabled_single_shift_tables:
- Expected resource name in `android.R.array` to be in the `fooBarBaz` style, was `config_sms_enabled_single_shift_tables`
-
-
SamShouldBeLast: android.accounts.AccountManager#addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
SamShouldBeLast: android.accounts.AccountManager#addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean):
diff --git a/api/test-current.txt b/api/test-current.txt
index 697b7e8f8a9d..9ed451c2f47e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -62,7 +62,6 @@ package android.app {
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
method public static void resumeAppSwitches() throws android.os.RemoteException;
method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
- method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
}
public static interface ActivityManager.OnUidImportanceListener {
@@ -1507,16 +1506,39 @@ package android.net {
public class Network implements android.os.Parcelable {
ctor public Network(@NonNull android.net.Network);
+ method public int getNetId();
method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
}
public final class NetworkCapabilities implements android.os.Parcelable {
+ method @NonNull public int[] getAdministratorUids();
method public int[] getCapabilities();
+ method @Nullable public String getSsid();
method @NonNull public int[] getTransportTypes();
method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
field public static final int TRANSPORT_TEST = 7; // 0x7
}
+ public static class NetworkCapabilities.Builder {
+ ctor public NetworkCapabilities.Builder();
+ ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
+ method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
+ method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
+ method @NonNull public android.net.NetworkCapabilities build();
+ method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
+ method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
+ method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
+ method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
+ method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int);
+ method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier);
+ method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setOwnerUid(int);
+ method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String);
+ method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setRequestorUid(int);
+ method @NonNull @RequiresPermission("android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP") public android.net.NetworkCapabilities.Builder setSignalStrength(int);
+ method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
+ method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
+ }
+
public class NetworkStack {
method @Nullable public static android.os.IBinder getService();
method public static void setServiceForTest(@Nullable android.os.IBinder);
@@ -1593,7 +1615,6 @@ package android.net {
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
- method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
@@ -3328,7 +3349,7 @@ package android.telephony.ims {
method public int getEmergencyServiceCategories();
method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
- method @Nullable public android.os.Bundle getProprietaryCallExtras();
+ method @NonNull public android.os.Bundle getProprietaryCallExtras();
method public int getRestrictCause();
method public int getServiceType();
method public static int getVideoStateFromCallType(int);
@@ -3490,7 +3511,6 @@ package android.telephony.ims {
}
public class ImsManager {
- method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int);
field public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION";
}
@@ -3518,10 +3538,6 @@ package android.telephony.ims {
ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
}
- public class ImsRcsManager implements android.telephony.ims.RegistrationManager {
- method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter();
- }
-
public class ImsService extends android.app.Service {
ctor public ImsService();
method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
@@ -3786,8 +3802,8 @@ package android.telephony.ims {
field public static final int KEY_RCS_CAPABILITY_DISCOVERY_ENABLED = 17; // 0x11
field public static final int KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC = 23; // 0x17
field public static final int KEY_RCS_MAX_NUM_ENTRIES_IN_RCL = 22; // 0x16
+ field public static final int KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC = 16; // 0x10
field public static final int KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS = 21; // 0x15
- field public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16; // 0x10
field public static final int KEY_RCS_PUBLISH_TIMER_SEC = 15; // 0xf
field public static final int KEY_REGISTRATION_DOMAIN_NAME = 12; // 0xc
field public static final int KEY_REGISTRATION_RETRY_BASE_TIME_SEC = 33; // 0x21
@@ -3894,7 +3910,6 @@ package android.telephony.ims {
}
public class RcsUceAdapter {
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
}
diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp
index bb8d92737563..f482191b09a8 100644
--- a/cmds/idmap2/idmap2/Create.cpp
+++ b/cmds/idmap2/idmap2/Create.cpp
@@ -50,7 +50,7 @@ Result<Unit> Create(const std::vector<std::string>& args) {
std::string overlay_apk_path;
std::string idmap_path;
std::vector<std::string> policies;
- bool ignore_overlayable;
+ bool ignore_overlayable = false;
const CommandLineOptions opts =
CommandLineOptions("idmap2 create")
diff --git a/cmds/idmap2/idmap2/Dump.cpp b/cmds/idmap2/idmap2/Dump.cpp
index 8716bf313ed0..47f442aab235 100644
--- a/cmds/idmap2/idmap2/Dump.cpp
+++ b/cmds/idmap2/idmap2/Dump.cpp
@@ -39,7 +39,7 @@ using android::idmap2::Unit;
Result<Unit> Dump(const std::vector<std::string>& args) {
SYSTRACE << "Dump " << args;
std::string idmap_path;
- bool verbose;
+ bool verbose = false;
const CommandLineOptions opts =
CommandLineOptions("idmap2 dump")
diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
index 8a48f4b8e6d5..499eb99af290 100644
--- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp
+++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
@@ -131,7 +131,6 @@ TEST_F(Idmap2BinaryTests, Dump) {
ASSERT_NE(result->stdout.find("0x7f02000c -> 0x7f020000 string/str1"), std::string::npos);
ASSERT_NE(result->stdout.find("0x7f02000e -> 0x7f020001 string/str3"), std::string::npos);
ASSERT_NE(result->stdout.find("0x7f02000f -> 0x7f020002 string/str4"), std::string::npos);
- ASSERT_EQ(result->stdout.find("00000210: 007f target package id"), std::string::npos);
// clang-format off
result = ExecuteBinary({"idmap2",
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index f476fcf91bd5..1cc761fa359f 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -512,8 +512,8 @@ status_t LogSection::BlockingCall(int pipeWriteFd) const {
// Open log buffer and getting logs since last retrieved time if any.
unique_ptr<logger_list, void (*)(logger_list*)> loggers(
gLastLogsRetrieved.find(mLogID) == gLastLogsRetrieved.end()
- ? android_logger_list_alloc(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, 0)
- : android_logger_list_alloc_time(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
+ ? android_logger_list_alloc(ANDROID_LOG_NONBLOCK, 0, 0)
+ : android_logger_list_alloc_time(ANDROID_LOG_NONBLOCK,
gLastLogsRetrieved[mLogID], 0),
android_logger_list_free);
diff --git a/config/preloaded-classes b/config/preloaded-classes
index eb3879fdb50e..b05d02c9eb15 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -7438,6 +7438,7 @@ sun.nio.fs.LinuxFileSystemProvider
sun.nio.fs.NativeBuffer$Deallocator
sun.nio.fs.NativeBuffer
sun.nio.fs.NativeBuffers
+sun.nio.fs.UnixChannelFactory
sun.nio.fs.UnixChannelFactory$Flags
sun.nio.fs.UnixConstants
sun.nio.fs.UnixException
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 1e50077e1dc9..9d63bc2ef85a 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -3880,8 +3880,6 @@ public class ActivityManager {
* {@code false} otherwise.
* @hide
*/
- @SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION)
public boolean updateMccMncConfiguration(@NonNull String mcc, @NonNull String mnc) {
if (mcc == null || mnc == null) {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 2a72d43eccad..71b2773cf3ec 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -797,6 +797,11 @@ public final class LoadedApk {
makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
String libraryPermittedPath = mDataDir;
+ if (mActivityThread == null) {
+ // In a zygote context where mActivityThread is null we can't access the app data dir
+ // and including this in libraryPermittedPath would cause SELinux denials.
+ libraryPermittedPath = "";
+ }
if (isBundledApp) {
// For bundled apps, add the base directory of the app (e.g.,
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index e6b90d87a59f..1508a657cf4a 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -916,23 +916,11 @@ public final class BluetoothAdapter {
if (!isBleScanAlwaysAvailable()) {
return false;
}
-
- int state = getLeState();
- if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON) {
- String packageName = ActivityThread.currentPackageName();
- if (DBG) {
- Log.d(TAG, "disableBLE(): de-registering " + packageName);
- }
- try {
- mManagerService.updateBleAppCount(mToken, false, packageName);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- return true;
- }
-
- if (DBG) {
- Log.d(TAG, "disableBLE(): Already disabled");
+ String packageName = ActivityThread.currentPackageName();
+ try {
+ return mManagerService.disableBle(packageName, mToken);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
}
return false;
}
@@ -973,20 +961,9 @@ public final class BluetoothAdapter {
if (!isBleScanAlwaysAvailable()) {
return false;
}
-
+ String packageName = ActivityThread.currentPackageName();
try {
- String packageName = ActivityThread.currentPackageName();
- mManagerService.updateBleAppCount(mToken, true, packageName);
- if (isLeEnabled()) {
- if (DBG) {
- Log.d(TAG, "enableBLE(): Bluetooth already enabled");
- }
- return true;
- }
- if (DBG) {
- Log.d(TAG, "enableBLE(): Calling enable");
- }
- return mManagerService.enable(packageName);
+ return mManagerService.enableBle(packageName, mToken);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index e0674d75974a..fa62a02499e0 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -379,6 +379,7 @@ public final class BluetoothHearingAid implements BluetoothProfile {
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
@ConnectionPolicy int connectionPolicy) {
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
+ verifyDeviceNotNull(device, "setConnectionPolicy");
final IBluetoothHearingAid service = getService();
try {
if (service != null && isEnabled()
@@ -428,6 +429,7 @@ public final class BluetoothHearingAid implements BluetoothProfile {
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
if (VDBG) log("getConnectionPolicy(" + device + ")");
+ verifyDeviceNotNull(device, "getConnectionPolicy");
final IBluetoothHearingAid service = getService();
try {
if (service != null && isEnabled()
@@ -504,6 +506,7 @@ public final class BluetoothHearingAid implements BluetoothProfile {
if (VDBG) {
log("getHiSyncId(" + device + ")");
}
+ verifyDeviceNotNull(device, "getConnectionPolicy");
final IBluetoothHearingAid service = getService();
try {
if (service == null) {
@@ -577,6 +580,13 @@ public final class BluetoothHearingAid implements BluetoothProfile {
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/Context.java b/core/java/android/content/Context.java
index 2f621c3cd1f6..b79965eb4c21 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3945,8 +3945,6 @@ public abstract class Context {
*/
public static final String NETWORK_STATS_SERVICE = "netstats";
/** {@hide} */
- @SystemApi
- @SuppressLint("ServiceName")
public static final String NETWORK_POLICY_SERVICE = "netpolicy";
/** {@hide} */
public static final String NETWORK_WATCHLIST_SERVICE = "network_watchlist";
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 2217807254e9..2914e4c2c2ff 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -68,6 +68,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
/**
* Offers the ability to install, upgrade, and remove applications on the
@@ -486,35 +487,30 @@ public class PackageInstaller {
}
/**
- * Returns an active staged session, or {@code null} if there is none.
+ * Returns first active staged session, or {@code null} if there is none.
*
- * <p>Staged session is active iff:
- * <ul>
- * <li>It is committed, i.e. {@link SessionInfo#isCommitted()} is {@code true}, and
- * <li>it is not applied, i.e. {@link SessionInfo#isStagedSessionApplied()} is {@code
- * false}, and
- * <li>it is not failed, i.e. {@link SessionInfo#isStagedSessionFailed()} is {@code false}.
- * </ul>
+ * <p>For more information on what sessions are considered active see
+ * {@link SessionInfo#isStagedSessionActive()}.
*
- * <p>In case of a multi-apk session, reasoning above is applied to the parent session, since
- * that is the one that should been {@link Session#commit committed}.
+ * @deprecated Use {@link #getActiveStagedSessions} as there can be more than one active staged
+ * session
*/
+ @Deprecated
public @Nullable SessionInfo getActiveStagedSession() {
- final List<SessionInfo> stagedSessions = getStagedSessions();
- for (SessionInfo s : stagedSessions) {
- if (s.isStagedSessionApplied() || s.isStagedSessionFailed()) {
- // Finalized session.
- continue;
- }
- if (s.getParentSessionId() != SessionInfo.INVALID_ID) {
- // Child session.
- continue;
- }
- if (s.isCommitted()) {
- return s;
- }
- }
- return null;
+ List<SessionInfo> activeSessions = getActiveStagedSessions();
+ return activeSessions.isEmpty() ? null : activeSessions.get(0);
+ }
+
+ /**
+ * Returns list of active staged sessions. Returns empty list if there is none.
+ *
+ * <p>For more information on what sessions are considered active see
+ * * {@link SessionInfo#isStagedSessionActive()}.
+ */
+ public @NonNull List<SessionInfo> getActiveStagedSessions() {
+ return getStagedSessions().stream()
+ .filter(s -> s.isStagedSessionActive())
+ .collect(Collectors.toList());
}
/**
@@ -2234,13 +2230,36 @@ public class PackageInstaller {
}
/**
- * Returns true if this session is a staged session which will be applied at next reboot.
+ * Returns true if this session is a staged session.
*/
public boolean isStaged() {
return isStaged;
}
/**
+ * Returns {@code true} if this session is an active staged session.
+ *
+ * We consider a session active if it has been committed and it is either pending
+ * verification, or will be applied at next reboot.
+ *
+ * <p>Staged session is active iff:
+ * <ul>
+ * <li>It is committed, i.e. {@link SessionInfo#isCommitted()} is {@code true}, and
+ * <li>it is not applied, i.e. {@link SessionInfo#isStagedSessionApplied()} is {@code
+ * false}, and
+ * <li>it is not failed, i.e. {@link SessionInfo#isStagedSessionFailed()} is
+ * {@code false}.
+ * </ul>
+ *
+ * <p>In case of a multi-package session, reasoning above is applied to the parent session,
+ * since that is the one that should have been {@link Session#commit committed}.
+ */
+ public boolean isStagedSessionActive() {
+ return isStaged && isCommitted && !isStagedSessionApplied && !isStagedSessionFailed
+ && !hasParentSessionId();
+ }
+
+ /**
* Returns the parent multi-package session ID if this session belongs to one,
* {@link #INVALID_ID} otherwise.
*/
@@ -2249,6 +2268,13 @@ public class PackageInstaller {
}
/**
+ * Returns true if session has a valid parent session, otherwise false.
+ */
+ public boolean hasParentSessionId() {
+ return parentSessionId != INVALID_ID;
+ }
+
+ /**
* Returns the set of session IDs that will be committed when this session is commited if
* this session is a multi-package session.
*/
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 2db661dc2c96..66f9ac0fb53f 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1424,7 +1424,7 @@ public abstract class PackageManager {
/**
* Installation failed return code: a new staged session was attempted to be committed while
- * there is already one in-progress.
+ * there is already one in-progress or new session has package that is already staged.
*
* @hide
*/
diff --git a/core/java/android/net/InvalidPacketException.java b/core/java/android/net/InvalidPacketException.java
index 909998d4562c..b3b0f11a776b 100644
--- a/core/java/android/net/InvalidPacketException.java
+++ b/core/java/android/net/InvalidPacketException.java
@@ -28,7 +28,7 @@ import java.lang.annotation.RetentionPolicy;
*/
@SystemApi
public class InvalidPacketException extends Exception {
- public final int error;
+ private final int mError;
// Must match SocketKeepalive#ERROR_INVALID_IP_ADDRESS.
/** Invalid IP address. */
@@ -56,6 +56,11 @@ public class InvalidPacketException extends Exception {
* See the error code for details.
*/
public InvalidPacketException(@ErrorCode final int error) {
- this.error = error;
+ this.mError = error;
+ }
+
+ /** Get error code. */
+ public int getError() {
+ return mError;
}
}
diff --git a/core/java/android/net/KeepalivePacketData.java b/core/java/android/net/KeepalivePacketData.java
index 6c0ba2f63a80..e21cb44f72d8 100644
--- a/core/java/android/net/KeepalivePacketData.java
+++ b/core/java/android/net/KeepalivePacketData.java
@@ -19,6 +19,7 @@ package android.net;
import static android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS;
import static android.net.InvalidPacketException.ERROR_INVALID_PORT;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.net.util.IpUtils;
@@ -37,17 +38,17 @@ public class KeepalivePacketData {
/** Source IP address */
@NonNull
- public final InetAddress srcAddress;
+ private final InetAddress mSrcAddress;
/** Destination IP address */
@NonNull
- public final InetAddress dstAddress;
+ private final InetAddress mDstAddress;
/** Source port */
- public final int srcPort;
+ private final int mSrcPort;
/** Destination port */
- public final int dstPort;
+ private final int mDstPort;
/** Packet data. A raw byte string of packet data, not including the link-layer header. */
private final byte[] mPacket;
@@ -60,13 +61,14 @@ public class KeepalivePacketData {
/**
* A holding class for data necessary to build a keepalive packet.
*/
- protected KeepalivePacketData(@NonNull InetAddress srcAddress, int srcPort,
- @NonNull InetAddress dstAddress, int dstPort,
- @NonNull byte[] data) throws InvalidPacketException {
- this.srcAddress = srcAddress;
- this.dstAddress = dstAddress;
- this.srcPort = srcPort;
- this.dstPort = dstPort;
+ protected KeepalivePacketData(@NonNull InetAddress srcAddress,
+ @IntRange(from = 0, to = 65535) int srcPort, @NonNull InetAddress dstAddress,
+ @IntRange(from = 0, to = 65535) int dstPort,
+ @NonNull byte[] data) throws InvalidPacketException {
+ this.mSrcAddress = srcAddress;
+ this.mDstAddress = dstAddress;
+ this.mSrcPort = srcPort;
+ this.mDstPort = dstPort;
this.mPacket = data;
// Check we have two IP addresses of the same family.
@@ -83,6 +85,31 @@ public class KeepalivePacketData {
}
}
+ /** Get source IP address. */
+ @NonNull
+ public InetAddress getSrcAddress() {
+ return mSrcAddress;
+ }
+
+ /** Get destination IP address. */
+ @NonNull
+ public InetAddress getDstAddress() {
+ return mDstAddress;
+ }
+
+ /** Get source port number. */
+ public int getSrcPort() {
+ return mSrcPort;
+ }
+
+ /** Get destination port number. */
+ public int getDstPort() {
+ return mDstPort;
+ }
+
+ /**
+ * Returns a byte array of the given packet data.
+ */
@NonNull
public byte[] getPacket() {
return mPacket.clone();
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 2c356e43d9fe..7ff954bdc1d2 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -690,9 +690,9 @@ public final class LinkProperties implements Parcelable {
route.getMtu());
}
- private int findRouteIndexByDestination(RouteInfo route) {
+ private int findRouteIndexByRouteKey(RouteInfo route) {
for (int i = 0; i < mRoutes.size(); i++) {
- if (mRoutes.get(i).isSameDestinationAs(route)) {
+ if (mRoutes.get(i).getRouteKey().equals(route.getRouteKey())) {
return i;
}
}
@@ -701,11 +701,11 @@ public final class LinkProperties implements Parcelable {
/**
* Adds a {@link RouteInfo} to this {@code LinkProperties}, if a {@link RouteInfo}
- * with the same destination exists with different properties (e.g., different MTU),
- * it will be updated. If the {@link RouteInfo} had an interface name set and
- * that differs from the interface set for this {@code LinkProperties} an
- * {@link IllegalArgumentException} will be thrown. The proper
- * course is to add either un-named or properly named {@link RouteInfo}.
+ * with the same {@link RouteInfo.RouteKey} with different properties
+ * (e.g., different MTU), it will be updated. If the {@link RouteInfo} had an
+ * interface name set and that differs from the interface set for this
+ * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown.
+ * The proper course is to add either un-named or properly named {@link RouteInfo}.
*
* @param route A {@link RouteInfo} to add to this object.
* @return {@code true} was added or updated, false otherwise.
@@ -719,7 +719,7 @@ public final class LinkProperties implements Parcelable {
}
route = routeWithInterface(route);
- int i = findRouteIndexByDestination(route);
+ int i = findRouteIndexByRouteKey(route);
if (i == -1) {
// Route was not present. Add it.
mRoutes.add(route);
diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java
index 29da4952daa5..22288b6205d7 100644
--- a/core/java/android/net/NattKeepalivePacketData.java
+++ b/core/java/android/net/NattKeepalivePacketData.java
@@ -94,10 +94,10 @@ public final class NattKeepalivePacketData extends KeepalivePacketData implement
/** Write to parcel */
public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeString(srcAddress.getHostAddress());
- out.writeString(dstAddress.getHostAddress());
- out.writeInt(srcPort);
- out.writeInt(dstPort);
+ out.writeString(getSrcAddress().getHostAddress());
+ out.writeString(getDstAddress().getHostAddress());
+ out.writeInt(getSrcPort());
+ out.writeInt(getDstPort());
}
/** Parcelable Creator */
@@ -115,7 +115,7 @@ public final class NattKeepalivePacketData extends KeepalivePacketData implement
dstAddress, dstPort);
} catch (InvalidPacketException e) {
throw new IllegalArgumentException(
- "Invalid NAT-T keepalive data: " + e.error);
+ "Invalid NAT-T keepalive data: " + e.getError());
}
}
@@ -128,14 +128,16 @@ public final class NattKeepalivePacketData extends KeepalivePacketData implement
public boolean equals(@Nullable final Object o) {
if (!(o instanceof NattKeepalivePacketData)) return false;
final NattKeepalivePacketData other = (NattKeepalivePacketData) o;
- return this.srcAddress.equals(other.srcAddress)
- && this.dstAddress.equals(other.dstAddress)
- && this.srcPort == other.srcPort
- && this.dstPort == other.dstPort;
+ final InetAddress srcAddress = getSrcAddress();
+ final InetAddress dstAddress = getDstAddress();
+ return srcAddress.equals(other.getSrcAddress())
+ && dstAddress.equals(other.getDstAddress())
+ && getSrcPort() == other.getSrcPort()
+ && getDstPort() == other.getDstPort();
}
@Override
public int hashCode() {
- return Objects.hash(srcAddress, dstAddress, srcPort, dstPort);
+ return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort());
}
}
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index c145b2bc1881..3d641f5a0029 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -27,6 +27,7 @@ import android.system.Os;
import android.system.OsConstants;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.GuardedBy;
import com.android.okhttp.internalandroidapi.Dns;
import com.android.okhttp.internalandroidapi.HttpURLConnectionFactory;
@@ -64,15 +65,15 @@ public class Network implements Parcelable {
* The unique id of the network.
* @hide
*/
- @SystemApi
+ @UnsupportedAppUsage
public final int netId;
// Objects used to perform per-network operations such as getSocketFactory
// and openConnection, and a lock to protect access to them.
private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
- // mLock should be used to control write access to mUrlConnectionFactory.
- // maybeInitUrlConnectionFactory() must be called prior to reading this field.
- private volatile HttpURLConnectionFactory mUrlConnectionFactory;
+ // mUrlConnectionFactory is initialized lazily when it is first needed.
+ @GuardedBy("mLock")
+ private HttpURLConnectionFactory mUrlConnectionFactory;
private final Object mLock = new Object();
// Default connection pool values. These are evaluated at startup, just
@@ -170,6 +171,17 @@ public class Network implements Parcelable {
}
/**
+ * Get the unique id of the network.
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ public int getNetId() {
+ return netId;
+ }
+
+ /**
* Returns a netid marked with the Private DNS bypass flag.
*
* This flag must be kept in sync with the NETID_USE_LOCAL_NAMESERVERS flag
@@ -284,36 +296,16 @@ public class Network implements Parcelable {
return mNetworkBoundSocketFactory;
}
- // TODO: This creates a connection pool and host resolver for
- // every Network object, instead of one for every NetId. This is
- // suboptimal, because an app could potentially have more than one
- // Network object for the same NetId, causing increased memory footprint
- // and performance penalties due to lack of connection reuse (connection
- // setup time, congestion window growth time, etc.).
- //
- // Instead, investigate only having one connection pool and host resolver
- // for every NetId, perhaps by using a static HashMap of NetIds to
- // connection pools and host resolvers. The tricky part is deciding when
- // to remove a map entry; a WeakHashMap shouldn't be used because whether
- // a Network is referenced doesn't correlate with whether a new Network
- // will be instantiated in the near future with the same NetID. A good
- // solution would involve purging empty (or when all connections are timed
- // out) ConnectionPools.
- private void maybeInitUrlConnectionFactory() {
- synchronized (mLock) {
- if (mUrlConnectionFactory == null) {
- // Set configuration on the HttpURLConnectionFactory that will be good for all
- // connections created by this Network. Configuration that might vary is left
- // until openConnection() and passed as arguments.
- Dns dnsLookup = hostname -> Arrays.asList(Network.this.getAllByName(hostname));
- HttpURLConnectionFactory urlConnectionFactory = new HttpURLConnectionFactory();
- urlConnectionFactory.setDns(dnsLookup); // Let traffic go via dnsLookup
- // A private connection pool just for this Network.
- urlConnectionFactory.setNewConnectionPool(httpMaxConnections,
- httpKeepAliveDurationMs, TimeUnit.MILLISECONDS);
- mUrlConnectionFactory = urlConnectionFactory;
- }
- }
+ private static HttpURLConnectionFactory createUrlConnectionFactory(Dns dnsLookup) {
+ // Set configuration on the HttpURLConnectionFactory that will be good for all
+ // connections created by this Network. Configuration that might vary is left
+ // until openConnection() and passed as arguments.
+ HttpURLConnectionFactory urlConnectionFactory = new HttpURLConnectionFactory();
+ urlConnectionFactory.setDns(dnsLookup); // Let traffic go via dnsLookup
+ // A private connection pool just for this Network.
+ urlConnectionFactory.setNewConnectionPool(httpMaxConnections,
+ httpKeepAliveDurationMs, TimeUnit.MILLISECONDS);
+ return urlConnectionFactory;
}
/**
@@ -354,9 +346,31 @@ public class Network implements Parcelable {
*/
public URLConnection openConnection(URL url, java.net.Proxy proxy) throws IOException {
if (proxy == null) throw new IllegalArgumentException("proxy is null");
- maybeInitUrlConnectionFactory();
+ // TODO: This creates a connection pool and host resolver for
+ // every Network object, instead of one for every NetId. This is
+ // suboptimal, because an app could potentially have more than one
+ // Network object for the same NetId, causing increased memory footprint
+ // and performance penalties due to lack of connection reuse (connection
+ // setup time, congestion window growth time, etc.).
+ //
+ // Instead, investigate only having one connection pool and host resolver
+ // for every NetId, perhaps by using a static HashMap of NetIds to
+ // connection pools and host resolvers. The tricky part is deciding when
+ // to remove a map entry; a WeakHashMap shouldn't be used because whether
+ // a Network is referenced doesn't correlate with whether a new Network
+ // will be instantiated in the near future with the same NetID. A good
+ // solution would involve purging empty (or when all connections are timed
+ // out) ConnectionPools.
+ final HttpURLConnectionFactory urlConnectionFactory;
+ synchronized (mLock) {
+ if (mUrlConnectionFactory == null) {
+ Dns dnsLookup = hostname -> Arrays.asList(getAllByName(hostname));
+ mUrlConnectionFactory = createUrlConnectionFactory(dnsLookup);
+ }
+ urlConnectionFactory = mUrlConnectionFactory;
+ }
SocketFactory socketFactory = getSocketFactory();
- return mUrlConnectionFactory.openConnection(url, socketFactory, proxy);
+ return urlConnectionFactory.openConnection(url, socketFactory, proxy);
}
/**
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index ae5c24ecd7ae..ad1e50122748 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -19,6 +19,7 @@ package android.net;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -32,6 +33,7 @@ import android.util.ArraySet;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.BitUtils;
import com.android.internal.util.Preconditions;
@@ -86,6 +88,7 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Completely clears the contents of this object, removing even the capabilities that are set
* by default when the object is constructed.
+ * @hide
*/
public void clearAll() {
mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
@@ -412,12 +415,27 @@ public final class NetworkCapabilities implements Parcelable {
| (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
/**
+ * Capabilities that are allowed for test networks. This list must be set so that it is safe
+ * for an unprivileged user to create a network with these capabilities via shell. As such,
+ * it must never contain capabilities that are generally useful to the system, such as
+ * INTERNET, IMS, SUPL, etc.
+ */
+ private static final long TEST_NETWORKS_ALLOWED_CAPABILITIES =
+ (1 << NET_CAPABILITY_NOT_METERED)
+ | (1 << NET_CAPABILITY_NOT_RESTRICTED)
+ | (1 << NET_CAPABILITY_NOT_VPN)
+ | (1 << NET_CAPABILITY_NOT_ROAMING)
+ | (1 << NET_CAPABILITY_NOT_CONGESTED)
+ | (1 << NET_CAPABILITY_NOT_SUSPENDED);
+
+ /**
* Adds the given capability to this {@code NetworkCapability} instance.
- * Multiple capabilities may be applied sequentially. Note that when searching
- * for a network to satisfy a request, all capabilities requested must be satisfied.
+ * Note that when searching for a network to satisfy a request, all capabilities
+ * requested must be satisfied.
*
* @param capability the capability to be added.
* @return This NetworkCapabilities instance, to facilitate chaining.
+ * @hide
*/
public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) {
// If the given capability was previously added to the list of unwanted capabilities
@@ -432,9 +450,9 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Adds the given capability to the list of unwanted capabilities of this
- * {@code NetworkCapability} instance. Multiple unwanted capabilities may be applied
- * sequentially. Note that when searching for a network to satisfy a request, the network
- * must not contain any capability from unwanted capability list.
+ * {@code NetworkCapability} instance. Note that when searching for a network to
+ * satisfy a request, the network must not contain any capability from unwanted capability
+ * list.
* <p>
* If the capability was previously added to the list of required capabilities (for
* example, it was there by default or added using {@link #addCapability(int)} method), then
@@ -454,6 +472,7 @@ public final class NetworkCapabilities implements Parcelable {
*
* @param capability the capability to be removed.
* @return This NetworkCapabilities instance, to facilitate chaining.
+ * @hide
*/
public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) {
// Note that this method removes capabilities that were added via addCapability(int),
@@ -468,7 +487,7 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Sets (or clears) the given capability on this {@link NetworkCapabilities}
* instance.
- *
+ * @hide
*/
public @NonNull NetworkCapabilities setCapability(@NetCapability int capability,
boolean value) {
@@ -641,6 +660,21 @@ public final class NetworkCapabilities implements Parcelable {
}
/**
+ * Test networks have strong restrictions on what capabilities they can have. Enforce these
+ * restrictions.
+ * @hide
+ */
+ public void restrictCapabilitesForTestNetwork() {
+ final long originalCapabilities = mNetworkCapabilities;
+ final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
+ clearAll();
+ // Reset the transports to only contain TRANSPORT_TEST.
+ mTransportTypes = (1 << TRANSPORT_TEST);
+ mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
+ mNetworkSpecifier = originalSpecifier;
+ }
+
+ /**
* Representing the transport type. Apps should generally not care about transport. A
* request for a fast internet connection could be satisfied by a number of different
* transports. If any are specified here it will be satisfied a Network that matches
@@ -728,7 +762,7 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Adds the given transport type to this {@code NetworkCapability} instance.
- * Multiple transports may be applied sequentially. Note that when searching
+ * Multiple transports may be applied. Note that when searching
* for a network to satisfy a request, any listed in the request will satisfy the request.
* For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
* {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
@@ -737,6 +771,7 @@ public final class NetworkCapabilities implements Parcelable {
*
* @param transportType the transport type to be added.
* @return This NetworkCapabilities instance, to facilitate chaining.
+ * @hide
*/
public @NonNull NetworkCapabilities addTransportType(@Transport int transportType) {
checkValidTransportType(transportType);
@@ -849,6 +884,7 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Set the UID of the owner app.
+ * @hide
*/
public @NonNull NetworkCapabilities setOwnerUid(final int uid) {
mOwnerUid = uid;
@@ -866,6 +902,8 @@ public final class NetworkCapabilities implements Parcelable {
* <li>The user's location toggle is on
* </ol>
*
+ * Instances of NetworkCapabilities sent to apps without the appropriate permissions will
+ * have this field cleared out.
*/
public int getOwnerUid() {
return mOwnerUid;
@@ -904,7 +942,6 @@ public final class NetworkCapabilities implements Parcelable {
* @hide
*/
@NonNull
- @SystemApi
public NetworkCapabilities setAdministratorUids(@NonNull final int[] administratorUids) {
mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
return this;
@@ -918,6 +955,7 @@ public final class NetworkCapabilities implements Parcelable {
*/
@NonNull
@SystemApi
+ @TestApi
public int[] getAdministratorUids() {
return Arrays.copyOf(mAdministratorUids, mAdministratorUids.length);
}
@@ -940,15 +978,10 @@ public final class NetworkCapabilities implements Parcelable {
* Sets the upstream bandwidth for this network in Kbps. This always only refers to
* the estimated first hop transport bandwidth.
* <p>
- * Note that when used to request a network, this specifies the minimum acceptable.
- * When received as the state of an existing network this specifies the typical
- * first hop bandwidth expected. This is never measured, but rather is inferred
- * from technology type and other link parameters. It could be used to differentiate
- * between very slow 1xRTT cellular links and other faster networks or even between
- * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
- * fast backhauls and slow backhauls.
+ * {@see Builder#setLinkUpstreamBandwidthKbps}
*
* @param upKbps the estimated first hop upstream (device to network) bandwidth.
+ * @hide
*/
public @NonNull NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) {
mLinkUpBandwidthKbps = upKbps;
@@ -969,15 +1002,10 @@ public final class NetworkCapabilities implements Parcelable {
* Sets the downstream bandwidth for this network in Kbps. This always only refers to
* the estimated first hop transport bandwidth.
* <p>
- * Note that when used to request a network, this specifies the minimum acceptable.
- * When received as the state of an existing network this specifies the typical
- * first hop bandwidth expected. This is never measured, but rather is inferred
- * from technology type and other link parameters. It could be used to differentiate
- * between very slow 1xRTT cellular links and other faster networks or even between
- * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
- * fast backhauls and slow backhauls.
+ * {@see Builder#setLinkUpstreamBandwidthKbps}
*
* @param downKbps the estimated first hop downstream (network to device) bandwidth.
+ * @hide
*/
public @NonNull NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) {
mLinkDownBandwidthKbps = downKbps;
@@ -1036,6 +1064,7 @@ public final class NetworkCapabilities implements Parcelable {
* @param networkSpecifier A concrete, parcelable framework class that extends
* NetworkSpecifier.
* @return This NetworkCapabilities instance, to facilitate chaining.
+ * @hide
*/
public @NonNull NetworkCapabilities setNetworkSpecifier(
@NonNull NetworkSpecifier networkSpecifier) {
@@ -1057,7 +1086,6 @@ public final class NetworkCapabilities implements Parcelable {
* @return This NetworkCapabilities instance, to facilitate chaining.
* @hide
*/
- @SystemApi
public @NonNull NetworkCapabilities setTransportInfo(@NonNull TransportInfo transportInfo) {
mTransportInfo = transportInfo;
return this;
@@ -1067,7 +1095,7 @@ public final class NetworkCapabilities implements Parcelable {
* Gets the optional bearer specific network specifier. May be {@code null} if not set.
*
* @return The optional {@link NetworkSpecifier} specifying the bearer specific network
- * specifier or {@code null}. See {@link #setNetworkSpecifier}.
+ * specifier or {@code null}.
*/
public @Nullable NetworkSpecifier getNetworkSpecifier() {
return mNetworkSpecifier;
@@ -1137,6 +1165,7 @@ public final class NetworkCapabilities implements Parcelable {
* effect when requesting a callback.
*
* @param signalStrength the bearer-specific signal strength.
+ * @hide
*/
public @NonNull NetworkCapabilities setSignalStrength(int signalStrength) {
mSignalStrength = signalStrength;
@@ -1363,7 +1392,6 @@ public final class NetworkCapabilities implements Parcelable {
* Sets the SSID of this network.
* @hide
*/
- @SystemApi
public @NonNull NetworkCapabilities setSSID(@Nullable String ssid) {
mSSID = ssid;
return this;
@@ -1374,7 +1402,8 @@ public final class NetworkCapabilities implements Parcelable {
* @hide
*/
@SystemApi
- public @Nullable String getSSID() {
+ @TestApi
+ public @Nullable String getSsid() {
return mSSID;
}
@@ -1854,25 +1883,32 @@ public final class NetworkCapabilities implements Parcelable {
}
/**
- * Set the uid of the app making the request.
+ * Set the UID of the app making the request.
*
- * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in
- * via the public {@link ConnectivityManager} API's will have this field overwritten.
+ * For instances of NetworkCapabilities representing a request, sets the
+ * UID of the app making the request. For a network created by the system,
+ * sets the UID of the only app whose requests can match this network.
+ * This can be set to {@link Process#INVALID_UID} if there is no such app,
+ * or if this instance of NetworkCapabilities is about to be sent to a
+ * party that should not learn about this.
*
* @param uid UID of the app.
* @hide
*/
- @SystemApi
public @NonNull NetworkCapabilities setRequestorUid(int uid) {
mRequestorUid = uid;
return this;
}
/**
- * @return the uid of the app making the request.
+ * Returns the UID of the app making the request.
+ *
+ * For a NetworkRequest being made by an app, contains the app's UID. For a network
+ * created by the system, contains the UID of the only app whose requests can match
+ * this network, or {@link Process#INVALID_UID} if none or if the
+ * caller does not have permission to learn about this.
*
- * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest}
- * object was not obtained from {@link ConnectivityManager}.
+ * @return the uid of the app making the request.
* @hide
*/
public int getRequestorUid() {
@@ -1882,23 +1918,29 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Set the package name of the app making the request.
*
- * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in
- * via the public {@link ConnectivityManager} API's will have this field overwritten.
+ * For instances of NetworkCapabilities representing a request, sets the
+ * package name of the app making the request. For a network created by the system,
+ * sets the package name of the only app whose requests can match this network.
+ * This can be set to null if there is no such app, or if this instance of
+ * NetworkCapabilities is about to be sent to a party that should not learn about this.
*
* @param packageName package name of the app.
* @hide
*/
- @SystemApi
public @NonNull NetworkCapabilities setRequestorPackageName(@NonNull String packageName) {
mRequestorPackageName = packageName;
return this;
}
/**
- * @return the package name of the app making the request.
+ * Returns the package name of the app making the request.
*
- * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained
- * from {@link ConnectivityManager}.
+ * For a NetworkRequest being made by an app, contains the app's package name. For a
+ * network created by the system, contains the package name of the only app whose
+ * requests can match this network, or null if none or if the caller does not have
+ * permission to learn about this.
+ *
+ * @return the package name of the app making the request.
* @hide
*/
@Nullable
@@ -1907,9 +1949,9 @@ public final class NetworkCapabilities implements Parcelable {
}
/**
- * Set the uid and package name of the app making the request.
+ * Set the uid and package name of the app causing this network to exist.
*
- * Note: This is intended to be only invoked from within connectivitiy service.
+ * {@see #setRequestorUid} and {@link #setRequestorPackageName}
*
* @param uid UID of the app.
* @param packageName package name of the app.
@@ -1968,4 +2010,316 @@ public final class NetworkCapabilities implements Parcelable {
return mRequestorUid == nc.mRequestorUid
&& TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName);
}
+
+ /**
+ * Builder class for NetworkCapabilities.
+ *
+ * This class is mainly for for {@link NetworkAgent} instances to use. Many fields in
+ * the built class require holding a signature permission to use - mostly
+ * {@link android.Manifest.permission.NETWORK_FACTORY}, but refer to the specific
+ * description of each setter. As this class lives entirely in app space it does not
+ * enforce these restrictions itself but the system server clears out the relevant
+ * fields when receiving a NetworkCapabilities object from a caller without the
+ * appropriate permission.
+ *
+ * Apps don't use this builder directly. Instead, they use {@link NetworkRequest} via
+ * its builder object.
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public static class Builder {
+ private final NetworkCapabilities mCaps;
+
+ /**
+ * Creates a new Builder to construct NetworkCapabilities objects.
+ */
+ public Builder() {
+ mCaps = new NetworkCapabilities();
+ }
+
+ /**
+ * Creates a new Builder of NetworkCapabilities from an existing instance.
+ */
+ public Builder(@NonNull final NetworkCapabilities nc) {
+ Objects.requireNonNull(nc);
+ mCaps = new NetworkCapabilities(nc);
+ }
+
+ /**
+ * Adds the given transport type.
+ *
+ * Multiple transports may be added. Note that when searching for a network to satisfy a
+ * request, satisfying any of the transports listed in the request will satisfy the request.
+ * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
+ * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
+ * to be selected. This is logically different than
+ * {@code NetworkCapabilities.NET_CAPABILITY_*}.
+ *
+ * @param transportType the transport type to be added or removed.
+ * @return this builder
+ */
+ @NonNull
+ public Builder addTransportType(@Transport int transportType) {
+ checkValidTransportType(transportType);
+ mCaps.addTransportType(transportType);
+ return this;
+ }
+
+ /**
+ * Removes the given transport type.
+ *
+ * {@see #addTransportType}.
+ *
+ * @param transportType the transport type to be added or removed.
+ * @return this builder
+ */
+ @NonNull
+ public Builder removeTransportType(@Transport int transportType) {
+ checkValidTransportType(transportType);
+ mCaps.removeTransportType(transportType);
+ return this;
+ }
+
+ /**
+ * Adds the given capability.
+ *
+ * @param capability the capability
+ * @return this builder
+ */
+ @NonNull
+ public Builder addCapability(@NetCapability final int capability) {
+ mCaps.setCapability(capability, true);
+ return this;
+ }
+
+ /**
+ * Removes the given capability.
+ *
+ * @param capability the capability
+ * @return this builder
+ */
+ @NonNull
+ public Builder removeCapability(@NetCapability final int capability) {
+ mCaps.setCapability(capability, false);
+ return this;
+ }
+
+ /**
+ * Sets the owner UID.
+ *
+ * The default value is {@link Process#INVALID_UID}. Pass this value to reset.
+ *
+ * Note: for security the system will clear out this field when received from a
+ * non-privileged source.
+ *
+ * @param ownerUid the owner UID
+ * @return this builder
+ */
+ @NonNull
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ public Builder setOwnerUid(final int ownerUid) {
+ mCaps.setOwnerUid(ownerUid);
+ return this;
+ }
+
+ /**
+ * Sets the list of UIDs that are administrators of this network.
+ *
+ * <p>UIDs included in administratorUids gain administrator privileges over this
+ * Network. Examples of UIDs that should be included in administratorUids are:
+ * <ul>
+ * <li>Carrier apps with privileges for the relevant subscription
+ * <li>Active VPN apps
+ * <li>Other application groups with a particular Network-related role
+ * </ul>
+ *
+ * <p>In general, user-supplied networks (such as WiFi networks) do not have
+ * administrators.
+ *
+ * <p>An app is granted owner privileges over Networks that it supplies. The owner
+ * UID MUST always be included in administratorUids.
+ *
+ * The default value is the empty array. Pass an empty array to reset.
+ *
+ * Note: for security the system will clear out this field when received from a
+ * non-privileged source, such as an app using reflection to call this or
+ * mutate the member in the built object.
+ *
+ * @param administratorUids the UIDs to be set as administrators of this Network.
+ * @return this builder
+ */
+ @NonNull
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ public Builder setAdministratorUids(@NonNull final int[] administratorUids) {
+ Objects.requireNonNull(administratorUids);
+ mCaps.setAdministratorUids(administratorUids);
+ return this;
+ }
+
+ /**
+ * Sets the upstream bandwidth of the link.
+ *
+ * Sets the upstream bandwidth for this network in Kbps. This always only refers to
+ * the estimated first hop transport bandwidth.
+ * <p>
+ * Note that when used to request a network, this specifies the minimum acceptable.
+ * When received as the state of an existing network this specifies the typical
+ * first hop bandwidth expected. This is never measured, but rather is inferred
+ * from technology type and other link parameters. It could be used to differentiate
+ * between very slow 1xRTT cellular links and other faster networks or even between
+ * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
+ * fast backhauls and slow backhauls.
+ *
+ * @param upKbps the estimated first hop upstream (device to network) bandwidth.
+ * @return this builder
+ */
+ @NonNull
+ public Builder setLinkUpstreamBandwidthKbps(final int upKbps) {
+ mCaps.setLinkUpstreamBandwidthKbps(upKbps);
+ return this;
+ }
+
+ /**
+ * Sets the downstream bandwidth for this network in Kbps. This always only refers to
+ * the estimated first hop transport bandwidth.
+ * <p>
+ * Note that when used to request a network, this specifies the minimum acceptable.
+ * When received as the state of an existing network this specifies the typical
+ * first hop bandwidth expected. This is never measured, but rather is inferred
+ * from technology type and other link parameters. It could be used to differentiate
+ * between very slow 1xRTT cellular links and other faster networks or even between
+ * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
+ * fast backhauls and slow backhauls.
+ *
+ * @param downKbps the estimated first hop downstream (network to device) bandwidth.
+ * @return this builder
+ */
+ @NonNull
+ public Builder setLinkDownstreamBandwidthKbps(final int downKbps) {
+ mCaps.setLinkDownstreamBandwidthKbps(downKbps);
+ return this;
+ }
+
+ /**
+ * Sets the optional bearer specific network specifier.
+ * This has no meaning if a single transport is also not specified, so calling
+ * this without a single transport set will generate an exception, as will
+ * subsequently adding or removing transports after this is set.
+ * </p>
+ *
+ * @param specifier a concrete, parcelable framework class that extends NetworkSpecifier,
+ * or null to clear it.
+ * @return this builder
+ */
+ @NonNull
+ public Builder setNetworkSpecifier(@Nullable final NetworkSpecifier specifier) {
+ mCaps.setNetworkSpecifier(specifier);
+ return this;
+ }
+
+ /**
+ * Sets the optional transport specific information.
+ *
+ * @param info A concrete, parcelable framework class that extends {@link TransportInfo},
+ * or null to clear it.
+ * @return this builder
+ */
+ @NonNull
+ public Builder setTransportInfo(@Nullable final TransportInfo info) {
+ mCaps.setTransportInfo(info);
+ return this;
+ }
+
+ /**
+ * Sets the signal strength. This is a signed integer, with higher values indicating a
+ * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the
+ * same RSSI units reported by wifi code.
+ * <p>
+ * Note that when used to register a network callback, this specifies the minimum
+ * acceptable signal strength. When received as the state of an existing network it
+ * specifies the current value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means
+ * no value when received and has no effect when requesting a callback.
+ *
+ * Note: for security the system will throw if it receives a NetworkRequest where
+ * the underlying NetworkCapabilities has this member set from a source that does
+ * not hold the {@link android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP}
+ * permission. Apps with this permission can use this indirectly through
+ * {@link android.net.NetworkRequest}.
+ *
+ * @param signalStrength the bearer-specific signal strength.
+ * @return this builder
+ */
+ @NonNull
+ @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP)
+ public Builder setSignalStrength(final int signalStrength) {
+ mCaps.setSignalStrength(signalStrength);
+ return this;
+ }
+
+ /**
+ * Sets the SSID of this network.
+ *
+ * Note: for security the system will clear out this field when received from a
+ * non-privileged source, like an app using reflection to set this.
+ *
+ * @param ssid the SSID, or null to clear it.
+ * @return this builder
+ */
+ @NonNull
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ public Builder setSsid(@Nullable final String ssid) {
+ mCaps.setSSID(ssid);
+ return this;
+ }
+
+ /**
+ * Set the uid of the app causing this network to exist.
+ *
+ * Note: for security the system will clear out this field when received from a
+ * non-privileged source.
+ *
+ * @param uid UID of the app.
+ * @return this builder
+ */
+ @NonNull
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ public Builder setRequestorUid(final int uid) {
+ mCaps.setRequestorUid(uid);
+ return this;
+ }
+
+ /**
+ * Set the package name of the app causing this network to exist.
+ *
+ * Note: for security the system will clear out this field when received from a
+ * non-privileged source.
+ *
+ * @param packageName package name of the app, or null to clear it.
+ * @return this builder
+ */
+ @NonNull
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ public Builder setRequestorPackageName(@Nullable final String packageName) {
+ mCaps.setRequestorPackageName(packageName);
+ return this;
+ }
+
+ /**
+ * Builds the instance of the capabilities.
+ *
+ * @return the built instance of NetworkCapabilities.
+ */
+ @NonNull
+ public NetworkCapabilities build() {
+ if (mCaps.getOwnerUid() != Process.INVALID_UID) {
+ if (!ArrayUtils.contains(mCaps.getAdministratorUids(), mCaps.getOwnerUid())) {
+ throw new IllegalStateException("The owner UID must be included in "
+ + " administrator UIDs.");
+ }
+ }
+ return new NetworkCapabilities(mCaps);
+ }
+ }
}
diff --git a/core/java/android/net/OWNERS b/core/java/android/net/OWNERS
index 767b69351065..5e2a71876103 100644
--- a/core/java/android/net/OWNERS
+++ b/core/java/android/net/OWNERS
@@ -8,4 +8,4 @@ lorenzo@google.com
reminv@google.com
satk@google.com
-per-file SSL*, Uri*, Url* = prb@google.com, dauletz@google.com, narayan@google.com, tobiast@google.com
+per-file SSL*, Uri*, Url* = prb@google.com, dauletz@google.com, narayan@google.com, ngeoffray@google.com
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index fec2df412adb..dbdaa4c2da67 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -26,6 +26,7 @@ import android.net.util.NetUtils;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Pair;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -527,23 +528,27 @@ public final class RouteInfo implements Parcelable {
}
/**
- * Compares this RouteInfo object against the specified object and indicates if the
- * destinations of both routes are equal.
- * @return {@code true} if the route destinations are equal, {@code false} otherwise.
+ * A helper class that contains the destination and the gateway in a {@code RouteInfo},
+ * used by {@link ConnectivityService#updateRoutes} or
+ * {@link LinkProperties#addRoute} to calculate the list to be updated.
*
* @hide
*/
- public boolean isSameDestinationAs(@Nullable Object obj) {
- if (this == obj) return true;
-
- if (!(obj instanceof RouteInfo)) return false;
-
- RouteInfo target = (RouteInfo) obj;
-
- if (Objects.equals(mDestination, target.getDestination())) {
- return true;
+ public static class RouteKey extends Pair<IpPrefix, InetAddress> {
+ RouteKey(@NonNull IpPrefix destination, @Nullable InetAddress gateway) {
+ super(destination, gateway);
}
- return false;
+ }
+
+ /**
+ * Get {@code RouteKey} of this {@code RouteInfo}.
+ * @return a {@code RouteKey} object.
+ *
+ * @hide
+ */
+ @NonNull
+ public RouteKey getRouteKey() {
+ return new RouteKey(mDestination, mGateway);
}
/**
diff --git a/core/java/android/net/http/OWNERS b/core/java/android/net/http/OWNERS
index 309261277024..3271d243e2cd 100644
--- a/core/java/android/net/http/OWNERS
+++ b/core/java/android/net/http/OWNERS
@@ -1,4 +1,4 @@
narayan@google.com
-tobiast@google.com
+ngeoffray@google.com
include platform/libcore:/OWNERS
include platform/external/conscrypt:/OWNERS
diff --git a/core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl b/core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl
index 0ae353d2741f..5d8f6d126a89 100644
--- a/core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl
+++ b/core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl
@@ -17,11 +17,12 @@
package android.os.incremental;
/**
- * Wraps two file descriptors that Incremental Service uses to communicate
+ * Wraps the file descriptors Incremental Service uses to communicate
* with Incremental FileSystem.
* @hide
*/
parcelable IncrementalFileSystemControlParcel {
@nullable ParcelFileDescriptor cmd;
+ @nullable ParcelFileDescriptor pendingReads;
@nullable ParcelFileDescriptor log;
}
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index ab31d247bb73..f8b9f584c6c9 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -176,7 +176,6 @@ public class PhoneStateListener {
* @hide
*/
@RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
- @SystemApi
public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH = 0x00000200;
/**
diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java
index 28a5c2086ede..901957f6ca4a 100644
--- a/core/java/android/telephony/SubscriptionPlan.java
+++ b/core/java/android/telephony/SubscriptionPlan.java
@@ -91,10 +91,11 @@ public final class SubscriptionPlan implements Parcelable {
private long dataUsageBytes = BYTES_UNKNOWN;
private long dataUsageTime = TIME_UNKNOWN;
private @NetworkType int[] networkTypes;
- private long networkTypesBitMask;
private SubscriptionPlan(RecurrenceRule cycleRule) {
this.cycleRule = Preconditions.checkNotNull(cycleRule);
+ this.networkTypes = Arrays.copyOf(TelephonyManager.getAllNetworkTypes(),
+ TelephonyManager.getAllNetworkTypes().length);
}
private SubscriptionPlan(Parcel source) {
@@ -221,28 +222,10 @@ public final class SubscriptionPlan implements Parcelable {
/**
* Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to.
- * A null value means this SubscriptionPlan applies to all network types.
+ * @see TelephonyManager for network types values
*/
- public @Nullable @NetworkType int[] getNetworkTypes() {
- return networkTypes;
- }
-
- /**
- * Return the networkTypes array converted to a {@link TelephonyManager.NetworkTypeBitMask}
- * @hide
- */
- public long getNetworkTypesBitMask() {
- // calculate bitmask the first time and save for future calls
- if (networkTypesBitMask == 0) {
- if (networkTypes == null) {
- networkTypesBitMask = ~0;
- } else {
- for (int networkType : networkTypes) {
- networkTypesBitMask |= TelephonyManager.getBitMaskForNetworkType(networkType);
- }
- }
- }
- return networkTypesBitMask;
+ public @NonNull @NetworkType int[] getNetworkTypes() {
+ return Arrays.copyOf(networkTypes, networkTypes.length);
}
/**
@@ -379,14 +362,14 @@ public final class SubscriptionPlan implements Parcelable {
}
/**
- * Set the network types this SubscriptionPlan applies to.
+ * Set the network types this SubscriptionPlan applies to. By default the plan will apply
+ * to all network types. An empty array means this plan applies to no network types.
*
- * @param networkTypes a set of all {@link NetworkType}s that apply to this plan.
- * A null value means the plan applies to all network types,
- * and an empty array means the plan applies to no network types.
+ * @param networkTypes an array of all {@link NetworkType}s that apply to this plan.
+ * @see TelephonyManager for network type values
*/
- public @NonNull Builder setNetworkTypes(@Nullable @NetworkType int[] networkTypes) {
- plan.networkTypes = networkTypes;
+ public @NonNull Builder setNetworkTypes(@NonNull @NetworkType int[] networkTypes) {
+ plan.networkTypes = Arrays.copyOf(networkTypes, networkTypes.length);
return this;
}
}
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 73cd708f43f7..e3620426049f 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -26,8 +26,10 @@ import android.os.ServiceManager;
import android.telephony.Annotation.CallState;
import android.telephony.Annotation.DataActivityType;
import android.telephony.Annotation.DataFailureCause;
+import android.telephony.Annotation.DisconnectCauses;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.PreciseCallStates;
+import android.telephony.Annotation.PreciseDisconnectCauses;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SimActivationState;
import android.telephony.Annotation.SrvccState;
@@ -229,11 +231,9 @@ public class TelephonyRegistryManager {
* invalid.
* @param state latest call state. e.g, offhook, ringing
* @param incomingNumber incoming phone number.
- *
- * @hide
*/
public void notifyCallStateChanged(int subId, int slotIndex, @CallState int state,
- String incomingNumber) {
+ @Nullable String incomingNumber) {
try {
sRegistry.notifyCallState(slotIndex, subId, state, incomingNumber);
} catch (RemoteException ex) {
@@ -266,10 +266,8 @@ public class TelephonyRegistryManager {
* @param slotIndex for which the service state changed. Can be derived from subId except
* subId is invalid.
* @param state service state e.g, in service, out of service or roaming status.
- *
- * @hide
*/
- public void notifyServiceStateChanged(int subId, int slotIndex, ServiceState state) {
+ public void notifyServiceStateChanged(int subId, int slotIndex, @NonNull ServiceState state) {
try {
sRegistry.notifyServiceStateForPhoneId(slotIndex, subId, state);
} catch (RemoteException ex) {
@@ -284,11 +282,9 @@ public class TelephonyRegistryManager {
* @param slotIndex for which the signalstrength changed. Can be derived from subId except when
* subId is invalid.
* @param signalStrength e.g, signalstrength level {@see SignalStrength#getLevel()}
- *
- * @hide
*/
public void notifySignalStrengthChanged(int subId, int slotIndex,
- SignalStrength signalStrength) {
+ @NonNull SignalStrength signalStrength) {
try {
sRegistry.notifySignalStrengthForPhoneId(slotIndex, subId, signalStrength);
} catch (RemoteException ex) {
@@ -305,8 +301,6 @@ public class TelephonyRegistryManager {
* except when subId is invalid.
* @param msgWaitingInd {@code true} indicates there is message-waiting indicator, {@code false}
* otherwise.
- *
- * @hide
*/
public void notifyMessageWaitingChanged(int subId, int slotIndex, boolean msgWaitingInd) {
try {
@@ -322,8 +316,6 @@ public class TelephonyRegistryManager {
* @param subId for which call forwarding status changed.
* @param callForwardInd {@code true} indicates there is call forwarding, {@code false}
* otherwise.
- *
- * @hide
*/
public void notifyCallForwardingChanged(int subId, boolean callForwardInd) {
try {
@@ -339,8 +331,6 @@ public class TelephonyRegistryManager {
* @param subId for which data activity state changed.
* @param dataActivityType indicates the latest data activity type e.g, {@link
* TelephonyManager#DATA_ACTIVITY_IN}
- *
- * @hide
*/
public void notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType) {
try {
@@ -361,10 +351,9 @@ public class TelephonyRegistryManager {
*
* @see android.telephony.PreciseDataConnection
* @see TelephonyManager#DATA_DISCONNECTED
- * @hide
*/
public void notifyDataConnectionForSubscriber(int slotIndex, int subId,
- String apnType, PreciseDataConnectionState preciseState) {
+ String apnType, @Nullable PreciseDataConnectionState preciseState) {
try {
sRegistry.notifyDataConnectionForSubscriber(
slotIndex, subId, apnType, preciseState);
@@ -381,10 +370,8 @@ public class TelephonyRegistryManager {
* subId is invalid.
* @param callQuality Information about call quality e.g, call quality level
* @param networkType associated with this data connection. e.g, LTE
- *
- * @hide
*/
- public void notifyCallQualityChanged(int subId, int slotIndex, CallQuality callQuality,
+ public void notifyCallQualityChanged(int subId, int slotIndex, @NonNull CallQuality callQuality,
@NetworkType int networkType) {
try {
sRegistry.notifyCallQualityChanged(callQuality, slotIndex, subId, networkType);
@@ -399,8 +386,6 @@ public class TelephonyRegistryManager {
* @param subId for which emergency number list changed.
* @param slotIndex for which emergency number list changed. Can be derived from subId except
* when subId is invalid.
- *
- * @hide
*/
public void notifyEmergencyNumberList(int subId, int slotIndex) {
try {
@@ -417,8 +402,6 @@ public class TelephonyRegistryManager {
* @param slotIndex for which radio power state changed. Can be derived from subId except when
* subId is invalid.
* @param radioPowerState the current modem radio state.
- *
- * @hide
*/
public void notifyRadioPowerStateChanged(int subId, int slotIndex,
@RadioPowerState int radioPowerState) {
@@ -433,10 +416,8 @@ public class TelephonyRegistryManager {
* Notify {@link PhoneCapability} changed.
*
* @param phoneCapability the capability of the modem group.
- *
- * @hide
*/
- public void notifyPhoneCapabilityChanged(PhoneCapability phoneCapability) {
+ public void notifyPhoneCapabilityChanged(@NonNull PhoneCapability phoneCapability) {
try {
sRegistry.notifyPhoneCapabilityChanged(phoneCapability);
} catch (RemoteException ex) {
@@ -465,8 +446,6 @@ public class TelephonyRegistryManager {
* @param slotIndex for which data activation state changed. Can be derived from subId except
* when subId is invalid.
* @param activationState sim activation state e.g, activated.
- *
- * @hide
*/
public void notifyDataActivationStateChanged(int subId, int slotIndex,
@SimActivationState int activationState) {
@@ -486,8 +465,6 @@ public class TelephonyRegistryManager {
* @param slotIndex for which voice activation state changed. Can be derived from subId except
* subId is invalid.
* @param activationState sim activation state e.g, activated.
- *
- * @hide
*/
public void notifyVoiceActivationStateChanged(int subId, int slotIndex,
@SimActivationState int activationState) {
@@ -507,8 +484,6 @@ public class TelephonyRegistryManager {
* @param slotIndex for which mobile data state has changed. Can be derived from subId except
* when subId is invalid.
* @param state {@code true} indicates mobile data is enabled/on. {@code false} otherwise.
- *
- * @hide
*/
public void notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state) {
try {
@@ -519,23 +494,6 @@ public class TelephonyRegistryManager {
}
/**
- * TODO: this is marked as deprecated, can we move this one safely?
- *
- * @param subId
- * @param slotIndex
- * @param rawData
- *
- * @hide
- */
- public void notifyOemHookRawEventForSubscriber(int subId, int slotIndex, byte[] rawData) {
- try {
- sRegistry.notifyOemHookRawEventForSubscriber(slotIndex, subId, rawData);
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- /**
* Notify display info changed.
*
* @param slotIndex The SIM slot index for which display info has changed. Can be
@@ -558,10 +516,8 @@ public class TelephonyRegistryManager {
*
* @param subId for which ims call disconnect.
* @param imsReasonInfo the reason for ims call disconnect.
- *
- * @hide
*/
- public void notifyImsDisconnectCause(int subId, ImsReasonInfo imsReasonInfo) {
+ public void notifyImsDisconnectCause(int subId, @NonNull ImsReasonInfo imsReasonInfo) {
try {
sRegistry.notifyImsDisconnectCause(subId, imsReasonInfo);
} catch (RemoteException ex) {
@@ -578,11 +534,9 @@ public class TelephonyRegistryManager {
* @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN.
* @param apn the APN {@link ApnSetting#getApnName()} of this data connection.
* @param failCause data fail cause.
- *
- * @hide
*/
public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, String apnType,
- String apn, @DataFailureCause int failCause) {
+ @Nullable String apn, @DataFailureCause int failCause) {
try {
sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause);
} catch (RemoteException ex) {
@@ -596,8 +550,6 @@ public class TelephonyRegistryManager {
*
* @param subId for which srvcc state changed.
* @param state srvcc state
- *
- * @hide
*/
public void notifySrvccStateChanged(int subId, @SrvccState int state) {
try {
@@ -617,8 +569,6 @@ public class TelephonyRegistryManager {
* @param ringCallPreciseState ringCall state.
* @param foregroundCallPreciseState foreground call state.
* @param backgroundCallPreciseState background call state.
- *
- * @hide
*/
public void notifyPreciseCallState(int subId, int slotIndex,
@PreciseCallStates int ringCallPreciseState,
@@ -642,10 +592,9 @@ public class TelephonyRegistryManager {
* @param cause {@link DisconnectCause} for the disconnected call.
* @param preciseCause {@link android.telephony.PreciseDisconnectCause} for the disconnected
* call.
- *
- * @hide
*/
- public void notifyDisconnectCause(int slotIndex, int subId, int cause, int preciseCause) {
+ public void notifyDisconnectCause(int slotIndex, int subId, @DisconnectCauses int cause,
+ @PreciseDisconnectCauses int preciseCause) {
try {
sRegistry.notifyDisconnectCause(slotIndex, subId, cause, preciseCause);
} catch (RemoteException ex) {
@@ -658,10 +607,8 @@ public class TelephonyRegistryManager {
*
* <p>To be compatible with {@link TelephonyRegistry}, use {@link CellIdentity} which is
* parcelable, and convert to CellLocation in client code.
- *
- * @hide
*/
- public void notifyCellLocation(int subId, CellIdentity cellLocation) {
+ public void notifyCellLocation(int subId, @NonNull CellIdentity cellLocation) {
try {
sRegistry.notifyCellLocationForSubscriber(subId, cellLocation);
} catch (RemoteException ex) {
@@ -675,10 +622,8 @@ public class TelephonyRegistryManager {
*
* @param subId for which cellinfo changed.
* @param cellInfo A list of cellInfo associated with the given subscription.
- *
- * @hide
*/
- public void notifyCellInfoChanged(int subId, List<CellInfo> cellInfo) {
+ public void notifyCellInfoChanged(int subId, @NonNull List<CellInfo> cellInfo) {
try {
sRegistry.notifyCellInfoForSubscriber(subId, cellInfo);
} catch (RemoteException ex) {
@@ -687,8 +632,8 @@ public class TelephonyRegistryManager {
}
/**
- * @param activeDataSubId
- * @hide
+ * Notify that the active data subscription ID has changed.
+ * @param activeDataSubId The new subscription ID for active data
*/
public void notifyActiveDataSubIdChanged(int activeDataSubId) {
try {
diff --git a/core/jni/android_app_admin_SecurityLog.cpp b/core/jni/android_app_admin_SecurityLog.cpp
index b3bcaa0f7f03..e5a13db3dfb0 100644
--- a/core/jni/android_app_admin_SecurityLog.cpp
+++ b/core/jni/android_app_admin_SecurityLog.cpp
@@ -41,7 +41,7 @@ static void android_app_admin_SecurityLog_readEvents(JNIEnv* env, jobject /* cla
jniThrowNullPointerException(env, NULL);
return;
}
- SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out);
+ SLog::readEvents(env, ANDROID_LOG_NONBLOCK, 0, out);
}
static void android_app_admin_SecurityLog_readEventsSince(JNIEnv* env, jobject /* clazz */,
@@ -52,7 +52,7 @@ static void android_app_admin_SecurityLog_readEventsSince(JNIEnv* env, jobject /
jniThrowNullPointerException(env, NULL);
return;
}
- SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out);
+ SLog::readEvents(env, ANDROID_LOG_NONBLOCK, timestamp, out);
}
static void android_app_admin_SecurityLog_readPreviousEvents(JNIEnv* env, jobject /* clazz */,
@@ -62,7 +62,7 @@ static void android_app_admin_SecurityLog_readPreviousEvents(JNIEnv* env, jobjec
jniThrowNullPointerException(env, NULL);
return;
}
- SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out);
+ SLog::readEvents(env, ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out);
}
static void android_app_admin_SecurityLog_readEventsOnWrapping(JNIEnv* env, jobject /* clazz */,
@@ -72,8 +72,7 @@ static void android_app_admin_SecurityLog_readEventsOnWrapping(JNIEnv* env, jobj
jniThrowNullPointerException(env, NULL);
return;
}
- SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp,
- out);
+ SLog::readEvents(env, ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp, out);
}
/*
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 3b5a144a4e61..0a5e78617568 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -44,7 +44,7 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz ATTRIBUT
return;
}
- ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tags, 0, out);
+ ELog::readEvents(env, ANDROID_LOG_NONBLOCK, tags, 0, out);
}
/*
* In class android.util.EventLog:
@@ -60,8 +60,7 @@ static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject claz
jniThrowNullPointerException(env, NULL);
return;
}
- ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, tags,
- timestamp, out);
+ ELog::readEvents(env, ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, tags, timestamp, out);
}
/*
diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto
index 15ef12285e24..afd109996722 100644
--- a/core/proto/android/stats/dnsresolver/dns_resolver.proto
+++ b/core/proto/android/stats/dnsresolver/dns_resolver.proto
@@ -43,6 +43,7 @@ enum ReturnCode {
RC_EAI_BADHINTS = 12;
RC_EAI_PROTOCOL = 13;
RC_EAI_OVERFLOW = 14;
+ RC_RESOLV_INTERNAL_ERROR = 254;
RC_RESOLV_TIMEOUT = 255;
RC_EAI_MAX = 256;
}
@@ -197,6 +198,144 @@ enum CacheStatus{
CS_SKIP = 3;
}
+// The enum LinuxErrno is defined in the following 2 files.
+// 1. bionic/libc/kernel/uapi/asm-generic/errno-base.h
+// 2. bionic/libc/kernel/uapi/asm-generic/errno.h
+enum LinuxErrno {
+ SYS_UNKNOWN = 0;
+ SYS_EPERM = 1; // Not super-user
+ SYS_ENOENT = 2; // No such file or directory
+ SYS_ESRCH = 3; // No such process
+ SYS_EINTR = 4; // Interrupted system call
+ SYS_EIO = 5; // I/O error
+ SYS_ENXIO = 6; // No such device or address
+ SYS_E2BIG = 7; // Arg list too long
+ SYS_ENOEXEC = 8; // Exec format error
+ SYS_EBADF = 9; // Bad file number
+ SYS_ECHILD = 10; // No children
+ SYS_EAGAIN = 11; // No more processes
+ SYS_ENOMEM = 12; // Not enough core
+ SYS_EACCES = 13; // Permission denied
+ SYS_EFAULT = 14; // Bad address
+ SYS_ENOTBLK = 15; // Block device required
+ SYS_EBUSY = 16; // Mount device busy
+ SYS_EEXIST = 17; // File exists
+ SYS_EXDEV = 18; // Cross-device link
+ SYS_ENODEV = 19; // No such device
+ SYS_ENOTDIR = 20; // Not a directory
+ SYS_EISDIR = 21; // Is a directory
+ SYS_EINVAL = 22; // Invalid argument
+ SYS_ENFILE = 23; // Too many open files in system
+ SYS_EMFILE = 24; // Too many open files
+ SYS_ENOTTY = 25; // Not a typewriter
+ SYS_ETXTBSY = 26; // Text file busy
+ SYS_EFBIG = 27; // File too large
+ SYS_ENOSPC = 28; // No space left on device
+ SYS_ESPIPE = 29; // Illegal seek
+ SYS_EROFS = 30; // Read only file system
+ SYS_EMLINK = 31; // Too many links
+ SYS_EPIPE = 32; // Broken pipe
+ SYS_EDOM = 33; // Math arg out of domain of func
+ SYS_ERANGE = 34; // Math result not representable
+ SYS_EDEADLOCK = 35; // File locking deadlock error
+ SYS_ENAMETOOLONG = 36; // File or path name too long
+ SYS_ENOLCK = 37; // No record locks available
+ SYS_ENOSYS = 38; // Function not implemented
+ SYS_ENOTEMPTY = 39; // Directory not empty
+ SYS_ELOOP = 40; // Too many symbolic links
+ SYS_ENOMSG = 42; // No message of desired type
+ SYS_EIDRM = 43; // Identifier removed
+ SYS_ECHRNG = 44; // Channel number out of range
+ SYS_EL2NSYNC = 45; // Level 2 not synchronized
+ SYS_EL3HLT = 46; // Level 3 halted
+ SYS_EL3RST = 47; // Level 3 reset
+ SYS_ELNRNG = 48; // Link number out of range
+ SYS_EUNATCH = 49; // rotocol driver not attached
+ SYS_ENOCSI = 50; // No CSI structure available
+ SYS_EL2HLT = 51; // Level 2 halted
+ SYS_EBADE = 52; // Invalid exchange
+ SYS_EBADR = 53; // Invalid request descriptor
+ SYS_EXFULL = 54; // Exchange full
+ SYS_ENOANO = 55; // No anode
+ SYS_EBADRQC = 56; // Invalid request code
+ SYS_EBADSLT = 57; // Invalid slot
+ SYS_EBFONT = 59; // Bad font file fmt
+ SYS_ENOSTR = 60; // Device not a stream
+ SYS_ENODATA = 61; // No data (for no delay io)
+ SYS_ETIME = 62; // Timer expired
+ SYS_ENOSR = 63; // Out of streams resources
+ SYS_ENONET = 64; // Machine is not on the network
+ SYS_ENOPKG = 65; // Package not installed
+ SYS_EREMOTE = 66; // The object is remote
+ SYS_ENOLINK = 67; // The link has been severed
+ SYS_EADV = 68; // Advertise error
+ SYS_ESRMNT = 69; // Srmount error
+ SYS_ECOMM = 70; // Communication error on send
+ SYS_EPROTO = 71; // Protocol error
+ SYS_EMULTIHOP = 72; // Multihop attempted
+ SYS_EDOTDOT = 73; // Cross mount point (not really error)
+ SYS_EBADMSG = 74; // Trying to read unreadable message
+ SYS_EOVERFLOW = 75; // Value too large for defined data type
+ SYS_ENOTUNIQ = 76; // Given log. name not unique
+ SYS_EBADFD = 77; // f.d. invalid for this operation
+ SYS_EREMCHG = 78; // Remote address changed
+ SYS_ELIBACC = 79; // Can't access a needed shared lib
+ SYS_ELIBBAD = 80; // Accessing a corrupted shared lib
+ SYS_ELIBSCN = 81; // .lib section in a.out corrupted
+ SYS_ELIBMAX = 82; // Attempting to link in too many libs
+ SYS_ELIBEXEC = 83; // Attempting to exec a shared library
+ SYS_EILSEQ = 84;
+ SYS_ERESTART = 85;
+ SYS_ESTRPIPE = 86;
+ SYS_EUSERS = 87;
+ SYS_ENOTSOCK = 88; // Socket operation on non-socket
+ SYS_EDESTADDRREQ = 89; // Destination address required
+ SYS_EMSGSIZE = 90; // Message too long
+ SYS_EPROTOTYPE = 91; // Protocol wrong type for socket
+ SYS_ENOPROTOOPT = 92; // Protocol not available
+ SYS_EPROTONOSUPPORT = 93; // Unknown protocol
+ SYS_ESOCKTNOSUPPORT = 94; // Socket type not supported
+ SYS_EOPNOTSUPP = 95; // Operation not supported on transport endpoint
+ SYS_EPFNOSUPPORT = 96; // Protocol family not supported
+ SYS_EAFNOSUPPORT = 97; // Address family not supported by protocol family
+ SYS_EADDRINUSE = 98; // Address already in use
+ SYS_EADDRNOTAVAIL = 99; // Address not available
+ SYS_ENETDOWN = 100; // Network interface is not configured
+ SYS_ENETUNREACH = 101; // Network is unreachable
+ SYS_ENETRESET = 102;
+ SYS_ECONNABORTED = 103; // Connection aborted
+ SYS_ECONNRESET = 104; // Connection reset by peer
+ SYS_ENOBUFS = 105; // No buffer space available
+ SYS_EISCONN = 106; // Socket is already connected
+ SYS_ENOTCONN = 107; // Socket is not connected
+ SYS_ESHUTDOWN = 108; // Can't send after socket shutdown
+ SYS_ETOOMANYREFS = 109;
+ SYS_ETIMEDOUT = 110; // Connection timed out
+ SYS_ECONNREFUSED = 111; // Connection refused
+ SYS_EHOSTDOWN = 112; // Host is down
+ SYS_EHOSTUNREACH = 113; // Host is unreachable
+ SYS_EALREADY = 114; // Socket already connected
+ SYS_EINPROGRESS = 115; // Connection already in progress
+ SYS_ESTALE = 116;
+ SYS_EUCLEAN = 117;
+ SYS_ENOTNAM = 118;
+ SYS_ENAVAIL = 119;
+ SYS_EISNAM = 120;
+ SYS_EREMOTEIO = 121;
+ SYS_EDQUOT = 122;
+ SYS_ENOMEDIUM = 123; // No medium (in tape drive)
+ SYS_EMEDIUMTYPE = 124;
+ SYS_ECANCELED = 125;
+ SYS_ENOKEY = 126;
+ SYS_EKEYEXPIRED = 127;
+ SYS_EKEYREVOKED = 128;
+ SYS_EKEYREJECTED = 129;
+ SYS_EOWNERDEAD = 130;
+ SYS_ENOTRECOVERABLE = 131;
+ SYS_ERFKILL = 132;
+ SYS_EHWPOISON = 133;
+}
+
message DnsQueryEvent {
optional android.stats.dnsresolver.NsRcode rcode = 1;
@@ -218,6 +357,8 @@ message DnsQueryEvent {
optional bool connected = 8;
optional int32 latency_micros = 9;
+
+ optional android.stats.dnsresolver.LinuxErrno linux_errno = 10;
}
message DnsQueryEvents {
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 93080e9a8016..8a7b515ee436 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3010,8 +3010,6 @@
</public-group>
<public-group type="string" first-id="0x01040025">
- <!-- @hide @SystemApi -->
- <public name="low_memory" />
</public-group>
<public-group type="bool" first-id="0x01110005">
@@ -3026,14 +3024,7 @@
<public-group type="array" first-id="0x01070006">
<!-- @hide @SystemApi -->
<public name="simColors" />
- <!-- @hide @SystemApi -->
- <public name="config_restrictedPreinstalledCarrierApps" />
- <!-- @hide @SystemApi -->
- <public name="config_sms_enabled_single_shift_tables" />
- <!-- @hide @SystemApi -->
- <public name="config_sms_enabled_locking_shift_tables" />
</public-group>
-
<!-- ===============================================================
DO NOT ADD UN-GROUPED ITEMS HERE
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 492ea68dd515..7f463807e1e9 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5421,4 +5421,236 @@
<!-- ChooserActivity - Alphabetically sorted apps list label. [CHAR LIMIT=NONE] -->
<string name="chooser_all_apps_button_label">Apps list</string>
+ <!-- Icc depersonalization related strings -->
+ <!-- Label text for PIN entry widget on SIM Network Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY">SIM network unlock PIN</string>
+ <!-- Label text for PIN entry widget on SIM Network Subset Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY">SIM network subset unlock PIN</string>
+ <!-- Label text for PIN entry widget on SIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY">SIM corporate unlock PIN</string>
+ <!-- Label text for PIN entry widget on SIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ENTRY">SIM service provider unlock PIN</string>
+ <!-- Label text for PIN entry widget on SIM SIM Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SIM_ENTRY">SIM unlock PIN</string>
+ <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for Subset PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for Corporate PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for SIM service provider PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for SIM PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SIM_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for PIN entry widget on RUIM Network1 Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_ENTRY">RUIM network1 unlock PIN</string>
+ <!-- Label text for PIN entry widget on RUIM Network2 Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_ENTRY">RUIM network2 unlock PIN</string>
+ <!-- Label text for PIN entry widget on RUIM Hrpd Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_HRPD_ENTRY">RUIM hrpd unlock PIN</string>
+ <!-- Label text for PIN entry widget on RUIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_ENTRY">RUIM corporate unlock PIN</string>
+ <!-- Label text for PIN entry widget on RUIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ENTRY">RUIM service provider unlock PIN</string>
+ <!-- Label text for PIN entry widget on RUIM RUIM Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_RUIM_ENTRY">RUIM unlock PIN</string>
+ <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ENTRY">Enter PUK</string>
+ <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ENTRY">Enter PUK</string>
+
+ <!-- Label text for PIN entry widget on SIM SPN Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SPN_ENTRY">SPN unlock PIN</string>
+ <!-- Label text for PIN entry widget on SIM SP EHPLMN Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ENTRY">SP Equivalent Home PLMN unlock PIN</string>
+ <!-- Label text for PIN entry widget on SIM ICCID Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_ICCID_ENTRY">ICCID unlock PIN</string>
+ <!-- Label text for PIN entry widget on SIM IMPI Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_IMPI_ENTRY">IMPI unlock PIN</string>
+ <!-- Label text for PIN entry widget on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NS_SP_ENTRY">Network subset service provider unlock PIN</string>
+
+ <!-- Status message displayed on SIM Network Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_IN_PROGRESS">Requesting SIM network unlock\u2026</string>
+ <!-- Status message displayed on SIM Network Subset Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_IN_PROGRESS">Requesting SIM network subset unlock
+\u2026</string>
+ <!-- Status message displayed on SIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_IN_PROGRESS">Requesting SIM service provider un
+lock\u2026</string>
+ <!-- Status message displayed on SIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_IN_PROGRESS">Requesting SIM corporate unlock\u2026</string>
+ <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on Corporate PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on SIM Service provider PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on SIM PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SIM_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on SIM SIM Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SIM_IN_PROGRESS">Requesting SIM unlock\u2026</string>
+ <!-- Status message displayed on RUIM Network1 Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_IN_PROGRESS">Requesting RUIM network1 unlock\u2026</string>
+ <!-- Status message displayed on RUIM Network2 Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_IN_PROGRESS">Requesting RUIM network2 unlock\u2026</string>
+ <!-- Status message displayed on RUIM Hrpd Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_HRPD_IN_PROGRESS">Requesting RUIM hrpd unlock\u2026</string>
+ <!-- Status message displayed on RUIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_IN_PROGRESS">Requesting RUIM service provider
+unlock\u2026</string>
+ <!-- Status message displayed on RUIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_IN_PROGRESS">Requesting RUIM corporate unlock\u2026</string>
+
+ <!-- Status message displayed on SIM SPN Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SPN_IN_PROGRESS">Requesting SPN unlock\u2026</string>
+ <!-- Status message displayed on SIM SP EHPLMN Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_IN_PROGRESS">Requesting SP Equivalent Home PLMN unlock\u2026</string>
+ <!-- Status message displayed on SIM ICCID Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_ICCID_IN_PROGRESS">Requesting ICCID unlock\u2026</string>
+ <!-- Status message displayed on SIM IMPI Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_IMPI_IN_PROGRESS">Requesting IMPI unlock\u2026</string>
+ <!-- Status message displayed on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NS_SP_IN_PROGRESS">Requesting Network subset service provider unlock\u2026</string>
+
+ <!-- Status message displayed on RUIM RUIM Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_RUIM_IN_PROGRESS">Requesting RUIM unlock\u2026</string>
+ <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+ <!-- Error message displayed on SIM Network Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_ERROR">SIM Network unlock request unsuccessful.</string>
+ <!-- Error message displayed on SIM Network Subset Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ERROR">SIM Network Subset unlock request unsucces
+sful.</string>
+ <!-- Error message displayed on SIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ERROR">SIM Service Provider unlock request unsu
+ccessful.</string>
+ <!-- Error message displayed on SIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_ERROR">SIM Corporate unlock request unsuccessful.</string>
+ <!-- Error message displayed on SIM SIM Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SIM_ERROR">SIM unlock request unsuccessful.</string>
+ <!-- Error message displayed on RUIM Network1 Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_ERROR">RUIM Network1 unlock request unsuccessful.</string>
+ <!-- Error message displayed on RUIM Network2 Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_ERROR">RUIM Network2 unlock request unsuccessful.</string>
+ <!-- Error message displayed on RUIM Hrpd Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_HRPD_ERROR">RUIM Hrpd unlock request unsuccessful.</string>
+ <!-- Error message displayed on RUIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_ERROR">RUIM Corporate unlock request unsuccessful.</string>
+ <!-- Error message displayed on RUIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ERROR">RUIM Service Provider unlock request un
+successful.</string>
+ <!-- Error message displayed on RUIM RUIM Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_RUIM_ERROR">RUIM unlock request unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SIM_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ERROR">PUK unlock unsuccessful.</string>
+ <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ERROR">PUK unlock unsuccessful.</string>
+
+ <!-- Error message displayed on SIM SPN Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SPN_ERROR">SPN unlock request unsuccessful.</string>
+ <!-- Error message displayed on SIM SP EHPLMN Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ERROR">SP Equivalent Home PLMN unlock request unsuccessful.</string>
+ <!-- Error message displayed on SIM ICCID Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_ICCID_ERROR">ICCID unlock request unsuccessful.</string>
+ <!-- Error message displayed on SIM IMPI Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_IMPI_ERROR">IMPI unlock request unsuccessful.</string>
+ <!-- Error message displayed on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NS_SP_ERROR">Network subset service provider unlock request unsuccessful.</string>
+
+ <!-- Success message displayed on SIM Network Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUCCESS">SIM Network unlock successful.</string>
+ <!-- Success message displayed on SIM Network Subset Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_SUCCESS">SIM Network Subset unlock successful.</string>
+ <!-- Success message displayed on SIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_SUCCESS">SIM Service Provider unlock successful
+.</string>
+ <!-- Success message displayed on SIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_SUCCESS">SIM Corporate unlock successful.</string>
+ <!-- Success message displayed on SIM SIM Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SIM_SUCCESS">SIM unlock successful.</string>
+ <!-- Success message displayed on RUIM Network1 Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_SUCCESS">RUIM Network1 unlock successful.</string>
+ <!-- Success message displayed on RUIM Network2 Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_SUCCESS">RUIM Network2 unlock successful.</string>
+ <!-- Success message displayed on RUIM Hrpd Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_HRPD_SUCCESS">RUIM Hrpd unlock successful.</string>
+ <!-- Success message displayed on RUIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_SUCCESS">RUIM Service Provider unlock successf
+ul.</string>
+ <!-- Success message displayed on RUIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_SUCCESS">RUIM Corporate unlock successful.</string>
+ <!-- Success message displayed on RUIM RUIM Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_RUIM_SUCCESS">RUIM unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SIM_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_SUCCESS">PUK unlock successful.</string>
+ <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_SUCCESS">PUK unlock successful.</string>
+
+ <!-- Success message displayed on SIM SPN Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SPN_SUCCESS">SPN unlock successful.</string>
+ <!-- Success message displayed on SIM SP EHPLMN Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_SUCCESS">SP Equivalent Home PLMN unlock successful.</string>
+ <!-- Success message displayed on SIM ICCID Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_ICCID_SUCCESS">ICCID unlock successful.</string>
+ <!-- Success message displayed on SIM IMPI Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_IMPI_SUCCESS">IMPI unlock successful.</string>
+ <!-- Success message displayed on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
+ <string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS">Network subset service provider unlock successful.</string>
</resources>
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index d282744bc3a0..e9de02e82432 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -57,7 +57,6 @@ platform cert need to be included, as apps signed with the platform cert are exe
<hidden-api-whitelisted-app package="com.android.terminal" />
<hidden-api-whitelisted-app package="com.android.wallpaper" />
<hidden-api-whitelisted-app package="jp.co.omronsoft.openwnn" />
- <!-- STOPSHIP: Remove this when fixing all @hide usage for tethering.-->
- <hidden-api-whitelisted-app package="com.android.networkstack.tethering" />
+ <!-- TODO: Remove NetworkStack whitelisting -->
<hidden-api-whitelisted-app package="com.android.networkstack" />
</config>
diff --git a/libs/androidfw/OWNERS b/libs/androidfw/OWNERS
index 8cffd6a3e548..bc056df23a36 100644
--- a/libs/androidfw/OWNERS
+++ b/libs/androidfw/OWNERS
@@ -3,4 +3,4 @@ toddke@google.com
rtmitchell@google.com
per-file CursorWindow.cpp=omakoto@google.com
-per-file LocaleDataTables.cpp=vichang@google.com,tobiast@google.com,nikitai@google.com
+per-file LocaleDataTables.cpp=vichang@google.com,ngeoffray@google.com,nikitai@google.com
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 94d32c63edb1..59943eb546b4 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -4213,6 +4213,7 @@ public class AudioManager {
* {@hide}
*/
@UnsupportedAppUsage
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void setWiredDeviceConnectionState(int type, int state, String address, String name) {
final IAudioService service = getService();
try {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index d17f242d5d63..a1fba4a018e2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -174,7 +174,7 @@ public class HearingAidProfile implements LocalBluetoothProfile {
@Override
public boolean isEnabled(BluetoothDevice device) {
- if (mService == null) {
+ if (mService == null || device == null) {
return false;
}
return mService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN;
@@ -182,7 +182,7 @@ public class HearingAidProfile implements LocalBluetoothProfile {
@Override
public int getConnectionPolicy(BluetoothDevice device) {
- if (mService == null) {
+ if (mService == null || device == null) {
return CONNECTION_POLICY_FORBIDDEN;
}
return mService.getConnectionPolicy(device);
@@ -191,7 +191,7 @@ public class HearingAidProfile implements LocalBluetoothProfile {
@Override
public boolean setEnabled(BluetoothDevice device, boolean enabled) {
boolean isEnabled = false;
- if (mService == null) {
+ if (mService == null || device == null) {
return false;
}
if (enabled) {
@@ -213,7 +213,7 @@ public class HearingAidProfile implements LocalBluetoothProfile {
}
public long getHiSyncId(BluetoothDevice device) {
- if (mService == null) {
+ if (mService == null || device == null) {
return BluetoothHearingAid.HI_SYNC_ID_INVALID;
}
return mService.getHiSyncId(device);
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 656827a80117..c8cf7f503468 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -4,7 +4,6 @@ dsandler@android.com
adamcohen@google.com
asc@google.com
-ashaikh@google.com
beverlyt@google.com
brockman@google.com
cinek@google.com
@@ -12,8 +11,8 @@ cwren@google.com
dupin@google.com
ethibodeau@google.com
evanlaird@google.com
+hwwang@google.com
hyunyoungs@google.com
-jmonk@google.com
jaggies@google.com
jjaggi@google.com
joshmcgrath@google.com
@@ -29,16 +28,16 @@ mrcasey@google.com
mrenouf@google.com
nbenbernou@google.com
nesciosquid@google.com
-ngmatthew@google.com
ogunwale@google.com
+peanutbutter@google.com
pixel@google.com
roosa@google.com
-shahrk@google.com
snoeberger@google.com
steell@google.com
stwu@google.com
sunnygoyal@google.com
susikp@google.com
+tracyzhou@google.com
tsuji@google.com
twickham@google.com
winsonc@google.com
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index 2fbba68f1e03..00d0d9c428ff 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -60,6 +60,7 @@ java_library {
hostdex: true, // for hiddenapi check
visibility: ["//frameworks/base/packages/Tethering:__subpackages__"],
apex_available: ["com.android.tethering"],
+ permitted_packages: ["android.net"],
}
stubs_defaults {
diff --git a/packages/Tethering/common/TetheringLib/api/system-current.txt b/packages/Tethering/common/TetheringLib/api/system-current.txt
index 2f5ea6af719a..edd1ebb5f751 100644
--- a/packages/Tethering/common/TetheringLib/api/system-current.txt
+++ b/packages/Tethering/common/TetheringLib/api/system-current.txt
@@ -23,7 +23,6 @@ package android.net {
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
index b70165ab74b4..0107a7ef5b59 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
@@ -571,9 +571,8 @@ public class TetheringManager {
/**
* Configure tethering with static IPv4 assignment.
*
- * The clientAddress must be in the localIPv4Address prefix. A DHCP server will be
- * started, but will only be able to offer the client address. The two addresses must
- * be in the same prefix.
+ * A DHCP server will be started, but will only be able to offer the client address.
+ * The two addresses must be in the same prefix.
*
* @param localIPv4Address The preferred local IPv4 link address to use.
* @param clientAddress The static client address.
@@ -584,10 +583,7 @@ public class TetheringManager {
@NonNull final LinkAddress clientAddress) {
Objects.requireNonNull(localIPv4Address);
Objects.requireNonNull(clientAddress);
- if (localIPv4Address.getPrefixLength() != clientAddress.getPrefixLength()
- || !localIPv4Address.isIpv4() || !clientAddress.isIpv4()
- || !new IpPrefix(localIPv4Address.toString()).equals(
- new IpPrefix(clientAddress.toString()))) {
+ if (!checkStaticAddressConfiguration(localIPv4Address, clientAddress)) {
throw new IllegalArgumentException("Invalid server or client addresses");
}
@@ -657,6 +653,19 @@ public class TetheringManager {
}
/**
+ * Check whether the two addresses are ipv4 and in the same prefix.
+ * @hide
+ */
+ public static boolean checkStaticAddressConfiguration(
+ @NonNull final LinkAddress localIPv4Address,
+ @NonNull final LinkAddress clientAddress) {
+ return localIPv4Address.getPrefixLength() == clientAddress.getPrefixLength()
+ && localIPv4Address.isIpv4() && clientAddress.isIpv4()
+ && new IpPrefix(localIPv4Address.toString()).equals(
+ new IpPrefix(clientAddress.toString()));
+ }
+
+ /**
* Get a TetheringRequestParcel from the configuration
* @hide
*/
@@ -739,11 +748,13 @@ public class TetheringManager {
* @param type The tethering type, on of the {@code TetheringManager#TETHERING_*} constants.
* @param executor {@link Executor} to specify the thread upon which the callback of
* TetheringRequest will be invoked.
+ * @hide
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.TETHER_PRIVILEGED,
android.Manifest.permission.WRITE_SETTINGS
})
+ @SystemApi(client = MODULE_LIBRARIES)
public void startTethering(int type, @NonNull final Executor executor,
@NonNull final StartTetheringCallback callback) {
startTethering(new TetheringRequest.Builder(type).build(), executor, callback);
diff --git a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
index d6bc063210b3..82a26beadacf 100644
--- a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
+++ b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
@@ -18,10 +18,12 @@ package android.net.dhcp;
import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import android.annotation.NonNull;
import android.net.LinkAddress;
import android.util.ArraySet;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import java.net.Inet4Address;
import java.util.Collection;
import java.util.Collections;
@@ -160,6 +162,17 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel {
return this;
}
+ /**
+ * Set the client address to tell DHCP server only offer this address.
+ * The client's prefix length is the same as server's.
+ *
+ * <p>If not set, the default value is null.
+ */
+ public DhcpServingParamsParcelExt setSingleClientAddr(@Nullable Inet4Address clientAddr) {
+ this.clientAddr = clientAddr == null ? 0 : inet4AddressToIntHTH(clientAddr);
+ return this;
+ }
+
private static int[] toIntArray(@NonNull Collection<Inet4Address> addrs) {
int[] res = new int[addrs.size()];
int i = 0;
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index c5478d2e1a14..82b17acae592 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -18,6 +18,7 @@ package android.net.ip;
import static android.net.InetAddresses.parseNumericAddress;
import static android.net.RouteInfo.RTN_UNICAST;
+import static android.net.TetheringManager.TetheringRequest.checkStaticAddressConfiguration;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
import static android.net.util.NetworkConstants.FF;
@@ -492,17 +493,24 @@ public class IpServer extends StateMachine {
}
}
- private boolean startDhcp(Inet4Address addr, int prefixLen) {
+ private boolean startDhcp(final LinkAddress serverLinkAddr, final LinkAddress clientLinkAddr) {
if (mUsingLegacyDhcp) {
return true;
}
+
+ final Inet4Address addr = (Inet4Address) serverLinkAddr.getAddress();
+ final int prefixLen = serverLinkAddr.getPrefixLength();
+ final Inet4Address clientAddr = clientLinkAddr == null ? null :
+ (Inet4Address) clientLinkAddr.getAddress();
+
final DhcpServingParamsParcel params;
params = new DhcpServingParamsParcelExt()
.setDefaultRouters(addr)
.setDhcpLeaseTimeSecs(DHCP_LEASE_TIME_SECS)
.setDnsServers(addr)
- .setServerAddr(new LinkAddress(addr, prefixLen))
- .setMetered(true);
+ .setServerAddr(serverLinkAddr)
+ .setMetered(true)
+ .setSingleClientAddr(clientAddr);
// TODO: also advertise link MTU
mDhcpServerStartIndex++;
@@ -537,9 +545,10 @@ public class IpServer extends StateMachine {
}
}
- private boolean configureDhcp(boolean enable, Inet4Address addr, int prefixLen) {
+ private boolean configureDhcp(boolean enable, final LinkAddress serverAddr,
+ final LinkAddress clientAddr) {
if (enable) {
- return startDhcp(addr, prefixLen);
+ return startDhcp(serverAddr, clientAddr);
} else {
stopDhcp();
return true;
@@ -587,7 +596,7 @@ public class IpServer extends StateMachine {
// code that calls into NetworkManagementService directly.
srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR);
mIpv4Address = new LinkAddress(srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
- return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
+ return configureDhcp(enabled, mIpv4Address, null /* clientAddress */);
}
mIpv4Address = new LinkAddress(srvAddr, prefixLen);
} catch (IllegalArgumentException e) {
@@ -624,7 +633,7 @@ public class IpServer extends StateMachine {
mLinkProperties.removeRoute(route);
}
- return configureDhcp(enabled, srvAddr, prefixLen);
+ return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr);
}
private String getRandomWifiIPv4Address() {
@@ -945,7 +954,14 @@ public class IpServer extends StateMachine {
}
private void maybeConfigureStaticIp(final TetheringRequestParcel request) {
- if (request == null) return;
+ // Ignore static address configuration if they are invalid or null. In theory, static
+ // addresses should not be invalid here because TetheringManager do not allow caller to
+ // specify invalid static address configuration.
+ if (request == null || request.localIPv4Address == null
+ || request.staticClientAddress == null || !checkStaticAddressConfiguration(
+ request.localIPv4Address, request.staticClientAddress)) {
+ return;
+ }
mStaticIpv4ServerAddr = request.localIPv4Address;
mStaticIpv4ClientAddr = request.staticClientAddress;
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index 3dcc15f92c06..343ed4b16cd6 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -303,31 +303,26 @@ public class Tethering {
final UserManager userManager = (UserManager) mContext.getSystemService(
Context.USER_SERVICE);
- mTetheringRestriction = new UserRestrictionActionListener(userManager, this);
+ mTetheringRestriction = new UserRestrictionActionListener(
+ userManager, this, mNotificationUpdater);
mExecutor = new TetheringThreadExecutor(mHandler);
mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
+ mNetdCallback = new NetdCallback();
// Load tethering configuration.
updateConfiguration();
- // NetdCallback should be registered after updateConfiguration() to ensure
- // TetheringConfiguration is created.
- mNetdCallback = new NetdCallback();
+ }
+
+ /**
+ * Start to register callbacks.
+ * Call this function when tethering is ready to handle callback events.
+ */
+ public void startStateMachineUpdaters() {
try {
mNetd.registerUnsolicitedEventListener(mNetdCallback);
} catch (RemoteException e) {
mLog.e("Unable to register netd UnsolicitedEventListener");
}
-
- startStateMachineUpdaters(mHandler);
- startTrackDefaultNetwork();
-
- final WifiManager wifiManager = getWifiManager();
- if (wifiManager != null) {
- wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback());
- }
- }
-
- private void startStateMachineUpdaters(Handler handler) {
mCarrierConfigChange.startListening();
mContext.getSystemService(TelephonyManager.class).listen(mActiveDataSubIdListener,
PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
@@ -340,7 +335,14 @@ public class Tethering {
filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED);
- mContext.registerReceiver(mStateReceiver, filter, null, handler);
+ mContext.registerReceiver(mStateReceiver, filter, null, mHandler);
+
+ final WifiManager wifiManager = getWifiManager();
+ if (wifiManager != null) {
+ wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback());
+ }
+
+ startTrackDefaultNetwork();
}
private class TetheringThreadExecutor implements Executor {
@@ -369,9 +371,10 @@ public class Tethering {
mActiveDataSubId = subId;
updateConfiguration();
+ mNotificationUpdater.onActiveDataSubscriptionIdChanged(subId);
// To avoid launching unexpected provisioning checks, ignore re-provisioning
// when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning()
- // ill be triggered again when CarrierConfig is loaded.
+ // will be triggered again when CarrierConfig is loaded.
if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
} else {
@@ -431,9 +434,7 @@ public class Tethering {
// Called by wifi when the number of soft AP clients changed.
@Override
public void onConnectedClientsChanged(final List<WifiClient> clients) {
- if (mConnectedClientsTracker.updateConnectedClients(mForwardedDownstreams, clients)) {
- reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
- }
+ updateConnectedClients(clients);
}
}
@@ -635,7 +636,10 @@ public class Tethering {
Context.ETHERNET_SERVICE);
synchronized (mPublicSync) {
if (enable) {
- if (mEthernetCallback != null) return TETHER_ERROR_NO_ERROR;
+ if (mEthernetCallback != null) {
+ Log.d(TAG, "Ethernet tethering already started");
+ return TETHER_ERROR_NO_ERROR;
+ }
mEthernetCallback = new EthernetCallback();
mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback);
@@ -996,11 +1000,14 @@ public class Tethering {
protected static class UserRestrictionActionListener {
private final UserManager mUserManager;
private final Tethering mWrapper;
+ private final TetheringNotificationUpdater mNotificationUpdater;
public boolean mDisallowTethering;
- public UserRestrictionActionListener(UserManager um, Tethering wrapper) {
+ public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper,
+ @NonNull TetheringNotificationUpdater updater) {
mUserManager = um;
mWrapper = wrapper;
+ mNotificationUpdater = updater;
mDisallowTethering = false;
}
@@ -1019,13 +1026,21 @@ public class Tethering {
return;
}
- // TODO: Add user restrictions notification.
- final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0);
-
- if (newlyDisallowed && isTetheringActiveOnDevice) {
- mWrapper.untetherAll();
- // TODO(b/148139325): send tetheringSupported on restriction change
+ if (!newlyDisallowed) {
+ // Clear the restricted notification when user is allowed to have tethering
+ // function.
+ mNotificationUpdater.tetheringRestrictionLifted();
+ return;
}
+
+ // Restricted notification is shown when tethering function is disallowed on
+ // user's device.
+ mNotificationUpdater.notifyTetheringDisabledByRestriction();
+
+ // Untether from all downstreams since tethering is disallowed.
+ mWrapper.untetherAll();
+
+ // TODO(b/148139325): send tetheringSupported on restriction change
}
}
@@ -1494,7 +1509,7 @@ public class Tethering {
} else {
dnsServers = mConfig.defaultIPv4DNS;
}
- final int netId = (network != null) ? network.netId : NETID_UNSET;
+ final int netId = (network != null) ? network.getNetId() : NETID_UNSET;
try {
mNetd.tetherDnsSet(netId, dnsServers);
mLog.log(String.format(
@@ -1559,6 +1574,7 @@ public class Tethering {
mIPv6TetheringCoordinator.removeActiveDownstream(who);
mOffload.excludeDownstreamInterface(who.interfaceName());
mForwardedDownstreams.remove(who);
+ updateConnectedClients(null /* wifiClients */);
// If this is a Wi-Fi interface, tell WifiManager of any errors
// or the inactive serving state.
@@ -2141,6 +2157,12 @@ public class Tethering {
return false;
}
+ private void updateConnectedClients(final List<WifiClient> wifiClients) {
+ if (mConnectedClientsTracker.updateConnectedClients(mForwardedDownstreams, wifiClients)) {
+ reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
+ }
+ }
+
private IpServer.Callback makeControlCallback() {
return new IpServer.Callback() {
@Override
@@ -2155,10 +2177,7 @@ public class Tethering {
@Override
public void dhcpLeasesChanged() {
- if (mConnectedClientsTracker.updateConnectedClients(
- mForwardedDownstreams, null /* wifiClients */)) {
- reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
- }
+ updateConnectedClients(null /* wifiClients */);
}
};
}
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java
index b97f75268a3b..992cdd8de6a7 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java
@@ -29,12 +29,14 @@ import android.content.Intent;
import android.content.res.Resources;
import android.os.UserHandle;
import android.provider.Settings;
+import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import androidx.annotation.ArrayRes;
import androidx.annotation.DrawableRes;
+import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
@@ -54,10 +56,15 @@ import com.android.networkstack.tethering.R;
public class TetheringNotificationUpdater {
private static final String TAG = TetheringNotificationUpdater.class.getSimpleName();
private static final String CHANNEL_ID = "TETHERING_STATUS";
+ private static final String WIFI_DOWNSTREAM = "WIFI";
+ private static final String USB_DOWNSTREAM = "USB";
+ private static final String BLUETOOTH_DOWNSTREAM = "BT";
private static final boolean NOTIFY_DONE = true;
private static final boolean NO_NOTIFY = false;
// Id to update and cancel tethering notification. Must be unique within the tethering app.
- private static final int NOTIFY_ID = 20191115;
+ private static final int ENABLE_NOTIFICATION_ID = 1000;
+ // Id to update and cancel restricted notification. Must be unique within the tethering app.
+ private static final int RESTRICTED_NOTIFICATION_ID = 1001;
@VisibleForTesting
static final int NO_ICON_ID = 0;
@VisibleForTesting
@@ -65,14 +72,25 @@ public class TetheringNotificationUpdater {
private final Context mContext;
private final NotificationManager mNotificationManager;
private final NotificationChannel mChannel;
- // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2.
- // This value has to be made 1 2 and 4, and OR'd with the others.
+
// WARNING : the constructor is called on a different thread. Thread safety therefore
// relies on this value being initialized to 0, and not any other value. If you need
// to change this, you will need to change the thread where the constructor is invoked,
// or to introduce synchronization.
+ // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2.
+ // This value has to be made 1 2 and 4, and OR'd with the others.
private int mDownstreamTypesMask = DOWNSTREAM_NONE;
+ // WARNING : this value is not able to being initialized to 0 and must have volatile because
+ // telephony service is not guaranteed that is up before tethering service starts. If telephony
+ // is up later than tethering, TetheringNotificationUpdater will use incorrect and valid
+ // subscription id(0) to query resources. Therefore, initialized subscription id must be
+ // INVALID_SUBSCRIPTION_ID.
+ private volatile int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+ @IntDef({ENABLE_NOTIFICATION_ID, RESTRICTED_NOTIFICATION_ID})
+ @interface NotificationId {}
+
public TetheringNotificationUpdater(@NonNull final Context context) {
mContext = context;
mNotificationManager = (NotificationManager) context.createContextAsUser(UserHandle.ALL, 0)
@@ -88,19 +106,46 @@ public class TetheringNotificationUpdater {
public void onDownstreamChanged(@IntRange(from = 0, to = 7) final int downstreamTypesMask) {
if (mDownstreamTypesMask == downstreamTypesMask) return;
mDownstreamTypesMask = downstreamTypesMask;
- updateNotification();
+ updateEnableNotification();
+ }
+
+ /** Called when active data subscription id changed */
+ public void onActiveDataSubscriptionIdChanged(final int subId) {
+ if (mActiveDataSubId == subId) return;
+ mActiveDataSubId = subId;
+ updateEnableNotification();
}
- private void updateNotification() {
+ @VisibleForTesting
+ Resources getResourcesForSubId(@NonNull final Context c, final int subId) {
+ return SubscriptionManager.getResourcesForSubId(c, subId);
+ }
+
+ private void updateEnableNotification() {
final boolean tetheringInactive = mDownstreamTypesMask <= DOWNSTREAM_NONE;
if (tetheringInactive || setupNotification() == NO_NOTIFY) {
- clearNotification();
+ clearNotification(ENABLE_NOTIFICATION_ID);
}
}
- private void clearNotification() {
- mNotificationManager.cancel(null /* tag */, NOTIFY_ID);
+ @VisibleForTesting
+ void tetheringRestrictionLifted() {
+ clearNotification(RESTRICTED_NOTIFICATION_ID);
+ }
+
+ private void clearNotification(@NotificationId final int id) {
+ mNotificationManager.cancel(null /* tag */, id);
+ }
+
+ @VisibleForTesting
+ void notifyTetheringDisabledByRestriction() {
+ final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
+ final String title = res.getString(R.string.disable_tether_notification_title);
+ final String message = res.getString(R.string.disable_tether_notification_message);
+
+ showNotification(R.drawable.stat_sys_tether_general, title, message,
+ RESTRICTED_NOTIFICATION_ID);
}
/**
@@ -110,16 +155,17 @@ public class TetheringNotificationUpdater {
*
* @return downstream types mask value.
*/
+ @VisibleForTesting
@IntRange(from = 0, to = 7)
- private int getDownstreamTypesMask(@NonNull final String types) {
+ int getDownstreamTypesMask(@NonNull final String types) {
int downstreamTypesMask = DOWNSTREAM_NONE;
final String[] downstreams = types.split("\\|");
for (String downstream : downstreams) {
- if ("USB".equals(downstream.trim())) {
+ if (USB_DOWNSTREAM.equals(downstream.trim())) {
downstreamTypesMask |= (1 << TETHERING_USB);
- } else if ("WIFI".equals(downstream.trim())) {
+ } else if (WIFI_DOWNSTREAM.equals(downstream.trim())) {
downstreamTypesMask |= (1 << TETHERING_WIFI);
- } else if ("BT".equals(downstream.trim())) {
+ } else if (BLUETOOTH_DOWNSTREAM.equals(downstream.trim())) {
downstreamTypesMask |= (1 << TETHERING_BLUETOOTH);
}
}
@@ -134,9 +180,8 @@ public class TetheringNotificationUpdater {
*
* @return {@link android.util.SparseArray} with downstream types and icon id info.
*/
- @NonNull
- private SparseArray<Integer> getIcons(@ArrayRes int id) {
- final Resources res = mContext.getResources();
+ @VisibleForTesting
+ SparseArray<Integer> getIcons(@ArrayRes int id, @NonNull Resources res) {
final String[] array = res.getStringArray(id);
final SparseArray<Integer> icons = new SparseArray<>();
for (String config : array) {
@@ -161,8 +206,9 @@ public class TetheringNotificationUpdater {
}
private boolean setupNotification() {
- final Resources res = mContext.getResources();
- final SparseArray<Integer> downstreamIcons = getIcons(R.array.tethering_notification_icons);
+ final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
+ final SparseArray<Integer> downstreamIcons =
+ getIcons(R.array.tethering_notification_icons, res);
final int iconId = downstreamIcons.get(mDownstreamTypesMask, NO_ICON_ID);
if (iconId == NO_ICON_ID) return NO_NOTIFY;
@@ -170,12 +216,12 @@ public class TetheringNotificationUpdater {
final String title = res.getString(R.string.tethering_notification_title);
final String message = res.getString(R.string.tethering_notification_message);
- showNotification(iconId, title, message);
+ showNotification(iconId, title, message, ENABLE_NOTIFICATION_ID);
return NOTIFY_DONE;
}
private void showNotification(@DrawableRes final int iconId, @NonNull final String title,
- @NonNull final String message) {
+ @NonNull final String message, @NotificationId final int id) {
final Intent intent = new Intent(Settings.ACTION_TETHER_SETTINGS);
final PendingIntent pi = PendingIntent.getActivity(
mContext.createContextAsUser(UserHandle.CURRENT, 0),
@@ -193,6 +239,6 @@ public class TetheringNotificationUpdater {
.setContentIntent(pi)
.build();
- mNotificationManager.notify(null /* tag */, NOTIFY_ID, notification);
+ mNotificationManager.notify(null /* tag */, id, notification);
}
}
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java
index c5329d8d3316..c30be25dbd22 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java
@@ -80,6 +80,7 @@ public class TetheringService extends Service {
mContext = mDeps.getContext();
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mTethering = makeTethering(mDeps);
+ mTethering.startStateMachineUpdaters();
}
/**
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 7ac7f5f06e50..45bb4ab6e5f7 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -586,21 +586,21 @@ public class UpstreamNetworkMonitor {
*/
@VisibleForTesting
public static NetworkCapabilities networkCapabilitiesForType(int type) {
- final NetworkCapabilities nc = new NetworkCapabilities();
+ final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
// Map from type to transports.
final int notFound = -1;
final int transport = sLegacyTypeToTransport.get(type, notFound);
Preconditions.checkArgument(transport != notFound, "unknown legacy type: " + type);
- nc.addTransportType(transport);
+ builder.addTransportType(transport);
if (type == TYPE_MOBILE_DUN) {
- nc.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
+ builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
// DUN is restricted network, see NetworkCapabilities#FORCE_RESTRICTED_CAPABILITIES.
- nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
} else {
- nc.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
}
- return nc;
+ return builder.build();
}
}
diff --git a/packages/Tethering/tests/integration/Android.bp b/packages/Tethering/tests/integration/Android.bp
new file mode 100644
index 000000000000..1a1c30d1d5f9
--- /dev/null
+++ b/packages/Tethering/tests/integration/Android.bp
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+android_test {
+ name: "TetheringIntegrationTests",
+ certificate: "platform",
+ platform_apis: true,
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
+ test_suites: [
+ "device-tests",
+ "mts",
+ ],
+ static_libs: [
+ "NetworkStackApiStableLib",
+ "androidx.test.rules",
+ "frameworks-base-testutils",
+ "mockito-target-extended-minus-junit4",
+ "net-tests-utils",
+ "testables",
+ ],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ ],
+}
diff --git a/packages/Tethering/tests/integration/AndroidManifest.xml b/packages/Tethering/tests/integration/AndroidManifest.xml
new file mode 100644
index 000000000000..233ba40b5d35
--- /dev/null
+++ b/packages/Tethering/tests/integration/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.networkstack.tethering.tests.integration">
+
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.TETHER_PRIVILEGED"/>
+
+ <application android:debuggable="true">
+ <uses-library android:name="android.test.runner" />
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.networkstack.tethering.tests.integration"
+ android:label="Tethering integration tests">
+ </instrumentation>
+</manifest>
diff --git a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
new file mode 100644
index 000000000000..492ce3db3424
--- /dev/null
+++ b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -0,0 +1,459 @@
+/*
+ * 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.
+ */
+
+package android.net;
+
+import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
+import static android.Manifest.permission.NETWORK_SETTINGS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.net.EthernetManager.TetheredInterfaceCallback;
+import android.net.EthernetManager.TetheredInterfaceRequest;
+import android.net.TetheringManager.StartTetheringCallback;
+import android.net.TetheringManager.TetheringEventCallback;
+import android.net.TetheringManager.TetheringRequest;
+import android.net.dhcp.DhcpAckPacket;
+import android.net.dhcp.DhcpOfferPacket;
+import android.net.dhcp.DhcpPacket;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.SystemClock;
+import android.system.Os;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.TapPacketReader;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileDescriptor;
+import java.net.Inet4Address;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class EthernetTetheringTest {
+
+ private static final String TAG = EthernetTetheringTest.class.getSimpleName();
+ private static final int TIMEOUT_MS = 1000;
+ private static final int PACKET_READ_TIMEOUT_MS = 100;
+ private static final int DHCP_DISCOVER_ATTEMPTS = 10;
+ private static final byte[] DHCP_REQUESTED_PARAMS = new byte[] {
+ DhcpPacket.DHCP_SUBNET_MASK,
+ DhcpPacket.DHCP_ROUTER,
+ DhcpPacket.DHCP_DNS_SERVER,
+ DhcpPacket.DHCP_LEASE_TIME,
+ };
+ private static final String DHCP_HOSTNAME = "testhostname";
+
+ private final Context mContext = InstrumentationRegistry.getContext();
+ private final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
+ private final TetheringManager mTm = mContext.getSystemService(TetheringManager.class);
+
+ private TestNetworkInterface mTestIface;
+ private HandlerThread mHandlerThread;
+ private Handler mHandler;
+ private TapPacketReader mTapPacketReader;
+
+ private TetheredInterfaceRequester mTetheredInterfaceRequester;
+ private MyTetheringEventCallback mTetheringEventCallback;
+
+ private UiAutomation mUiAutomation =
+ InstrumentationRegistry.getInstrumentation().getUiAutomation();
+
+ @Before
+ public void setUp() throws Exception {
+ mHandlerThread = new HandlerThread(getClass().getSimpleName());
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ mTetheredInterfaceRequester = new TetheredInterfaceRequester(mHandler, mEm);
+ // Needed to create a TestNetworkInterface, to call requestTetheredInterface, and to receive
+ // tethered client callbacks.
+ mUiAutomation.adoptShellPermissionIdentity(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS);
+ }
+
+ private void cleanUp() throws Exception {
+ mTm.stopTethering(TetheringManager.TETHERING_ETHERNET);
+ if (mTetheringEventCallback != null) {
+ mTetheringEventCallback.awaitInterfaceUntethered();
+ mTetheringEventCallback.unregister();
+ mTetheringEventCallback = null;
+ }
+ if (mTapPacketReader != null) {
+ TapPacketReader reader = mTapPacketReader;
+ mHandler.post(() -> reader.stop());
+ mTapPacketReader = null;
+ }
+ mHandlerThread.quitSafely();
+ mTetheredInterfaceRequester.release();
+ mEm.setIncludeTestInterfaces(false);
+ maybeDeleteTestInterface();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ try {
+ cleanUp();
+ } finally {
+ mUiAutomation.dropShellPermissionIdentity();
+ }
+ }
+
+ @Test
+ public void testVirtualEthernetAlreadyExists() throws Exception {
+ // This test requires manipulating packets. Skip if there is a physical Ethernet connected.
+ assumeFalse(mEm.isAvailable());
+
+ mTestIface = createTestInterface();
+ // This must be done now because as soon as setIncludeTestInterfaces(true) is called, the
+ // interface will be placed in client mode, which will delete the link-local address.
+ // At that point NetworkInterface.getByName() will cease to work on the interface, because
+ // starting in R NetworkInterface can no longer see interfaces without IP addresses.
+ int mtu = getMTU(mTestIface);
+
+ Log.d(TAG, "Including test interfaces");
+ mEm.setIncludeTestInterfaces(true);
+
+ final String iface = mTetheredInterfaceRequester.getInterface();
+ assertEquals("TetheredInterfaceCallback for unexpected interface",
+ mTestIface.getInterfaceName(), iface);
+
+ checkVirtualEthernet(mTestIface, mtu);
+ }
+
+ @Test
+ public void testVirtualEthernet() throws Exception {
+ // This test requires manipulating packets. Skip if there is a physical Ethernet connected.
+ assumeFalse(mEm.isAvailable());
+
+ CompletableFuture<String> futureIface = mTetheredInterfaceRequester.requestInterface();
+
+ mEm.setIncludeTestInterfaces(true);
+
+ mTestIface = createTestInterface();
+
+ final String iface = futureIface.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ assertEquals("TetheredInterfaceCallback for unexpected interface",
+ mTestIface.getInterfaceName(), iface);
+
+ checkVirtualEthernet(mTestIface, getMTU(mTestIface));
+ }
+
+ @Test
+ public void testPhysicalEthernet() throws Exception {
+ assumeTrue(mEm.isAvailable());
+
+ // Get an interface to use.
+ final String iface = mTetheredInterfaceRequester.getInterface();
+
+ // Enable Ethernet tethering and check that it starts.
+ mTetheringEventCallback = enableEthernetTethering(iface);
+
+ // There is nothing more we can do on a physical interface without connecting an actual
+ // client, which is not possible in this test.
+ }
+
+ private static final class MyTetheringEventCallback implements TetheringEventCallback {
+ private final TetheringManager mTm;
+ private final CountDownLatch mTetheringStartedLatch = new CountDownLatch(1);
+ private final CountDownLatch mTetheringStoppedLatch = new CountDownLatch(1);
+ private final CountDownLatch mClientConnectedLatch = new CountDownLatch(1);
+ private final String mIface;
+
+ private volatile boolean mInterfaceWasTethered = false;
+ private volatile boolean mUnregistered = false;
+ private volatile Collection<TetheredClient> mClients = null;
+
+ MyTetheringEventCallback(TetheringManager tm, String iface) {
+ mTm = tm;
+ mIface = iface;
+ }
+
+ public void unregister() {
+ mTm.unregisterTetheringEventCallback(this);
+ mUnregistered = true;
+ }
+
+ @Override
+ public void onTetheredInterfacesChanged(List<String> interfaces) {
+ // Ignore stale callbacks registered by previous test cases.
+ if (mUnregistered) return;
+
+ final boolean wasTethered = mTetheringStartedLatch.getCount() == 0;
+ if (!mInterfaceWasTethered && (mIface == null || interfaces.contains(mIface))) {
+ // This interface is being tethered for the first time.
+ Log.d(TAG, "Tethering started: " + interfaces);
+ mInterfaceWasTethered = true;
+ mTetheringStartedLatch.countDown();
+ } else if (mInterfaceWasTethered && !interfaces.contains(mIface)) {
+ Log.d(TAG, "Tethering stopped: " + interfaces);
+ mTetheringStoppedLatch.countDown();
+ }
+ }
+
+ public void awaitInterfaceTethered() throws Exception {
+ assertTrue("Ethernet not tethered after " + TIMEOUT_MS + "ms",
+ mTetheringStartedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ }
+
+ public void awaitInterfaceUntethered() throws Exception {
+ // Don't block teardown if the interface was never tethered.
+ // This is racy because the interface might become tethered right after this check, but
+ // that can only happen in tearDown if startTethering timed out, which likely means
+ // the test has already failed.
+ if (!mInterfaceWasTethered) return;
+
+ assertTrue(mIface + " not untethered after " + TIMEOUT_MS + "ms",
+ mTetheringStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ }
+
+ @Override
+ public void onError(String ifName, int error) {
+ // Ignore stale callbacks registered by previous test cases.
+ if (mUnregistered) return;
+
+ fail("TetheringEventCallback got error:" + error + " on iface " + ifName);
+ }
+
+ @Override
+ public void onClientsChanged(Collection<TetheredClient> clients) {
+ // Ignore stale callbacks registered by previous test cases.
+ if (mUnregistered) return;
+
+ Log.d(TAG, "Got clients changed: " + clients);
+ mClients = clients;
+ if (clients.size() > 0) {
+ mClientConnectedLatch.countDown();
+ }
+ }
+
+ public Collection<TetheredClient> awaitClientConnected() throws Exception {
+ assertTrue("Did not receive client connected callback after " + TIMEOUT_MS + "ms",
+ mClientConnectedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ return mClients;
+ }
+ }
+
+ private MyTetheringEventCallback enableEthernetTethering(String iface) throws Exception {
+ MyTetheringEventCallback callback = new MyTetheringEventCallback(mTm, iface);
+ mTm.registerTetheringEventCallback(mHandler::post, callback);
+
+ StartTetheringCallback startTetheringCallback = new StartTetheringCallback() {
+ @Override
+ public void onTetheringFailed(int resultCode) {
+ fail("Unexpectedly got onTetheringFailed");
+ }
+ };
+ Log.d(TAG, "Starting Ethernet tethering");
+ mTm.startTethering(
+ new TetheringRequest.Builder(TetheringManager.TETHERING_ETHERNET).build(),
+ mHandler::post /* executor */, startTetheringCallback);
+ callback.awaitInterfaceTethered();
+ return callback;
+ }
+
+ private int getMTU(TestNetworkInterface iface) throws SocketException {
+ NetworkInterface nif = NetworkInterface.getByName(iface.getInterfaceName());
+ assertNotNull("Can't get NetworkInterface object for " + iface.getInterfaceName(), nif);
+ return nif.getMTU();
+ }
+
+ private void checkVirtualEthernet(TestNetworkInterface iface, int mtu) throws Exception {
+ FileDescriptor fd = iface.getFileDescriptor().getFileDescriptor();
+ mTapPacketReader = new TapPacketReader(mHandler, fd, mtu);
+ mHandler.post(() -> mTapPacketReader.start());
+ HandlerUtilsKt.waitForIdle(mHandler, TIMEOUT_MS);
+
+ mTetheringEventCallback = enableEthernetTethering(iface.getInterfaceName());
+ checkTetheredClientCallbacks(fd);
+ }
+
+ private void checkTetheredClientCallbacks(FileDescriptor fd) throws Exception {
+ // Create a fake client.
+ byte[] clientMacAddr = new byte[6];
+ new Random().nextBytes(clientMacAddr);
+
+ // We have to retransmit DHCP requests because IpServer declares itself to be ready before
+ // its DhcpServer is actually started. TODO: fix this race and remove this loop.
+ DhcpPacket offerPacket = null;
+ for (int i = 0; i < DHCP_DISCOVER_ATTEMPTS; i++) {
+ Log.d(TAG, "Sending DHCP discover");
+ sendDhcpDiscover(fd, clientMacAddr);
+ offerPacket = getNextDhcpPacket();
+ if (offerPacket instanceof DhcpOfferPacket) break;
+ }
+ assertTrue("No DHCPOFFER received on interface within timeout",
+ offerPacket instanceof DhcpOfferPacket);
+
+ sendDhcpRequest(fd, offerPacket, clientMacAddr);
+ DhcpPacket ackPacket = getNextDhcpPacket();
+ assertTrue("No DHCPACK received on interface within timeout",
+ ackPacket instanceof DhcpAckPacket);
+
+ final Collection<TetheredClient> clients = mTetheringEventCallback.awaitClientConnected();
+ assertEquals(1, clients.size());
+ final TetheredClient client = clients.iterator().next();
+
+ // Check the MAC address.
+ assertEquals(MacAddress.fromBytes(clientMacAddr), client.getMacAddress());
+ assertEquals(TetheringManager.TETHERING_ETHERNET, client.getTetheringType());
+
+ // Check the hostname.
+ assertEquals(1, client.getAddresses().size());
+ TetheredClient.AddressInfo info = client.getAddresses().get(0);
+ assertEquals(DHCP_HOSTNAME, info.getHostname());
+
+ // Check the address is the one that was handed out in the DHCP ACK.
+ DhcpResults dhcpResults = offerPacket.toDhcpResults();
+ assertLinkAddressMatches(dhcpResults.ipAddress, info.getAddress());
+
+ // Check that the lifetime is correct +/- 10s.
+ final long now = SystemClock.elapsedRealtime();
+ final long actualLeaseDuration = (info.getAddress().getExpirationTime() - now) / 1000;
+ final String msg = String.format("IP address should have lifetime of %d, got %d",
+ dhcpResults.leaseDuration, actualLeaseDuration);
+ assertTrue(msg, Math.abs(dhcpResults.leaseDuration - actualLeaseDuration) < 10);
+ }
+
+ private DhcpPacket getNextDhcpPacket() throws ParseException {
+ byte[] packet;
+ while ((packet = mTapPacketReader.popPacket(PACKET_READ_TIMEOUT_MS)) != null) {
+ try {
+ return DhcpPacket.decodeFullPacket(packet, packet.length, DhcpPacket.ENCAP_L2);
+ } catch (DhcpPacket.ParseException e) {
+ // Not a DHCP packet. Continue.
+ }
+ }
+ return null;
+ }
+
+ private static final class TetheredInterfaceRequester implements TetheredInterfaceCallback {
+ private final CountDownLatch mInterfaceAvailableLatch = new CountDownLatch(1);
+ private final Handler mHandler;
+ private final EthernetManager mEm;
+
+ private TetheredInterfaceRequest mRequest;
+ private final CompletableFuture<String> mFuture = new CompletableFuture<>();
+
+ TetheredInterfaceRequester(Handler handler, EthernetManager em) {
+ mHandler = handler;
+ mEm = em;
+ }
+
+ @Override
+ public void onAvailable(String iface) {
+ Log.d(TAG, "Ethernet interface available: " + iface);
+ mFuture.complete(iface);
+ }
+
+ @Override
+ public void onUnavailable() {
+ mFuture.completeExceptionally(new IllegalStateException("onUnavailable received"));
+ }
+
+ public CompletableFuture<String> requestInterface() {
+ assertNull("BUG: more than one tethered interface request", mRequest);
+ Log.d(TAG, "Requesting tethered interface");
+ mRequest = mEm.requestTetheredInterface(mHandler::post, this);
+ return mFuture;
+ }
+
+ public String getInterface() throws Exception {
+ return requestInterface().get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ }
+
+ public void release() {
+ if (mRequest != null) {
+ mFuture.obtrudeException(new IllegalStateException("Request already released"));
+ mRequest.release();
+ mRequest = null;
+ }
+ }
+ }
+
+ private void sendDhcpDiscover(FileDescriptor fd, byte[] macAddress) throws Exception {
+ ByteBuffer packet = DhcpPacket.buildDiscoverPacket(DhcpPacket.ENCAP_L2,
+ new Random().nextInt() /* transactionId */, (short) 0 /* secs */,
+ macAddress, false /* unicast */, DHCP_REQUESTED_PARAMS,
+ false /* rapid commit */, DHCP_HOSTNAME);
+ sendPacket(fd, packet);
+ }
+
+ private void sendDhcpRequest(FileDescriptor fd, DhcpPacket offerPacket, byte[] macAddress)
+ throws Exception {
+ DhcpResults results = offerPacket.toDhcpResults();
+ Inet4Address clientIp = (Inet4Address) results.ipAddress.getAddress();
+ Inet4Address serverIdentifier = results.serverAddress;
+ ByteBuffer packet = DhcpPacket.buildRequestPacket(DhcpPacket.ENCAP_L2,
+ 0 /* transactionId */, (short) 0 /* secs */, DhcpPacket.INADDR_ANY /* clientIp */,
+ false /* broadcast */, macAddress, clientIp /* requestedIpAddress */,
+ serverIdentifier, DHCP_REQUESTED_PARAMS, DHCP_HOSTNAME);
+ sendPacket(fd, packet);
+ }
+
+ private void sendPacket(FileDescriptor fd, ByteBuffer packet) throws Exception {
+ assertNotNull("Only tests on virtual interfaces can send packets", fd);
+ Os.write(fd, packet);
+ }
+
+ public void assertLinkAddressMatches(LinkAddress l1, LinkAddress l2) {
+ // Check all fields except the deprecation and expiry times.
+ String msg = String.format("LinkAddresses do not match. expected: %s actual: %s", l1, l2);
+ assertTrue(msg, l1.isSameAddressAs(l2));
+ assertEquals("LinkAddress flags do not match", l1.getFlags(), l2.getFlags());
+ assertEquals("LinkAddress scope does not match", l1.getScope(), l2.getScope());
+ }
+
+ private TestNetworkInterface createTestInterface() throws Exception {
+ TestNetworkManager tnm = mContext.getSystemService(TestNetworkManager.class);
+ TestNetworkInterface iface = tnm.createTapInterface();
+ Log.d(TAG, "Created test interface " + iface.getInterfaceName());
+ assertNotNull(NetworkInterface.getByName(iface.getInterfaceName()));
+ return iface;
+ }
+
+ private void maybeDeleteTestInterface() throws Exception {
+ if (mTestIface != null) {
+ mTestIface.getFileDescriptor().close();
+ Log.d(TAG, "Deleted test interface " + mTestIface.getInterfaceName());
+ mTestIface = null;
+ }
+ }
+}
diff --git a/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java b/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java
index e8add9830b5f..f8eb1476bad0 100644
--- a/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java
@@ -42,7 +42,9 @@ import java.util.stream.IntStream;
@SmallTest
public class DhcpServingParamsParcelExtTest {
private static final Inet4Address TEST_ADDRESS = inet4Addr("192.168.0.123");
+ private static final Inet4Address TEST_CLIENT_ADDRESS = inet4Addr("192.168.0.42");
private static final int TEST_ADDRESS_PARCELED = 0xc0a8007b;
+ private static final int TEST_CLIENT_ADDRESS_PARCELED = 0xc0a8002a;
private static final int TEST_PREFIX_LENGTH = 17;
private static final int TEST_LEASE_TIME_SECS = 120;
private static final int TEST_MTU = 1000;
@@ -105,6 +107,12 @@ public class DhcpServingParamsParcelExtTest {
assertFalse(mParcel.metered);
}
+ @Test
+ public void testSetClientAddr() {
+ mParcel.setSingleClientAddr(TEST_CLIENT_ADDRESS);
+ assertEquals(TEST_CLIENT_ADDRESS_PARCELED, mParcel.clientAddr);
+ }
+
private static Inet4Address inet4Addr(String addr) {
return (Inet4Address) parseNumericAddress(addr);
}
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringNotificationUpdaterTest.kt b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringNotificationUpdaterTest.kt
new file mode 100644
index 000000000000..b86949185c69
--- /dev/null
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringNotificationUpdaterTest.kt
@@ -0,0 +1,262 @@
+/*
+ * 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.
+ */
+
+package com.android.server.connectivity.tethering
+
+import android.app.Notification
+import android.app.NotificationManager
+import android.content.Context
+import android.content.res.Resources
+import android.net.ConnectivityManager.TETHERING_BLUETOOTH
+import android.net.ConnectivityManager.TETHERING_USB
+import android.net.ConnectivityManager.TETHERING_WIFI
+import android.os.UserHandle
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.test.BroadcastInterceptingContext
+import com.android.networkstack.tethering.R
+import com.android.server.connectivity.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+const val TEST_SUBID = 1
+const val WIFI_ICON_ID = 1
+const val USB_ICON_ID = 2
+const val BT_ICON_ID = 3
+const val GENERAL_ICON_ID = 4
+const val WIFI_MASK = 1 shl TETHERING_WIFI
+const val USB_MASK = 1 shl TETHERING_USB
+const val BT_MASK = 1 shl TETHERING_BLUETOOTH
+const val TITTLE = "Tethering active"
+const val MESSAGE = "Tap here to set up."
+const val TEST_TITTLE = "Hotspot active"
+const val TEST_MESSAGE = "Tap to set up hotspot."
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class TetheringNotificationUpdaterTest {
+ // lateinit used here for mocks as they need to be reinitialized between each test and the test
+ // should crash if they are used before being initialized.
+ @Mock private lateinit var mockContext: Context
+ @Mock private lateinit var notificationManager: NotificationManager
+ @Mock private lateinit var defaultResources: Resources
+ @Mock private lateinit var testResources: Resources
+
+ // lateinit for this class under test, as it should be reset to a different instance for every
+ // tests but should always be initialized before use (or the test should crash).
+ private lateinit var notificationUpdater: TetheringNotificationUpdater
+
+ private val ENABLE_ICON_CONFIGS = arrayOf(
+ "USB;android.test:drawable/usb", "BT;android.test:drawable/bluetooth",
+ "WIFI|BT;android.test:drawable/general", "WIFI|USB;android.test:drawable/general",
+ "USB|BT;android.test:drawable/general", "WIFI|USB|BT;android.test:drawable/general")
+
+ private inner class TestContext(c: Context) : BroadcastInterceptingContext(c) {
+ override fun createContextAsUser(user: UserHandle, flags: Int) =
+ if (user == UserHandle.ALL) mockContext else this
+ }
+
+ private inner class WrappedNotificationUpdater(c: Context) : TetheringNotificationUpdater(c) {
+ override fun getResourcesForSubId(context: Context, subId: Int) =
+ if (subId == TEST_SUBID) testResources else defaultResources
+ }
+
+ private fun setupResources() {
+ doReturn(ENABLE_ICON_CONFIGS).`when`(defaultResources)
+ .getStringArray(R.array.tethering_notification_icons)
+ doReturn(arrayOf("WIFI;android.test:drawable/wifi")).`when`(testResources)
+ .getStringArray(R.array.tethering_notification_icons)
+ doReturn(TITTLE).`when`(defaultResources).getString(R.string.tethering_notification_title)
+ doReturn(MESSAGE).`when`(defaultResources)
+ .getString(R.string.tethering_notification_message)
+ doReturn(TEST_TITTLE).`when`(testResources).getString(R.string.tethering_notification_title)
+ doReturn(TEST_MESSAGE).`when`(testResources)
+ .getString(R.string.tethering_notification_message)
+ doReturn(USB_ICON_ID).`when`(defaultResources)
+ .getIdentifier(eq("android.test:drawable/usb"), any(), any())
+ doReturn(BT_ICON_ID).`when`(defaultResources)
+ .getIdentifier(eq("android.test:drawable/bluetooth"), any(), any())
+ doReturn(GENERAL_ICON_ID).`when`(defaultResources)
+ .getIdentifier(eq("android.test:drawable/general"), any(), any())
+ doReturn(WIFI_ICON_ID).`when`(testResources)
+ .getIdentifier(eq("android.test:drawable/wifi"), any(), any())
+ }
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ val context = TestContext(InstrumentationRegistry.getInstrumentation().context)
+ doReturn(notificationManager).`when`(mockContext)
+ .getSystemService(Context.NOTIFICATION_SERVICE)
+ notificationUpdater = WrappedNotificationUpdater(context)
+ setupResources()
+ }
+
+ private fun Notification.title() = this.extras.getString(Notification.EXTRA_TITLE)
+ private fun Notification.text() = this.extras.getString(Notification.EXTRA_TEXT)
+
+ private fun verifyNotification(iconId: Int = 0, title: String = "", text: String = "") {
+ verify(notificationManager, never()).cancel(any(), anyInt())
+
+ val notificationCaptor = ArgumentCaptor.forClass(Notification::class.java)
+ verify(notificationManager, times(1))
+ .notify(any(), anyInt(), notificationCaptor.capture())
+
+ val notification = notificationCaptor.getValue()
+ assertEquals(iconId, notification.smallIcon.resId)
+ assertEquals(title, notification.title())
+ assertEquals(text, notification.text())
+
+ reset(notificationManager)
+ }
+
+ private fun verifyNoNotification() {
+ verify(notificationManager, times(1)).cancel(any(), anyInt())
+ verify(notificationManager, never()).notify(any(), anyInt(), any())
+
+ reset(notificationManager)
+ }
+
+ @Test
+ fun testNotificationWithDownstreamChanged() {
+ // Wifi downstream. No notification.
+ notificationUpdater.onDownstreamChanged(WIFI_MASK)
+ verifyNoNotification()
+
+ // Same downstream changed. Nothing happened.
+ notificationUpdater.onDownstreamChanged(WIFI_MASK)
+ verifyZeroInteractions(notificationManager)
+
+ // Wifi and usb downstreams. Show enable notification
+ notificationUpdater.onDownstreamChanged(WIFI_MASK or USB_MASK)
+ verifyNotification(GENERAL_ICON_ID, TITTLE, MESSAGE)
+
+ // Usb downstream. Still show enable notification.
+ notificationUpdater.onDownstreamChanged(USB_MASK)
+ verifyNotification(USB_ICON_ID, TITTLE, MESSAGE)
+
+ // No downstream. No notification.
+ notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
+ verifyNoNotification()
+ }
+
+ @Test
+ fun testNotificationWithActiveDataSubscriptionIdChanged() {
+ // Usb downstream. Showed enable notification with default resource.
+ notificationUpdater.onDownstreamChanged(USB_MASK)
+ verifyNotification(USB_ICON_ID, TITTLE, MESSAGE)
+
+ // Same subId changed. Nothing happened.
+ notificationUpdater.onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID)
+ verifyZeroInteractions(notificationManager)
+
+ // Set test sub id. Clear notification with test resource.
+ notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
+ verifyNoNotification()
+
+ // Wifi downstream. Show enable notification with test resource.
+ notificationUpdater.onDownstreamChanged(WIFI_MASK)
+ verifyNotification(WIFI_ICON_ID, TEST_TITTLE, TEST_MESSAGE)
+
+ // No downstream. No notification.
+ notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
+ verifyNoNotification()
+ }
+
+ private fun assertIconNumbers(number: Int, configs: Array<String?>) {
+ doReturn(configs).`when`(defaultResources)
+ .getStringArray(R.array.tethering_notification_icons)
+ assertEquals(number, notificationUpdater.getIcons(
+ R.array.tethering_notification_icons, defaultResources).size())
+ }
+
+ @Test
+ fun testGetIcons() {
+ assertIconNumbers(0, arrayOfNulls<String>(0))
+ assertIconNumbers(0, arrayOf(null, ""))
+ assertIconNumbers(3, arrayOf(
+ // These configurations are invalid with wrong strings or symbols.
+ ";", ",", "|", "|,;", "WIFI", "1;2", " U SB; ", "bt;", "WIFI;USB;BT", "WIFI|USB|BT",
+ "WIFI,BT,USB", " WIFI| | | USB, test:drawable/test",
+ // This configuration is valid with two downstream types (USB, BT).
+ "USB|,,,,,|BT;drawable/test ",
+ // This configuration is valid with one downstream types (WIFI).
+ " WIFI ; android.test:drawable/xxx "))
+ }
+
+ @Test
+ fun testGetDownstreamTypesMask() {
+ assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask(""))
+ assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("1"))
+ assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("WIFI_P2P"))
+ assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("usb"))
+ assertEquals(WIFI_MASK, notificationUpdater.getDownstreamTypesMask(" WIFI "))
+ assertEquals(USB_MASK, notificationUpdater.getDownstreamTypesMask("USB | B T"))
+ assertEquals(BT_MASK, notificationUpdater.getDownstreamTypesMask(" WIFI: | BT"))
+ assertEquals(WIFI_MASK or USB_MASK,
+ notificationUpdater.getDownstreamTypesMask("1|2|USB|WIFI|BLUETOOTH||"))
+ }
+
+ @Test
+ fun testSetupRestrictedNotification() {
+ val title = InstrumentationRegistry.getInstrumentation().context.resources
+ .getString(R.string.disable_tether_notification_title)
+ val message = InstrumentationRegistry.getInstrumentation().context.resources
+ .getString(R.string.disable_tether_notification_message)
+ val disallowTitle = "Tether function is disallowed"
+ val disallowMessage = "Please contact your admin"
+ doReturn(title).`when`(defaultResources)
+ .getString(R.string.disable_tether_notification_title)
+ doReturn(message).`when`(defaultResources)
+ .getString(R.string.disable_tether_notification_message)
+ doReturn(disallowTitle).`when`(testResources)
+ .getString(R.string.disable_tether_notification_title)
+ doReturn(disallowMessage).`when`(testResources)
+ .getString(R.string.disable_tether_notification_message)
+
+ // User restrictions on. Show restricted notification.
+ notificationUpdater.notifyTetheringDisabledByRestriction()
+ verifyNotification(R.drawable.stat_sys_tether_general, title, message)
+
+ // User restrictions off. Clear notification.
+ notificationUpdater.tetheringRestrictionLifted()
+ verifyNoNotification()
+
+ // Set test sub id. No notification.
+ notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
+ verifyNoNotification()
+
+ // User restrictions on again. Show restricted notification with test resource.
+ notificationUpdater.notifyTetheringDisabledByRestriction()
+ verifyNotification(R.drawable.stat_sys_tether_general, disallowTitle, disallowMessage)
+ }
+} \ No newline at end of file
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
index d983fae09be4..a418c4a880d2 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
@@ -38,6 +38,7 @@ import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
+import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
@@ -210,7 +211,6 @@ public class TetheringTest {
private PhoneStateListener mPhoneStateListener;
private InterfaceConfigurationParcel mInterfaceConfiguration;
-
private class TestContext extends BroadcastInterceptingContext {
TestContext(Context base) {
super(base);
@@ -485,6 +485,7 @@ public class TetheringTest {
mServiceContext.registerReceiver(mBroadcastReceiver,
new IntentFilter(ACTION_TETHER_STATE_CHANGED));
mTethering = makeTethering();
+ mTethering.startStateMachineUpdaters();
verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
verify(mNetd).registerUnsolicitedEventListener(any());
final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
@@ -1073,13 +1074,15 @@ public class TetheringTest {
when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
final Tethering.UserRestrictionActionListener ural =
- new Tethering.UserRestrictionActionListener(mUserManager, mockTethering);
+ new Tethering.UserRestrictionActionListener(
+ mUserManager, mockTethering, mNotificationUpdater);
ural.mDisallowTethering = currentDisallow;
ural.onUserRestrictionsChanged();
- verify(mockTethering, times(expectedInteractionsWithShowNotification))
- .untetherAll();
+ verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
+ .notifyTetheringDisabledByRestriction();
+ verify(mockTethering, times(expectedInteractionsWithShowNotification)).untetherAll();
}
@Test
@@ -1087,7 +1090,7 @@ public class TetheringTest {
final String[] emptyActiveIfacesList = new String[]{};
final boolean currDisallow = false;
final boolean nextDisallow = true;
- final int expectedInteractionsWithShowNotification = 0;
+ final int expectedInteractionsWithShowNotification = 1;
runUserRestrictionsChange(currDisallow, nextDisallow, emptyActiveIfacesList,
expectedInteractionsWithShowNotification);
@@ -1399,6 +1402,7 @@ public class TetheringTest {
mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
assertEquals(fakeSubId, newConfig.activeDataSubId);
+ verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId));
}
@Test
@@ -1651,10 +1655,13 @@ public class TetheringTest {
}
@Test
- public void testRequestStaticServerIp() throws Exception {
- final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24");
- final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24");
- final String serverAddr = "192.168.20.1";
+ public void testRequestStaticIp() throws Exception {
+ final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
+ final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
+ final String serverAddr = "192.168.0.123";
+ final int clientAddrParceled = 0xc0a8002a;
+ final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
+ ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
serverLinkAddr, clientLinkAddr), null);
mLooper.dispatchAll();
@@ -1663,8 +1670,12 @@ public class TetheringTest {
sendUsbBroadcast(true, true, true, TETHERING_USB);
mLooper.dispatchAll();
verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
-
- // TODO: test static client address.
+ verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
+ any());
+ final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
+ assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
+ assertEquals(24, params.serverAddrPrefixLength);
+ assertEquals(clientAddrParceled, params.clientAddr);
}
// TODO: Test that a request for hotspot mode doesn't interfere with an
diff --git a/services/Android.bp b/services/Android.bp
index 8ebad4efc1b5..90f98e2bd7a6 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -75,10 +75,6 @@ java_library {
"framework-tethering-stubs-module_libs_api",
],
- plugins: [
- "compat-changeid-annotation-processor",
- ],
-
// Uncomment to enable output of certain warnings (deprecated, unchecked)
//javacflags: ["-Xlint"],
@@ -94,8 +90,8 @@ cc_library_shared {
}
platform_compat_config {
- name: "services-platform-compat-config",
- src: ":services",
+ name: "services-platform-compat-config",
+ src: ":services",
}
filegroup {
@@ -110,6 +106,7 @@ droidstubs {
name: "services-stubs.sources",
srcs: [":services-sources"],
installable: false,
+ api_tag_name: "SYSTEM_SERVER",
args: " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\)" +
" --hide-annotation android.annotation.Hide" +
" --hide InternalClasses" + // com.android.* classes are okay in this interface
@@ -138,7 +135,8 @@ droidstubs {
}
java_library {
- name: "services-stubs",
+ name: "android_system_server_stubs_current",
srcs: [":services-stubs.sources"],
installable: false,
+ static_libs: ["android_module_lib_stubs_current"],
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index b7fd227ed0bb..7a3a910c0447 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -56,10 +56,6 @@ java_library_static {
"dnsresolver_aidl_interface-V2-java",
"netd_event_listener_interface-java",
],
-
- plugins: [
- "compat-changeid-annotation-processor",
- ],
}
java_genrule {
diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java
index 207e007cc62f..ecbf9a48931e 100644
--- a/services/core/java/com/android/server/AppStateTracker.java
+++ b/services/core/java/com/android/server/AppStateTracker.java
@@ -54,7 +54,6 @@ import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.Preconditions;
import com.android.internal.util.StatLogger;
import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage;
import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
@@ -62,6 +61,7 @@ import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrict
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
/**
* Class to keep track of the information related to "force app standby", which includes:
@@ -416,12 +416,12 @@ public class AppStateTracker {
}
mStarted = true;
- mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
- mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal());
- mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
- mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
- mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
- mUsageStatsManagerInternal = Preconditions.checkNotNull(
+ mIActivityManager = Objects.requireNonNull(injectIActivityManager());
+ mActivityManagerInternal = Objects.requireNonNull(injectActivityManagerInternal());
+ mAppOpsManager = Objects.requireNonNull(injectAppOpsManager());
+ mAppOpsService = Objects.requireNonNull(injectIAppOpsService());
+ mPowerManagerInternal = Objects.requireNonNull(injectPowerManagerInternal());
+ mUsageStatsManagerInternal = Objects.requireNonNull(
injectUsageStatsManagerInternal());
mFlagsObserver = new FeatureFlagsObserver();
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index fa8eda54e53c..168c8cd713b6 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -106,9 +106,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private static final int USER_SWITCHED_TIME_MS = 200;
// Delay for the addProxy function in msec
private static final int ADD_PROXY_DELAY_MS = 100;
+ // Delay for retrying enable and disable in msec
+ private static final int ENABLE_DISABLE_DELAY_MS = 300;
private static final int MESSAGE_ENABLE = 1;
private static final int MESSAGE_DISABLE = 2;
+ private static final int MESSAGE_HANDLE_ENABLE_DELAYED = 3;
+ private static final int MESSAGE_HANDLE_DISABLE_DELAYED = 4;
private static final int MESSAGE_REGISTER_ADAPTER = 20;
private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
@@ -130,6 +134,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private static final int RESTORE_SETTING_TO_OFF = 0;
private static final int MAX_ERROR_RESTART_RETRIES = 6;
+ private static final int MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES = 10;
// Bluetooth persisted setting is off
private static final int BLUETOOTH_OFF = 0;
@@ -160,6 +165,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
private boolean mBinding;
private boolean mUnbinding;
+ private int mWaitForEnableRetry;
+ private int mWaitForDisableRetry;
private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
@@ -740,13 +747,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
}
- public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
- // Check if packageName belongs to callingUid
- final int callingUid = Binder.getCallingUid();
- final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
- if (!isCallerSystem) {
- checkPackage(callingUid, packageName);
- }
+ private int updateBleAppCount(IBinder token, boolean enable, String packageName) {
ClientDeathRecipient r = mBleApps.get(token);
if (r == null && enable) {
ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
@@ -771,13 +772,94 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (DBG) {
Slog.d(TAG, appCount + " registered Ble Apps");
}
- if (appCount == 0 && mEnable) {
- disableBleScanMode();
+ return appCount;
+ }
+
+ private boolean checkBluetoothPermissions(String packageName, boolean requireForeground) {
+ if (isBluetoothDisallowed()) {
+ if (DBG) {
+ Slog.d(TAG, "checkBluetoothPermissions: bluetooth disallowed");
+ }
+ return false;
}
- if (appCount == 0 && !mEnableExternal) {
- sendBrEdrDownCallback();
+ // Check if packageName belongs to callingUid
+ final int callingUid = Binder.getCallingUid();
+ final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
+ if (!isCallerSystem) {
+ checkPackage(callingUid, packageName);
+
+ if (requireForeground && !checkIfCallerIsForegroundUser()) {
+ Slog.w(TAG, "Not allowed for non-active and non system user");
+ return false;
+ }
+
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+ "Need BLUETOOTH ADMIN permission");
}
- return appCount;
+ return true;
+ }
+
+ public boolean enableBle(String packageName, IBinder token) throws RemoteException {
+ if (!checkBluetoothPermissions(packageName, false)) {
+ if (DBG) {
+ Slog.d(TAG, "enableBle(): bluetooth disallowed");
+ }
+ return false;
+ }
+
+ if (DBG) {
+ Slog.d(TAG, "enableBle(" + packageName + "): mBluetooth =" + mBluetooth
+ + " mBinding = " + mBinding + " mState = "
+ + BluetoothAdapter.nameForState(mState));
+ }
+ updateBleAppCount(token, true, packageName);
+
+ if (mState == BluetoothAdapter.STATE_ON
+ || mState == BluetoothAdapter.STATE_BLE_ON
+ || mState == BluetoothAdapter.STATE_TURNING_ON
+ || mState == BluetoothAdapter.STATE_TURNING_OFF) {
+ Log.d(TAG, "enableBLE(): Bluetooth already enabled");
+ return true;
+ }
+ synchronized (mReceiver) {
+ // waive WRITE_SECURE_SETTINGS permission check
+ sendEnableMsg(false,
+ BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
+ }
+ return true;
+ }
+
+ public boolean disableBle(String packageName, IBinder token) throws RemoteException {
+ if (!checkBluetoothPermissions(packageName, false)) {
+ if (DBG) {
+ Slog.d(TAG, "disableBLE(): bluetooth disallowed");
+ }
+ return false;
+ }
+
+ if (DBG) {
+ Slog.d(TAG, "disableBle(" + packageName + "): mBluetooth =" + mBluetooth
+ + " mBinding = " + mBinding + " mState = "
+ + BluetoothAdapter.nameForState(mState));
+ }
+
+ if (mState == BluetoothAdapter.STATE_OFF) {
+ Slog.d(TAG, "disableBLE(): Already disabled");
+ return false;
+ }
+ updateBleAppCount(token, false, packageName);
+
+ if (mState == BluetoothAdapter.STATE_BLE_ON && !isBleAppPresent()) {
+ if (mEnable) {
+ disableBleScanMode();
+ }
+ if (!mEnableExternal) {
+ addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
+ packageName, false);
+ sendBrEdrDownCallback();
+ }
+ }
+ return true;
}
// Clear all apps using BLE scan only mode.
@@ -806,6 +888,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
return;
}
+ if (!mEnableExternal && !isBleAppPresent() && isAirplaneModeOn()) {
+ // Airplane mode is turned on while enabling BLE only mode, disable
+ // BLE now.
+ disableBleScanMode();
+ sendBrEdrDownCallback();
+ return;
+ }
if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
// This triggers transition to STATE_ON
mBluetooth.onLeServiceUp();
@@ -855,29 +944,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
public boolean enableNoAutoConnect(String packageName) {
- if (isBluetoothDisallowed()) {
+ if (!checkBluetoothPermissions(packageName, false)) {
if (DBG) {
Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
}
return false;
}
- // Check if packageName belongs to callingUid
- final int callingUid = Binder.getCallingUid();
- final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
- if (!isCallerSystem) {
- checkPackage(callingUid, packageName);
- }
-
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
- "Need BLUETOOTH ADMIN permission");
-
if (DBG) {
Slog.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = "
+ mBinding);
}
- int callingAppId = UserHandle.getAppId(callingUid);
+ int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
if (callingAppId != Process.NFC_UID) {
throw new SecurityException("no permission to enable Bluetooth quietly");
}
@@ -892,32 +971,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
public boolean enable(String packageName) throws RemoteException {
- final int callingUid = Binder.getCallingUid();
- final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
-
- if (isBluetoothDisallowed()) {
+ if (!checkBluetoothPermissions(packageName, true)) {
if (DBG) {
Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
}
return false;
}
- if (!callerSystem) {
- // Check if packageName belongs to callingUid
- checkPackage(callingUid, packageName);
-
- if (!checkIfCallerIsForegroundUser()) {
- Slog.w(TAG, "enable(): not allowed for non-active and non system user");
- return false;
- }
-
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
- "Need BLUETOOTH ADMIN permission");
-
- if (!isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
- callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
- return false;
- }
+ final int callingUid = Binder.getCallingUid();
+ final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
+ if (!callerSystem && !isEnabled() && mWirelessConsentRequired
+ && startConsentUiIfNeeded(packageName,
+ callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
+ return false;
}
if (DBG) {
@@ -939,25 +1005,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
public boolean disable(String packageName, boolean persist) throws RemoteException {
- final int callingUid = Binder.getCallingUid();
- final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
-
- if (!callerSystem) {
- // Check if packageName belongs to callingUid
- checkPackage(callingUid, packageName);
-
- if (!checkIfCallerIsForegroundUser()) {
- Slog.w(TAG, "disable(): not allowed for non-active and non system user");
- return false;
+ if (!checkBluetoothPermissions(packageName, true)) {
+ if (DBG) {
+ Slog.d(TAG, "disable(): not disabling - bluetooth disallowed");
}
+ return false;
+ }
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
- "Need BLUETOOTH ADMIN permission");
-
- if (isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
- callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
- return false;
- }
+ final int callingUid = Binder.getCallingUid();
+ final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
+ if (!callerSystem && isEnabled() && mWirelessConsentRequired
+ && startConsentUiIfNeeded(packageName,
+ callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
+ return false;
}
if (DBG) {
@@ -1597,8 +1657,18 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
break;
case MESSAGE_ENABLE:
+ int quietEnable = msg.arg1;
+ if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
+ || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
+ // We are handling enable or disable right now, wait for it.
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_ENABLE,
+ quietEnable, 0), ENABLE_DISABLE_DELAY_MS);
+ break;
+ }
+
if (DBG) {
- Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
+ Slog.d(TAG, "MESSAGE_ENABLE(" + quietEnable + "): mBluetooth = "
+ + mBluetooth);
}
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mEnable = true;
@@ -1621,7 +1691,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mBluetoothLock.readLock().unlock();
}
- mQuietEnable = (msg.arg1 == 1);
+ mQuietEnable = (quietEnable == 1);
if (mBluetooth == null) {
handleEnable(mQuietEnable);
} else {
@@ -1630,7 +1700,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// the previous Bluetooth process has exited. The
// waiting period has three components:
// (a) Wait until the local state is STATE_OFF. This
- // is accomplished by "waitForOnOff(false, true)".
+ // is accomplished by sending delay a message
+ // MESSAGE_HANDLE_ENABLE_DELAYED
// (b) Wait until the STATE_OFF state is updated to
// all components.
// (c) Wait until the Bluetooth process exits, and
@@ -1640,28 +1711,108 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// message. The delay time is backed off if Bluetooth
// continuously failed to turn on itself.
//
- waitForOnOff(false, true);
- Message restartMsg =
- mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
- mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
+ mWaitForEnableRetry = 0;
+ Message enableDelayedMsg =
+ mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED);
+ mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
}
break;
case MESSAGE_DISABLE:
+ if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED) || mBinding
+ || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
+ // We are handling enable or disable right now, wait for it.
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_DISABLE),
+ ENABLE_DISABLE_DELAY_MS);
+ break;
+ }
+
if (DBG) {
- Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
+ Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth
+ + ", mBinding = " + mBinding);
}
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
+
if (mEnable && mBluetooth != null) {
- waitForOnOff(true, false);
+ mWaitForDisableRetry = 0;
+ Message disableDelayedMsg =
+ mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 0, 0);
+ mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
+ } else {
mEnable = false;
handleDisable();
- waitForOnOff(false, false);
- } else {
+ }
+ break;
+
+ case MESSAGE_HANDLE_ENABLE_DELAYED: {
+ // The Bluetooth is turning off, wait for STATE_OFF
+ if (mState != BluetoothAdapter.STATE_OFF) {
+ if (mWaitForEnableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
+ mWaitForEnableRetry++;
+ Message enableDelayedMsg =
+ mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED);
+ mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
+ break;
+ } else {
+ Slog.e(TAG, "Wait for STATE_OFF timeout");
+ }
+ }
+ // Either state is changed to STATE_OFF or reaches the maximum retry, we
+ // should move forward to the next step.
+ mWaitForEnableRetry = 0;
+ Message restartMsg =
+ mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
+ mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
+ Slog.d(TAG, "Handle enable is finished");
+ break;
+ }
+
+ case MESSAGE_HANDLE_DISABLE_DELAYED: {
+ boolean disabling = (msg.arg1 == 1);
+ Slog.d(TAG, "MESSAGE_HANDLE_DISABLE_DELAYED: disabling:" + disabling);
+ if (!disabling) {
+ // The Bluetooth is turning on, wait for STATE_ON
+ if (mState != BluetoothAdapter.STATE_ON) {
+ if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
+ mWaitForDisableRetry++;
+ Message disableDelayedMsg = mHandler.obtainMessage(
+ MESSAGE_HANDLE_DISABLE_DELAYED, 0, 0);
+ mHandler.sendMessageDelayed(disableDelayedMsg,
+ ENABLE_DISABLE_DELAY_MS);
+ break;
+ } else {
+ Slog.e(TAG, "Wait for STATE_ON timeout");
+ }
+ }
+ // Either state is changed to STATE_ON or reaches the maximum retry, we
+ // should move forward to the next step.
+ mWaitForDisableRetry = 0;
mEnable = false;
handleDisable();
+ // Wait for state exiting STATE_ON
+ Message disableDelayedMsg =
+ mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
+ mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
+ } else {
+ // The Bluetooth is turning off, wait for exiting STATE_ON
+ if (mState == BluetoothAdapter.STATE_ON) {
+ if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
+ mWaitForDisableRetry++;
+ Message disableDelayedMsg = mHandler.obtainMessage(
+ MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
+ mHandler.sendMessageDelayed(disableDelayedMsg,
+ ENABLE_DISABLE_DELAY_MS);
+ break;
+ } else {
+ Slog.e(TAG, "Wait for exiting STATE_ON timeout");
+ }
+ }
+ // Either state is exited from STATE_ON or reaches the maximum retry, we
+ // should move forward to the next step.
+ Slog.d(TAG, "Handle disable is finished");
}
break;
+ }
case MESSAGE_RESTORE_USER_SETTING:
if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
@@ -2031,6 +2182,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
try {
mBluetoothLock.writeLock().lock();
if ((mBluetooth == null) && (!mBinding)) {
+ Slog.d(TAG, "binding Bluetooth service");
//Start bind timeout and bind
Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
@@ -2418,6 +2570,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
writer.println(" " + app.getPackageName());
}
+ writer.println("\nBluetoothManagerService:");
+ writer.println(" mEnable:" + mEnable);
+ writer.println(" mQuietEnable:" + mQuietEnable);
+ writer.println(" mEnableExternal:" + mEnableExternal);
+ writer.println(" mQuietEnableExternal:" + mQuietEnableExternal);
+
writer.println("");
writer.flush();
if (args.length == 0) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1ec4bc310546..1484fe7c7c6c 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -40,6 +40,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkPolicyManager.RULE_NONE;
import static android.net.NetworkPolicyManager.uidRulesToString;
@@ -48,10 +49,9 @@ import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
-import static com.android.internal.util.Preconditions.checkNotNull;
-
import static java.util.Map.Entry;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
@@ -63,6 +63,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.net.CaptivePortal;
@@ -236,7 +237,6 @@ import java.util.SortedSet;
import java.util.StringJoiner;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Function;
/**
* @hide
@@ -928,7 +928,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
* @see IpConnectivityMetrics.Logger
*/
public IpConnectivityMetrics.Logger getMetricsLogger() {
- return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
+ return Objects.requireNonNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
"no IpConnectivityMetrics service");
}
@@ -957,10 +957,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps) {
if (DBG) log("ConnectivityService starting up");
- mDeps = checkNotNull(deps, "missing Dependencies");
+ mDeps = Objects.requireNonNull(deps, "missing Dependencies");
mSystemProperties = mDeps.getSystemProperties();
mNetIdManager = mDeps.makeNetIdManager();
- mContext = checkNotNull(context, "missing Context");
+ mContext = Objects.requireNonNull(context, "missing Context");
mMetricsLog = logger;
mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
@@ -990,13 +990,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
- mNMS = checkNotNull(netManager, "missing INetworkManagementService");
- mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
- mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
- mPolicyManagerInternal = checkNotNull(
+ mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
+ mStatsService = Objects.requireNonNull(statsService, "missing INetworkStatsService");
+ mPolicyManager = Objects.requireNonNull(policyManager, "missing INetworkPolicyManager");
+ mPolicyManagerInternal = Objects.requireNonNull(
LocalServices.getService(NetworkPolicyManagerInternal.class),
"missing NetworkPolicyManagerInternal");
- mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver");
+ mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
mNetd = netd;
@@ -2696,10 +2696,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
switch (msg.what) {
case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
- final NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj;
+ NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj;
if (networkCapabilities.hasConnectivityManagedCapability()) {
Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
}
+ if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
+ // Make sure the original object is not mutated. NetworkAgent normally
+ // makes a copy of the capabilities when sending the message through
+ // the Messenger, but if this ever changes, not making a defensive copy
+ // here will give attack vectors to clients using this code path.
+ networkCapabilities = new NetworkCapabilities(networkCapabilities);
+ networkCapabilities.restrictCapabilitesForTestNetwork();
+ }
updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
break;
}
@@ -5324,7 +5332,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// specific SSID/SignalStrength, or the calling app has permission to do so.
private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
int callerPid, int callerUid, String callerPackageName) {
- if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) {
+ if (null != nc.getSsid() && !checkSettingsPermission(callerPid, callerUid)) {
throw new SecurityException("Insufficient permissions to request a specific SSID");
}
@@ -5389,12 +5397,25 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ private boolean checkUnsupportedStartingFrom(int version, String callingPackageName) {
+ final PackageManager pm = mContext.getPackageManager();
+ final int userId = UserHandle.getCallingUserId();
+ try {
+ final int callingVersion = pm.getApplicationInfoAsUser(
+ callingPackageName, 0 /* flags */, userId).targetSdkVersion;
+ if (callingVersion < version) return false;
+ } catch (PackageManager.NameNotFoundException e) { }
+ return true;
+ }
+
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
Messenger messenger, int timeoutMs, IBinder binder, int legacyType,
@NonNull String callingPackageName) {
if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
- throw new SecurityException("Insufficient permissions to specify legacy type");
+ if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) {
+ throw new SecurityException("Insufficient permissions to specify legacy type");
+ }
}
final int callingUid = Binder.getCallingUid();
final NetworkRequest.Type type = (networkCapabilities == null)
@@ -5499,7 +5520,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
PendingIntent operation, @NonNull String callingPackageName) {
- checkNotNull(operation, "PendingIntent cannot be null.");
+ Objects.requireNonNull(operation, "PendingIntent cannot be null.");
final int callingUid = Binder.getCallingUid();
networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities);
@@ -5528,7 +5549,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public void releasePendingNetworkRequest(PendingIntent operation) {
- checkNotNull(operation, "PendingIntent cannot be null.");
+ Objects.requireNonNull(operation, "PendingIntent cannot be null.");
mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
getCallingUid(), 0, operation));
}
@@ -5587,7 +5608,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
PendingIntent operation, @NonNull String callingPackageName) {
- checkNotNull(operation, "PendingIntent cannot be null.");
+ Objects.requireNonNull(operation, "PendingIntent cannot be null.");
final int callingUid = Binder.getCallingUid();
if (!hasWifiNetworkListenPermission(networkCapabilities)) {
enforceAccessPermission();
@@ -5772,7 +5793,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
- enforceNetworkFactoryPermission();
+ if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
+ enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS);
+ // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in
+ // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
+ // sees capabilities that may be malicious, which might prevent mistakes in the future.
+ networkCapabilities = new NetworkCapabilities(networkCapabilities);
+ networkCapabilities.restrictCapabilitesForTestNetwork();
+ } else {
+ enforceNetworkFactoryPermission();
+ }
LinkProperties lp = new LinkProperties(linkProperties);
lp.ensureDirectlyConnectedRoutes();
@@ -5787,7 +5817,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
final String extraInfo = networkInfo.getExtraInfo();
final String name = TextUtils.isEmpty(extraInfo)
- ? nai.networkCapabilities.getSSID() : extraInfo;
+ ? nai.networkCapabilities.getSsid() : extraInfo;
if (DBG) log("registerNetworkAgent " + nai);
final long token = Binder.clearCallingIdentity();
try {
@@ -5982,12 +6012,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
* @return true if routes changed between oldLp and newLp
*/
private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
- Function<RouteInfo, IpPrefix> getDestination = (r) -> r.getDestination();
// compare the route diff to determine which routes have been updated
- CompareOrUpdateResult<IpPrefix, RouteInfo> routeDiff = new CompareOrUpdateResult<>(
- oldLp != null ? oldLp.getAllRoutes() : null,
- newLp != null ? newLp.getAllRoutes() : null,
- getDestination);
+ final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff =
+ new CompareOrUpdateResult<>(
+ oldLp != null ? oldLp.getAllRoutes() : null,
+ newLp != null ? newLp.getAllRoutes() : null,
+ (r) -> r.getRouteKey());
// add routes before removing old in case it helps with continuous connectivity
diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java
index f7c4aac2e04f..77059d918052 100644
--- a/services/core/java/com/android/server/ExplicitHealthCheckController.java
+++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java
@@ -47,6 +47,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
@@ -113,9 +114,9 @@ class ExplicitHealthCheckController {
Slog.wtf(TAG, "Resetting health check controller callbacks");
}
- mPassedConsumer = Preconditions.checkNotNull(passedConsumer);
- mSupportedConsumer = Preconditions.checkNotNull(supportedConsumer);
- mNotifySyncRunnable = Preconditions.checkNotNull(notifySyncRunnable);
+ mPassedConsumer = Objects.requireNonNull(passedConsumer);
+ mSupportedConsumer = Objects.requireNonNull(supportedConsumer);
+ mNotifySyncRunnable = Objects.requireNonNull(notifySyncRunnable);
}
}
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 98ac4cb7122a..905c489e1dcb 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -25,8 +25,6 @@ import static android.system.OsConstants.EINVAL;
import static android.system.OsConstants.IPPROTO_UDP;
import static android.system.OsConstants.SOCK_DGRAM;
-import static com.android.internal.util.Preconditions.checkNotNull;
-
import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.Context;
@@ -48,6 +46,7 @@ import android.net.TrafficStats;
import android.net.util.NetdService;
import android.os.Binder;
import android.os.IBinder;
+import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -76,6 +75,7 @@ import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* A service to manage multiple clients that want to access the IpSec API. The service is
@@ -115,6 +115,9 @@ public class IpSecService extends IIpSecService.Stub {
/* Binder context for this service */
private final Context mContext;
+ /* NetworkManager instance */
+ private final INetworkManagementService mNetworkManager;
+
/**
* The next non-repeating global ID for tracking resources between users, this service, and
* kernel data structures. Accessing this variable is not thread safe, so it is only read or
@@ -360,10 +363,14 @@ public class IpSecService extends IIpSecService.Stub {
@VisibleForTesting
static final class UserRecord {
/* Maximum number of each type of resource that a single UID may possess */
- public static final int MAX_NUM_TUNNEL_INTERFACES = 2;
- public static final int MAX_NUM_ENCAP_SOCKETS = 2;
- public static final int MAX_NUM_TRANSFORMS = 4;
- public static final int MAX_NUM_SPIS = 8;
+
+ // Up to 4 active VPNs/IWLAN with potential soft handover.
+ public static final int MAX_NUM_TUNNEL_INTERFACES = 8;
+ public static final int MAX_NUM_ENCAP_SOCKETS = 16;
+
+ // SPIs and Transforms are both cheap, and are 1:1 correlated.
+ public static final int MAX_NUM_TRANSFORMS = 64;
+ public static final int MAX_NUM_SPIS = 64;
/**
* Store each of the OwnedResource types in an (thinly wrapped) sparse array for indexing
@@ -566,7 +573,7 @@ public class IpSecService extends IIpSecService.Stub {
}
void put(int key, RefcountedResource<T> obj) {
- checkNotNull(obj, "Null resources cannot be added");
+ Objects.requireNonNull(obj, "Null resources cannot be added");
mArray.put(key, obj);
}
@@ -989,12 +996,13 @@ public class IpSecService extends IIpSecService.Stub {
*
* @param context Binder context for this service
*/
- private IpSecService(Context context) {
- this(context, IpSecServiceConfiguration.GETSRVINSTANCE);
+ private IpSecService(Context context, INetworkManagementService networkManager) {
+ this(context, networkManager, IpSecServiceConfiguration.GETSRVINSTANCE);
}
- static IpSecService create(Context context) throws InterruptedException {
- final IpSecService service = new IpSecService(context);
+ static IpSecService create(Context context, INetworkManagementService networkManager)
+ throws InterruptedException {
+ final IpSecService service = new IpSecService(context, networkManager);
service.connectNativeNetdService();
return service;
}
@@ -1008,9 +1016,11 @@ public class IpSecService extends IIpSecService.Stub {
/** @hide */
@VisibleForTesting
- public IpSecService(Context context, IpSecServiceConfiguration config) {
+ public IpSecService(Context context, INetworkManagementService networkManager,
+ IpSecServiceConfiguration config) {
this(
context,
+ networkManager,
config,
(fd, uid) -> {
try {
@@ -1024,9 +1034,10 @@ public class IpSecService extends IIpSecService.Stub {
/** @hide */
@VisibleForTesting
- public IpSecService(
- Context context, IpSecServiceConfiguration config, UidFdTagger uidFdTagger) {
+ public IpSecService(Context context, INetworkManagementService networkManager,
+ IpSecServiceConfiguration config, UidFdTagger uidFdTagger) {
mContext = context;
+ mNetworkManager = Objects.requireNonNull(networkManager);
mSrvConfig = config;
mUidFdTagger = uidFdTagger;
}
@@ -1101,7 +1112,7 @@ public class IpSecService extends IIpSecService.Stub {
if (requestedSpi > 0 && requestedSpi < 256) {
throw new IllegalArgumentException("ESP SPI must not be in the range of 0-255.");
}
- checkNotNull(binder, "Null Binder passed to allocateSecurityParameterIndex");
+ Objects.requireNonNull(binder, "Null Binder passed to allocateSecurityParameterIndex");
int callingUid = Binder.getCallingUid();
UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
@@ -1218,7 +1229,7 @@ public class IpSecService extends IIpSecService.Stub {
throw new IllegalArgumentException(
"Specified port number must be a valid non-reserved UDP port");
}
- checkNotNull(binder, "Null Binder passed to openUdpEncapsulationSocket");
+ Objects.requireNonNull(binder, "Null Binder passed to openUdpEncapsulationSocket");
int callingUid = Binder.getCallingUid();
UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
@@ -1278,8 +1289,8 @@ public class IpSecService extends IIpSecService.Stub {
String localAddr, String remoteAddr, Network underlyingNetwork, IBinder binder,
String callingPackage) {
enforceTunnelFeatureAndPermissions(callingPackage);
- checkNotNull(binder, "Null Binder passed to createTunnelInterface");
- checkNotNull(underlyingNetwork, "No underlying network was specified");
+ Objects.requireNonNull(binder, "Null Binder passed to createTunnelInterface");
+ Objects.requireNonNull(underlyingNetwork, "No underlying network was specified");
checkInetAddress(localAddr);
checkInetAddress(remoteAddr);
@@ -1305,6 +1316,10 @@ public class IpSecService extends IIpSecService.Stub {
final INetd netd = mSrvConfig.getNetdInstance();
netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
+ Binder.withCleanCallingIdentity(() -> {
+ mNetworkManager.setInterfaceUp(intfName);
+ });
+
for (int selAddrFamily : ADDRESS_FAMILIES) {
// Always send down correct local/remote addresses for template.
netd.ipSecAddSecurityPolicy(
@@ -1556,7 +1571,7 @@ public class IpSecService extends IIpSecService.Stub {
"IPsec Tunnel Mode requires PackageManager.FEATURE_IPSEC_TUNNELS");
}
- checkNotNull(callingPackage, "Null calling package cannot create IpSec tunnels");
+ Objects.requireNonNull(callingPackage, "Null calling package cannot create IpSec tunnels");
// OP_MANAGE_IPSEC_TUNNELS will return MODE_ERRORED by default, including for the system
// server. If the appop is not granted, require that the caller has the MANAGE_IPSEC_TUNNELS
@@ -1625,12 +1640,12 @@ public class IpSecService extends IIpSecService.Stub {
@Override
public synchronized IpSecTransformResponse createTransform(
IpSecConfig c, IBinder binder, String callingPackage) throws RemoteException {
- checkNotNull(c);
+ Objects.requireNonNull(c);
if (c.getMode() == IpSecTransform.MODE_TUNNEL) {
enforceTunnelFeatureAndPermissions(callingPackage);
}
checkIpSecConfig(c);
- checkNotNull(binder, "Null Binder passed to createTransform");
+ Objects.requireNonNull(binder, "Null Binder passed to createTransform");
final int resourceId = mNextResourceId++;
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 90e467034e6a..f4b769f5b11b 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -25,7 +25,6 @@ import static android.location.LocationProvider.AVAILABLE;
import static android.os.PowerManager.locationPowerSaveModeToString;
import static android.provider.Settings.Global.LOCATION_DISABLE_STATUS_CALLBACKS;
-import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.internal.util.Preconditions.checkState;
import android.Manifest;
@@ -133,6 +132,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.NoSuchElementException;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -986,7 +986,7 @@ public class LocationManagerService extends ILocationManager.Stub {
@GuardedBy("mLock")
public void attachLocked(AbstractLocationProvider provider) {
- checkNotNull(provider);
+ Objects.requireNonNull(provider);
checkState(mProvider == null);
if (D) {
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index ad02aad6e4cd..eac767f7355c 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -46,6 +46,7 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.LinkedList;
+import java.util.Objects;
/**
* Generic connector class for interfacing with a native daemon which uses the
@@ -126,7 +127,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo
*/
public void setWarnIfHeld(Object warnIfHeld) {
Preconditions.checkState(mWarnIfHeld == null);
- mWarnIfHeld = Preconditions.checkNotNull(warnIfHeld);
+ mWarnIfHeld = Objects.requireNonNull(warnIfHeld);
}
@Override
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 7d6ae21a830b..1bb3c3ac0cda 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -111,6 +111,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* @hide
@@ -458,7 +459,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
@Override
public void registerTetheringStatsProvider(ITetheringStatsProvider provider, String name) {
NetworkStack.checkNetworkStackPermission(mContext);
- Preconditions.checkNotNull(provider);
+ Objects.requireNonNull(provider);
synchronized(mTetheringStatsProviders) {
mTetheringStatsProviders.put(provider, name);
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 39ad3546e452..ba1d8ac31bc4 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1934,7 +1934,7 @@ class StorageManagerService extends IStorageManager.Stub
public void setVolumeNickname(String fsUuid, String nickname) {
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
- Preconditions.checkNotNull(fsUuid);
+ Objects.requireNonNull(fsUuid);
synchronized (mLock) {
final VolumeRecord rec = mRecords.get(fsUuid);
rec.nickname = nickname;
@@ -1947,7 +1947,7 @@ class StorageManagerService extends IStorageManager.Stub
public void setVolumeUserFlags(String fsUuid, int flags, int mask) {
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
- Preconditions.checkNotNull(fsUuid);
+ Objects.requireNonNull(fsUuid);
synchronized (mLock) {
final VolumeRecord rec = mRecords.get(fsUuid);
rec.userFlags = (rec.userFlags & ~mask) | (flags & mask);
@@ -1960,7 +1960,7 @@ class StorageManagerService extends IStorageManager.Stub
public void forgetVolume(String fsUuid) {
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
- Preconditions.checkNotNull(fsUuid);
+ Objects.requireNonNull(fsUuid);
synchronized (mLock) {
final VolumeRecord rec = mRecords.remove(fsUuid);
@@ -2361,7 +2361,7 @@ class StorageManagerService extends IStorageManager.Stub
@Override
public String getMountedObbPath(String rawPath) {
- Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
+ Objects.requireNonNull(rawPath, "rawPath cannot be null");
warnOnNotMounted();
@@ -2379,7 +2379,7 @@ class StorageManagerService extends IStorageManager.Stub
@Override
public boolean isObbMounted(String rawPath) {
- Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
+ Objects.requireNonNull(rawPath, "rawPath cannot be null");
synchronized (mObbMounts) {
return mObbPathToStateMap.containsKey(rawPath);
}
@@ -2388,10 +2388,10 @@ class StorageManagerService extends IStorageManager.Stub
@Override
public void mountObb(String rawPath, String canonicalPath, String key,
IObbActionListener token, int nonce, ObbInfo obbInfo) {
- Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
- Preconditions.checkNotNull(canonicalPath, "canonicalPath cannot be null");
- Preconditions.checkNotNull(token, "token cannot be null");
- Preconditions.checkNotNull(obbInfo, "obbIfno cannot be null");
+ Objects.requireNonNull(rawPath, "rawPath cannot be null");
+ Objects.requireNonNull(canonicalPath, "canonicalPath cannot be null");
+ Objects.requireNonNull(token, "token cannot be null");
+ Objects.requireNonNull(obbInfo, "obbIfno cannot be null");
final int callingUid = Binder.getCallingUid();
final ObbState obbState = new ObbState(rawPath, canonicalPath,
@@ -2405,7 +2405,7 @@ class StorageManagerService extends IStorageManager.Stub
@Override
public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce) {
- Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
+ Objects.requireNonNull(rawPath, "rawPath cannot be null");
final ObbState existingState;
synchronized (mObbMounts) {
diff --git a/services/core/java/com/android/server/SystemServerInitThreadPool.java b/services/core/java/com/android/server/SystemServerInitThreadPool.java
index ff6a5375565a..ba829381b9d4 100644
--- a/services/core/java/com/android/server/SystemServerInitThreadPool.java
+++ b/services/core/java/com/android/server/SystemServerInitThreadPool.java
@@ -26,6 +26,7 @@ import com.android.server.am.ActivityManagerService;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 45868932be2b..ac897e464659 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -168,14 +168,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
@Override
public String toString() {
- return "{callingPackage=" + callingPackage + " binder=" + binder
- + " callback=" + callback
+ return "{callingPackage=" + pii(callingPackage) + " callerUid=" + callerUid + " binder="
+ + binder + " callback=" + callback
+ " onSubscriptionsChangedListenererCallback="
+ onSubscriptionsChangedListenerCallback
+ " onOpportunisticSubscriptionsChangedListenererCallback="
- + onOpportunisticSubscriptionsChangedListenerCallback
- + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
- + " events=" + Integer.toHexString(events) + "}";
+ + onOpportunisticSubscriptionsChangedListenerCallback + " subId=" + subId
+ + " phoneId=" + phoneId + " events=" + Integer.toHexString(events) + "}";
}
}
@@ -598,9 +597,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
int callerUserId = UserHandle.getCallingUserId();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
if (VDBG) {
- log("listen oscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId()
- + " callerUserId=" + callerUserId + " callback=" + callback
- + " callback.asBinder=" + callback.asBinder());
+ log("listen oscl: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
+ + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId
+ + " callback=" + callback + " callback.asBinder=" + callback.asBinder());
}
synchronized (mRecords) {
@@ -652,9 +651,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
int callerUserId = UserHandle.getCallingUserId();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
if (VDBG) {
- log("listen ooscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId()
- + " callerUserId=" + callerUserId + " callback=" + callback
- + " callback.asBinder=" + callback.asBinder());
+ log("listen ooscl: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
+ + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId
+ + " callback=" + callback + " callback.asBinder=" + callback.asBinder());
}
synchronized (mRecords) {
@@ -769,9 +768,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
IPhoneStateListener callback, int events, boolean notifyNow, int subId) {
int callerUserId = UserHandle.getCallingUserId();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
- String str = "listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events)
- + " notifyNow=" + notifyNow + " subId=" + subId + " myUserId="
- + UserHandle.myUserId() + " callerUserId=" + callerUserId;
+ String str = "listen: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
+ + " events=0x" + Integer.toHexString(events) + " notifyNow=" + notifyNow + " subId="
+ + subId + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId;
mListenLog.log(str);
if (VDBG) {
log(str);
@@ -1538,17 +1537,15 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
synchronized (mRecords) {
if (validatePhoneId(phoneId)) {
- if (mDisplayInfos[phoneId] != null) {
- mDisplayInfos[phoneId] = displayInfo;
- for (Record r : mRecords) {
- if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
- && idMatch(r.subId, subId, phoneId)) {
- try {
- r.callback.onDisplayInfoChanged(displayInfo);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
- }
+ mDisplayInfos[phoneId] = displayInfo;
+ for (Record r : mRecords) {
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
+ && idMatch(r.subId, subId, phoneId)) {
+ try {
+ r.callback.onDisplayInfoChanged(displayInfo);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
}
}
}
@@ -2937,4 +2934,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (info == null) return INVALID_SIM_SLOT_INDEX;
return info.getSimSlotIndex();
}
+
+ /**
+ * On certain build types, we should redact information by default. UID information will be
+ * preserved in the same log line, so no debugging capability is lost in full bug reports.
+ * However, privacy-constrained bug report types (e.g. connectivity) cannot display raw
+ * package names on user builds as it's considered an information leak.
+ */
+ private static String pii(String packageName) {
+ return Build.IS_DEBUGGABLE ? packageName : "***";
+ }
}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 454941ccdb03..5f9d1d801441 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -115,6 +115,7 @@ public class Watchdog extends Thread {
"android.hardware.media.c2@1.0::IComponentStore",
"android.hardware.media.omx@1.0::IOmx",
"android.hardware.media.omx@1.0::IOmxStore",
+ "android.hardware.neuralnetworks@1.0::IDevice",
"android.hardware.power.stats@1.0::IPowerStats",
"android.hardware.sensors@1.0::ISensors",
"android.hardware.vr@1.0::IVr",
diff --git a/services/core/java/com/android/server/accounts/TokenCache.java b/services/core/java/com/android/server/accounts/TokenCache.java
index 2af2f38d8ba7..2aa9776fcab1 100644
--- a/services/core/java/com/android/server/accounts/TokenCache.java
+++ b/services/core/java/com/android/server/accounts/TokenCache.java
@@ -148,7 +148,7 @@ import java.util.Objects;
accountEvictor = new Evictor();
}
accountEvictor.add(k);
- mAccountEvictors.put(k.account, tokenEvictor);
+ mAccountEvictors.put(k.account, accountEvictor);
// Only cache the token once we can remove it directly or by account.
put(k, v);
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index d935162a629b..f5cefb3ff1ea 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -106,7 +106,6 @@ import com.android.server.pm.dex.DexManager;
import com.android.server.wm.ActivityServiceConnectionsHolder;
import com.android.server.wm.WindowManagerService;
-import dalvik.annotation.compat.VersionCodes;
import dalvik.system.VMRuntime;
import java.io.File;
@@ -290,7 +289,7 @@ public final class ProcessList {
* Pointers</a>
*/
@ChangeId
- @EnabledAfter(targetSdkVersion = VersionCodes.Q)
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id.
ActivityManagerService mService = null;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index e5cd783f2047..fc6d9f7b7849 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4318,6 +4318,7 @@ public class AudioService extends IAudioService.Stub
public void setWiredDeviceConnectionState(int type,
@ConnectionState int state, String address, String name,
String caller) {
+ enforceModifyAudioRoutingPermission();
if (state != CONNECTION_STATE_CONNECTED
&& state != CONNECTION_STATE_DISCONNECTED) {
throw new IllegalArgumentException("Invalid state " + state);
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 5059a4861a7b..7c8fb5aefd1e 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -220,9 +220,9 @@ public class KeepaliveTracker {
+ " network=" + mNai.network
+ " startedState=" + startedStateString(mStartedState)
+ " "
- + IpUtils.addressAndPortToString(mPacket.srcAddress, mPacket.srcPort)
+ + IpUtils.addressAndPortToString(mPacket.getSrcAddress(), mPacket.getSrcPort())
+ "->"
- + IpUtils.addressAndPortToString(mPacket.dstAddress, mPacket.dstPort)
+ + IpUtils.addressAndPortToString(mPacket.getDstAddress(), mPacket.getDstPort())
+ " interval=" + mInterval
+ " uid=" + mUid + " pid=" + mPid + " privileged=" + mPrivileged
+ " packetData=" + HexDump.toHexString(mPacket.getPacket())
@@ -250,7 +250,7 @@ public class KeepaliveTracker {
private int checkSourceAddress() {
// Check that we have the source address.
for (InetAddress address : mNai.linkProperties.getAddresses()) {
- if (address.equals(mPacket.srcAddress)) {
+ if (address.equals(mPacket.getSrcAddress())) {
return SUCCESS;
}
}
@@ -619,7 +619,7 @@ public class KeepaliveTracker {
packet = NattKeepalivePacketData.nattKeepalivePacket(
srcAddress, srcPort, dstAddress, NATT_PORT);
} catch (InvalidPacketException e) {
- notifyErrorCallback(cb, e.error);
+ notifyErrorCallback(cb, e.getError());
return;
}
KeepaliveInfo ki = null;
@@ -662,7 +662,7 @@ public class KeepaliveTracker {
notifyErrorCallback(cb, e.error);
return;
} catch (InvalidPacketException e) {
- notifyErrorCallback(cb, e.error);
+ notifyErrorCallback(cb, e.getError());
return;
}
KeepaliveInfo ki = null;
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 0925de8f9577..34b0aa246433 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -150,7 +150,7 @@ public class NetworkNotificationManager {
if (nai != null) {
transportType = approximateTransportType(nai);
final String extraInfo = nai.networkInfo.getExtraInfo();
- name = TextUtils.isEmpty(extraInfo) ? nai.networkCapabilities.getSSID() : extraInfo;
+ name = TextUtils.isEmpty(extraInfo) ? nai.networkCapabilities.getSsid() : extraInfo;
// Only notify for Internet-capable networks.
if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)) return;
} else {
@@ -183,14 +183,14 @@ public class NetworkNotificationManager {
int icon = getIcon(transportType);
if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
title = r.getString(R.string.wifi_no_internet,
- WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
details = r.getString(R.string.wifi_no_internet_detailed);
} else if (notifyType == NotificationType.PRIVATE_DNS_BROKEN) {
if (transportType == TRANSPORT_CELLULAR) {
title = r.getString(R.string.mobile_no_internet);
} else if (transportType == TRANSPORT_WIFI) {
title = r.getString(R.string.wifi_no_internet,
- WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
} else {
title = r.getString(R.string.other_networks_no_internet);
}
@@ -198,19 +198,19 @@ public class NetworkNotificationManager {
} else if (notifyType == NotificationType.PARTIAL_CONNECTIVITY
&& transportType == TRANSPORT_WIFI) {
title = r.getString(R.string.network_partial_connectivity,
- WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
details = r.getString(R.string.network_partial_connectivity_detailed);
} else if (notifyType == NotificationType.LOST_INTERNET &&
transportType == TRANSPORT_WIFI) {
title = r.getString(R.string.wifi_no_internet,
- WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
details = r.getString(R.string.wifi_no_internet_detailed);
} else if (notifyType == NotificationType.SIGN_IN) {
switch (transportType) {
case TRANSPORT_WIFI:
title = r.getString(R.string.wifi_available_sign_in, 0);
details = r.getString(R.string.network_available_sign_in_detailed,
- WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+ WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
break;
case TRANSPORT_CELLULAR:
title = r.getString(R.string.network_available_sign_in, 0);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 0392807bcb37..22ed661b03c0 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -3091,31 +3091,64 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) {
// nothing to check if no plans
if (plans.length == 0) {
+ Log.d(TAG, "Received empty plans list. Clearing existing SubscriptionPlans.");
return;
}
- long applicableNetworkTypes = 0;
- boolean allNetworks = false;
- for (SubscriptionPlan plan : plans) {
- if (plan.getNetworkTypes() == null) {
- allNetworks = true;
+ final int[] allNetworkTypes = TelephonyManager.getAllNetworkTypes();
+ final ArraySet<Integer> allNetworksSet = new ArraySet<>();
+ addAll(allNetworksSet, allNetworkTypes);
+
+ final ArraySet<Integer> applicableNetworkTypes = new ArraySet<>();
+ boolean hasGeneralPlan = false;
+ for (int i = 0; i < plans.length; i++) {
+ final int[] planNetworkTypes = plans[i].getNetworkTypes();
+ final ArraySet<Integer> planNetworksSet = new ArraySet<>();
+ for (int j = 0; j < planNetworkTypes.length; j++) {
+ // ensure all network types are valid
+ if (allNetworksSet.contains(planNetworkTypes[j])) {
+ // ensure no duplicate network types in the same SubscriptionPlan
+ if (!planNetworksSet.add(planNetworkTypes[j])) {
+ throw new IllegalArgumentException(
+ "Subscription plan contains duplicate network types.");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid network type: "
+ + planNetworkTypes[j]);
+ }
+ }
+
+ if (planNetworkTypes.length == allNetworkTypes.length) {
+ hasGeneralPlan = true;
} else {
- if ((applicableNetworkTypes & plan.getNetworkTypesBitMask()) != 0) {
+ // ensure no network type applies to multiple plans
+ if (!addAll(applicableNetworkTypes, planNetworkTypes)) {
throw new IllegalArgumentException(
"Multiple subscription plans defined for a single network type.");
- } else {
- applicableNetworkTypes |= plan.getNetworkTypesBitMask();
}
}
}
// ensure at least one plan applies for every network type
- if (!allNetworks) {
+ if (!hasGeneralPlan) {
throw new IllegalArgumentException(
"No generic subscription plan that applies to all network types.");
}
}
+ /**
+ * Adds all of the {@code elements} to the {@code set}.
+ *
+ * @return {@code false} if any element is not added because the set already has the value.
+ */
+ private static boolean addAll(@NonNull ArraySet<Integer> set, @NonNull int... elements) {
+ boolean result = true;
+ for (int i = 0; i < elements.length; i++) {
+ result &= set.add(elements[i]);
+ }
+ return result;
+ }
+
@Override
public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) {
enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index ebc41916d034..0e3268b8b9f2 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -844,13 +844,13 @@ public class ZenModeHelper {
final boolean policyChanged = !Objects.equals(getNotificationPolicy(mConfig),
getNotificationPolicy(config));
if (!config.equals(mConfig)) {
+ mConfig = config;
dispatchOnConfigChanged();
updateConsolidatedPolicy(reason);
}
if (policyChanged) {
dispatchOnPolicyChanged();
}
- mConfig = config;
mHandler.postApplyConfig(config, reason, triggeringComponent, setRingerMode);
return true;
} catch (SecurityException e) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index d0167c58df9f..6f6c3152fb9d 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1090,19 +1090,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
assertMultiPackageConsistencyLocked(childSessions);
}
- if (params.isStaged) {
- final PackageInstallerSession activeSession = mStagingManager.getActiveSession();
- final boolean anotherSessionAlreadyInProgress =
- activeSession != null && sessionId != activeSession.sessionId
- && mParentSessionId != activeSession.sessionId;
- if (anotherSessionAlreadyInProgress) {
- throw new PackageManagerException(
- PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
- "There is already in-progress committed staged session "
- + activeSession.sessionId, null);
- }
- }
-
// Read transfers from the original owner stay open, but as the session's data
// cannot be modified anymore, there is no leak of information. For staged sessions,
// further validation is performed by the staging manager.
@@ -1125,6 +1112,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new PackageManagerException(e);
}
}
+
+ if (params.isStaged) {
+ mStagingManager.checkNonOverlappingWithStagedSessions(this);
+ }
} catch (PackageManagerException e) {
// Session is sealed but could not be verified, we need to destroy it.
destroyInternal();
@@ -1449,7 +1440,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
/**
* Validate apex install.
* <p>
- * Sets {@link #mResolvedBaseFile} for RollbackManager to use.
+ * Sets {@link #mResolvedBaseFile} for RollbackManager to use. Sets {@link #mPackageName} for
+ * StagingManager to use.
*/
@GuardedBy("mLock")
private void validateApexInstallLocked()
@@ -1478,8 +1470,22 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final File targetFile = new File(stageDir, targetName);
resolveAndStageFile(addedFile, targetFile);
-
mResolvedBaseFile = targetFile;
+
+ // Populate package name of the apex session
+ mPackageName = null;
+ final ApkLite apk;
+ try {
+ apk = PackageParser.parseApkLite(
+ mResolvedBaseFile, PackageParser.PARSE_COLLECT_CERTIFICATES);
+ } catch (PackageParserException e) {
+ throw PackageManagerException.from(e);
+ }
+
+ if (mPackageName == null) {
+ mPackageName = apk.packageName;
+ mVersionCode = apk.getLongVersionCode();
+ }
}
/**
@@ -1848,6 +1854,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
/**
+ * @return the package name of this session
+ */
+ String getPackageName() {
+ synchronized (mLock) {
+ return mPackageName;
+ }
+ }
+
+ /**
* @return the timestamp of when this session last changed state
*/
public long getUpdatedMillis() {
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 15e2fd579cc4..96ccba5b4d6f 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -539,25 +539,95 @@ public class StagingManager {
mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId);
}
- @Nullable
- PackageInstallerSession getActiveSession() {
+ /**
+ * <p> Check if the session provided is non-overlapping with the active staged sessions.
+ *
+ * <p> A session is non-overlapping if it meets one of the following conditions: </p>
+ * <ul>
+ * <li>It is a parent session</li>
+ * <li>It is already one of the active sessions</li>
+ * <li>Its package name is not same as any of the active sessions</li>
+ * </ul>
+ * @throws PackageManagerException if session fails the check
+ */
+ void checkNonOverlappingWithStagedSessions(@NonNull PackageInstallerSession session)
+ throws PackageManagerException {
+ if (session.isMultiPackage()) {
+ // We cannot say a parent session overlaps until we process its children
+ return;
+ }
+ if (session.getPackageName() == null) {
+ throw new PackageManagerException(PackageManager.INSTALL_FAILED_INVALID_APK,
+ "Cannot stage session " + session.sessionId + " with package name null");
+ }
+
synchronized (mStagedSessions) {
for (int i = 0; i < mStagedSessions.size(); i++) {
- final PackageInstallerSession session = mStagedSessions.valueAt(i);
- if (!session.isCommitted()) {
+ final PackageInstallerSession stagedSession = mStagedSessions.valueAt(i);
+ if (!stagedSession.isCommitted() || stagedSession.isStagedAndInTerminalState()) {
continue;
}
- if (session.hasParentSessionId()) {
- // Staging manager will finalize only parent session. Ignore child sessions
- // picking the active.
+ if (stagedSession.isMultiPackage()) {
+ // This active parent staged session is useless as it doesn't have a package
+ // name and the session we are checking is not a parent session either.
+ continue;
+ }
+
+ // From here on, stagedSession is a non-parent active staged session
+
+ // Check if stagedSession has an active parent session or not
+ if (stagedSession.hasParentSessionId()) {
+ int parentId = stagedSession.getParentSessionId();
+ PackageInstallerSession parentSession = mStagedSessions.get(parentId);
+ if (parentSession == null || parentSession.isStagedAndInTerminalState()) {
+ // Parent session has been abandoned or terminated already
+ continue;
+ }
+ }
+
+ // Check if session is one of the active sessions
+ if (session.sessionId == stagedSession.sessionId) {
+ Slog.w(TAG, "Session " + session.sessionId + " is already staged");
continue;
}
- if (!session.isStagedSessionApplied() && !session.isStagedSessionFailed()) {
- return session;
+
+ // If session is not among the active sessions, then it cannot have same package
+ // name as any of the active sessions.
+ if (session.getPackageName().equals(stagedSession.getPackageName())) {
+ throw new PackageManagerException(
+ PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
+ "Package: " + session.getPackageName() + " in session: "
+ + session.sessionId + " has been staged already by session: "
+ + stagedSession.sessionId, null);
+ }
+
+ // TODO(b/141843321): Add support for staging multiple sessions in apexd
+ // Since apexd doesn't support multiple staged sessions yet, we have to careful how
+ // we handle apex sessions. We want to allow a set of apex sessions under the same
+ // parent to be staged when there is no previously staged apex sessions.
+ if (isApexSession(session) && isApexSession(stagedSession)) {
+ // session is apex and it can co-exist with stagedSession only if they are from
+ // same parent
+ final boolean coExist;
+ if (!session.hasParentSessionId() && !stagedSession.hasParentSessionId()) {
+ // Both single package apex sessions. Cannot co-exist.
+ coExist = false;
+ } else {
+ // At least one of the session has parent. Both must be from same parent.
+ coExist =
+ session.getParentSessionId() == stagedSession.getParentSessionId();
+ }
+ if (!coExist) {
+ throw new PackageManagerException(
+ PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
+ "Package: " + session.getPackageName() + " in session: "
+ + session.sessionId + " cannot be staged as there is "
+ + "already another apex staged session: "
+ + stagedSession.sessionId, null);
+ }
}
}
}
- return null;
}
void createSession(@NonNull PackageInstallerSession sessionInfo) {
@@ -584,7 +654,8 @@ public class StagingManager {
ApexSessionInfo apexSession = mApexManager.getStagedSessionInfo(session.sessionId);
if (apexSession == null || isApexSessionFinalized(apexSession)) {
Slog.w(TAG,
- "Cannot abort session because it is not active or APEXD is not reachable");
+ "Cannot abort session " + session.sessionId
+ + " because it is not active or APEXD is not reachable");
return;
}
mApexManager.abortActiveSession();
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 0ab1a3e916e3..4be4c896cbff 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -10,3 +10,4 @@ roosa@google.com
erosky@google.com
riddlehsu@google.com
louischang@google.com
+winsonc@google.com
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2b28ca228b1f..afa8c468cb48 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1328,7 +1328,7 @@ public final class SystemServer {
traceBeginAndSlog("StartIpSecService");
try {
- ipSecService = IpSecService.create(context);
+ ipSecService = IpSecService.create(context, networkManagement);
ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);
} catch (Throwable e) {
reportWtf("starting IpSec Service", e);
diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java
index fcf3a56de448..c0c386b3046e 100644
--- a/services/net/java/android/net/TcpKeepalivePacketData.java
+++ b/services/net/java/android/net/TcpKeepalivePacketData.java
@@ -152,10 +152,12 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
public boolean equals(@Nullable final Object o) {
if (!(o instanceof TcpKeepalivePacketData)) return false;
final TcpKeepalivePacketData other = (TcpKeepalivePacketData) o;
- return this.srcAddress.equals(other.srcAddress)
- && this.dstAddress.equals(other.dstAddress)
- && this.srcPort == other.srcPort
- && this.dstPort == other.dstPort
+ final InetAddress srcAddress = getSrcAddress();
+ final InetAddress dstAddress = getDstAddress();
+ return srcAddress.equals(other.getSrcAddress())
+ && dstAddress.equals(other.getDstAddress())
+ && getSrcPort() == other.getSrcPort()
+ && getDstPort() == other.getDstPort()
&& this.tcpAck == other.tcpAck
&& this.tcpSeq == other.tcpSeq
&& this.tcpWnd == other.tcpWnd
@@ -166,8 +168,8 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
@Override
public int hashCode() {
- return Objects.hash(srcAddress, dstAddress, srcPort, dstPort, tcpAck, tcpSeq, tcpWnd,
- tcpWndScale, ipTos, ipTtl);
+ return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort(),
+ tcpAck, tcpSeq, tcpWnd, tcpWndScale, ipTos, ipTtl);
}
/**
@@ -182,10 +184,10 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
/** Write to parcel. */
public void writeToParcel(Parcel out, int flags) {
- out.writeString(srcAddress.getHostAddress());
- out.writeString(dstAddress.getHostAddress());
- out.writeInt(srcPort);
- out.writeInt(dstPort);
+ out.writeString(getSrcAddress().getHostAddress());
+ out.writeString(getDstAddress().getHostAddress());
+ out.writeInt(getSrcPort());
+ out.writeInt(getDstPort());
out.writeByteArray(getPacket());
out.writeInt(tcpSeq);
out.writeInt(tcpAck);
@@ -219,7 +221,7 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
return readFromParcel(in);
} catch (InvalidPacketException e) {
throw new IllegalArgumentException(
- "Invalid NAT-T keepalive data: " + e.error);
+ "Invalid NAT-T keepalive data: " + e.getError());
}
}
@@ -234,10 +236,12 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
@NonNull
public TcpKeepalivePacketDataParcelable toStableParcelable() {
final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable();
+ final InetAddress srcAddress = getSrcAddress();
+ final InetAddress dstAddress = getDstAddress();
parcel.srcAddress = srcAddress.getAddress();
- parcel.srcPort = srcPort;
+ parcel.srcPort = getSrcPort();
parcel.dstAddress = dstAddress.getAddress();
- parcel.dstPort = dstPort;
+ parcel.dstPort = getDstPort();
parcel.seq = tcpSeq;
parcel.ack = tcpAck;
parcel.rcvWnd = tcpWnd;
@@ -249,10 +253,10 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce
@Override
public String toString() {
- return "saddr: " + srcAddress
- + " daddr: " + dstAddress
- + " sport: " + srcPort
- + " dport: " + dstPort
+ return "saddr: " + getSrcAddress()
+ + " daddr: " + getDstAddress()
+ + " sport: " + getSrcPort()
+ + " dport: " + getDstPort()
+ " seq: " + tcpSeq
+ " ack: " + tcpAck
+ " wnd: " + tcpWnd
diff --git a/services/net/java/android/net/util/KeepalivePacketDataUtil.java b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
index 9a51729212f7..4466ea0abe0e 100644
--- a/services/net/java/android/net/util/KeepalivePacketDataUtil.java
+++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
@@ -20,6 +20,8 @@ import android.annotation.NonNull;
import android.net.NattKeepalivePacketData;
import android.net.NattKeepalivePacketDataParcelable;
+import java.net.InetAddress;
+
/** @hide */
public final class KeepalivePacketDataUtil {
/**
@@ -29,11 +31,12 @@ public final class KeepalivePacketDataUtil {
public static NattKeepalivePacketDataParcelable toStableParcelable(
NattKeepalivePacketData pkt) {
final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
-
- parcel.srcAddress = pkt.srcAddress.getAddress();
- parcel.srcPort = pkt.srcPort;
- parcel.dstAddress = pkt.dstAddress.getAddress();
- parcel.dstPort = pkt.dstPort;
+ final InetAddress srcAddress = pkt.getSrcAddress();
+ final InetAddress dstAddress = pkt.getDstAddress();
+ parcel.srcAddress = srcAddress.getAddress();
+ parcel.srcPort = pkt.getSrcPort();
+ parcel.dstAddress = dstAddress.getAddress();
+ parcel.dstPort = pkt.getDstPort();
return parcel;
}
}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index c5fcf67c9be9..ead90bb4561f 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -2075,6 +2075,17 @@ public final class Call {
/**
* Returns the child {@link Call} in a generic conference that is currently active.
+ *
+ * A "generic conference" is the mechanism used to support two simultaneous calls on a device
+ * in CDMA networks. It is effectively equivalent to having one call active and one call on hold
+ * in GSM or IMS calls. This method returns the currently active call.
+ *
+ * In a generic conference, the network exposes the conference to us as a single call, and we
+ * switch between talking to the two participants using a CDMA flash command. Since the network
+ * exposes no additional information about the call, the only way we know which caller we're
+ * currently talking to is by keeping track of the flash commands that we've sent to the
+ * network.
+ *
* For calls that are not generic conferences, or when the generic conference has more than
* 2 children, returns {@code null}.
* @see Details#PROPERTY_GENERIC_CONFERENCE
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
index 2b9213ba9dbc..b8ad9e2fbe6c 100644
--- a/telecomm/java/android/telecom/ParcelableCallAnalytics.java
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
@@ -258,27 +258,6 @@ public class ParcelableCallAnalytics implements Parcelable {
public static final int SIP_PHONE = 0x8;
public static final int THIRD_PARTY_PHONE = 0x10;
- /**
- * Indicating the call source is not specified.
- *
- * @hide
- */
- public static final int CALL_SOURCE_UNSPECIFIED = 0;
-
- /**
- * Indicating the call is initiated via emergency dialer's dialpad.
- *
- * @hide
- */
- public static final int CALL_SOURCE_EMERGENCY_DIALPAD = 1;
-
- /**
- * Indicating the call is initiated via emergency dialer's shortcut button.
- *
- * @hide
- */
- public static final int CALL_SOURCE_EMERGENCY_SHORTCUT = 2;
-
public static final long MILLIS_IN_5_MINUTES = 1000 * 60 * 5;
public static final long MILLIS_IN_1_SECOND = 1000;
@@ -343,7 +322,7 @@ public class ParcelableCallAnalytics implements Parcelable {
private List<VideoEvent> videoEvents;
// The source where user initiated this call. ONE OF the CALL_SOURCE_* constants.
- private int callSource = CALL_SOURCE_UNSPECIFIED;
+ private int callSource = TelecomManager.CALL_SOURCE_UNSPECIFIED;
public ParcelableCallAnalytics(long startTimeMillis, long callDurationMillis, int callType,
boolean isAdditionalCall, boolean isInterrupted, int callTechnologies,
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 6ae4a08abaa3..768c8eebf067 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -82,8 +82,10 @@ public final class PhoneAccount implements Parcelable {
public static final String EXTRA_CALL_SUBJECT_CHARACTER_ENCODING =
"android.telecom.extra.CALL_SUBJECT_CHARACTER_ENCODING";
- /**
- * Indicating flag for phone account whether to use voip audio mode for voip calls
+ /**
+ * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+ * indicates that all calls from this {@link PhoneAccount} should be treated as VoIP calls
+ * rather than cellular calls.
* @hide
*/
public static final String EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE =
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 19a1021e57e2..8be146dd02fe 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -312,6 +312,9 @@ public class TelecomManager {
"android.telecom.extra.IS_USER_INTENT_EMERGENCY_CALL";
/**
+ * A mandatory extra containing a {@link Uri} to be passed in when calling
+ * {@link #addNewUnknownCall(PhoneAccountHandle, Bundle)}. The {@link Uri} value indicates
+ * the remote handle of the new call.
* @hide
*/
public static final String EXTRA_UNKNOWN_CALL_HANDLE =
@@ -373,8 +376,15 @@ public class TelecomManager {
"android.telecom.extra.CONNECTION_SERVICE";
/**
- * Optional extra for communicating the call technology used by a
- * {@link com.android.internal.telephony.Connection} to Telecom
+ * Optional extra for communicating the call technology used by a {@link ConnectionService}
+ * to Telecom. Valid values are:
+ * <ul>
+ * <li>{@link TelephonyManager#PHONE_TYPE_CDMA}</li>
+ * <li>{@link TelephonyManager#PHONE_TYPE_GSM}</li>
+ * <li>{@link TelephonyManager#PHONE_TYPE_IMS}</li>
+ * <li>{@link TelephonyManager#PHONE_TYPE_THIRD_PARTY}</li>
+ * <li>{@link TelephonyManager#PHONE_TYPE_SIP}</li>
+ * </ul>
* @hide
*/
public static final String EXTRA_CALL_TECHNOLOGY_TYPE =
@@ -725,15 +735,16 @@ public class TelecomManager {
/**
* The lookup key for an int that indicates the current TTY mode.
* Valid modes are:
- * - {@link #TTY_MODE_OFF}
- * - {@link #TTY_MODE_FULL}
- * - {@link #TTY_MODE_HCO}
- * - {@link #TTY_MODE_VCO}
- *
+ * <ul>
+ * <li>{@link #TTY_MODE_OFF}</li>
+ * <li>{@link #TTY_MODE_FULL}</li>
+ * <li>{@link #TTY_MODE_HCO}</li>
+ * <li>{@link #TTY_MODE_VCO}</li>
+ * </ul>
* @hide
*/
public static final String EXTRA_CURRENT_TTY_MODE =
- "android.telecom.intent.extra.CURRENT_TTY_MODE";
+ "android.telecom.extra.CURRENT_TTY_MODE";
/**
* Broadcast intent action indicating that the TTY preferred operating mode has changed. An
@@ -753,7 +764,7 @@ public class TelecomManager {
* @hide
*/
public static final String EXTRA_TTY_PREFERRED_MODE =
- "android.telecom.intent.extra.TTY_PREFERRED";
+ "android.telecom.extra.TTY_PREFERRED_MODE";
/**
* Broadcast intent action for letting custom component know to show the missed call
@@ -822,16 +833,37 @@ public class TelecomManager {
/**
* Optional extra for {@link #placeCall(Uri, Bundle)} containing an integer that specifies
* the source where user initiated this call. This data is used in metrics.
- * Valid source are:
- * {@link ParcelableCallAnalytics#CALL_SOURCE_UNSPECIFIED},
- * {@link ParcelableCallAnalytics#CALL_SOURCE_EMERGENCY_DIALPAD},
- * {@link ParcelableCallAnalytics#CALL_SOURCE_EMERGENCY_SHORTCUT}.
+ * Valid sources are:
+ * {@link TelecomManager#CALL_SOURCE_UNSPECIFIED},
+ * {@link TelecomManager#CALL_SOURCE_EMERGENCY_DIALPAD},
+ * {@link TelecomManager#CALL_SOURCE_EMERGENCY_SHORTCUT}.
*
* @hide
*/
public static final String EXTRA_CALL_SOURCE = "android.telecom.extra.CALL_SOURCE";
/**
+ * Indicating the call is initiated via emergency dialer's shortcut button.
+ *
+ * @hide
+ */
+ public static final int CALL_SOURCE_EMERGENCY_SHORTCUT = 2;
+
+ /**
+ * Indicating the call is initiated via emergency dialer's dialpad.
+ *
+ * @hide
+ */
+ public static final int CALL_SOURCE_EMERGENCY_DIALPAD = 1;
+
+ /**
+ * Indicating the call source is not specified.
+ *
+ * @hide
+ */
+ public static final int CALL_SOURCE_UNSPECIFIED = 0;
+
+ /**
* The following 4 constants define how properties such as phone numbers and names are
* displayed to the user.
*/
diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index de0221c7c2b1..3c1e707ab1dd 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -31,6 +31,7 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.util.ArrayUtils;
import com.android.server.SystemConfig;
@@ -156,7 +157,7 @@ public final class CarrierAppUtils {
for (ApplicationInfo ai : candidates) {
String packageName = ai.packageName;
String[] restrictedCarrierApps = Resources.getSystem().getStringArray(
- android.R.array.config_restrictedPreinstalledCarrierApps);
+ R.array.config_restrictedPreinstalledCarrierApps);
boolean hasPrivileges = telephonyManager != null
&& telephonyManager.checkCarrierPrivilegesForPackageAnyPhone(packageName)
== TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
diff --git a/telephony/common/com/android/internal/telephony/GsmAlphabet.java b/telephony/common/com/android/internal/telephony/GsmAlphabet.java
index 2201452e9011..60cd40094950 100644
--- a/telephony/common/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/common/com/android/internal/telephony/GsmAlphabet.java
@@ -19,10 +19,12 @@ package com.android.internal.telephony;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.os.Build;
-import android.text.TextUtils;
import android.util.Log;
+import android.text.TextUtils;
import android.util.SparseIntArray;
+import com.android.internal.R;
+
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
@@ -1085,10 +1087,8 @@ public class GsmAlphabet {
private static void enableCountrySpecificEncodings() {
Resources r = Resources.getSystem();
// See comments in frameworks/base/core/res/res/values/config.xml for allowed values
- sEnabledSingleShiftTables = r.getIntArray(
- android.R.array.config_sms_enabled_single_shift_tables);
- sEnabledLockingShiftTables = r.getIntArray(
- android.R.array.config_sms_enabled_locking_shift_tables);
+ sEnabledSingleShiftTables = r.getIntArray(R.array.config_sms_enabled_single_shift_tables);
+ sEnabledLockingShiftTables = r.getIntArray(R.array.config_sms_enabled_locking_shift_tables);
if (sEnabledSingleShiftTables.length > 0) {
sHighestEnabledSingleShiftCode =
diff --git a/telephony/common/com/google/android/mms/util/SqliteWrapper.java b/telephony/common/com/google/android/mms/util/SqliteWrapper.java
index 4871434ebc31..31fe4d7683d6 100644
--- a/telephony/common/com/google/android/mms/util/SqliteWrapper.java
+++ b/telephony/common/com/google/android/mms/util/SqliteWrapper.java
@@ -60,7 +60,8 @@ public final class SqliteWrapper {
@UnsupportedAppUsage
public static void checkSQLiteException(Context context, SQLiteException e) {
if (isLowMemory(e)) {
- Toast.makeText(context, android.R.string.low_memory, Toast.LENGTH_SHORT).show();
+ Toast.makeText(context, com.android.internal.R.string.low_memory,
+ Toast.LENGTH_SHORT).show();
} else {
throw e;
}
diff --git a/telephony/java/android/service/carrier/CarrierService.java b/telephony/java/android/service/carrier/CarrierService.java
index eefc1b70bac9..d06ec11f3e61 100644
--- a/telephony/java/android/service/carrier/CarrierService.java
+++ b/telephony/java/android/service/carrier/CarrierService.java
@@ -25,6 +25,9 @@ import android.os.ResultReceiver;
import android.telephony.TelephonyRegistryManager;
import android.util.Log;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
/**
* A service that exposes carrier-specific functionality to the system.
* <p>
@@ -156,5 +159,10 @@ public abstract class CarrierService extends Service {
result.send(RESULT_ERROR, null);
}
}
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ CarrierService.this.dump(fd, pw, args);
+ }
}
}
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 85db35d1ca08..ccda88f717c3 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -611,48 +611,6 @@ public class Annotation {
}
/**
- * Call forwarding function status
- */
- @IntDef(prefix = { "STATUS_" }, value = {
- CallForwardingInfo.STATUS_ACTIVE,
- CallForwardingInfo.STATUS_INACTIVE,
- CallForwardingInfo.STATUS_UNKNOWN_ERROR,
- CallForwardingInfo.STATUS_NOT_SUPPORTED,
- CallForwardingInfo.STATUS_FDN_CHECK_FAILURE
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CallForwardingStatus {
- }
-
- /**
- * Call forwarding reason types
- */
- @IntDef(flag = true, prefix = { "REASON_" }, value = {
- CallForwardingInfo.REASON_UNCONDITIONAL,
- CallForwardingInfo.REASON_BUSY,
- CallForwardingInfo.REASON_NO_REPLY,
- CallForwardingInfo.REASON_NOT_REACHABLE,
- CallForwardingInfo.REASON_ALL,
- CallForwardingInfo.REASON_ALL_CONDITIONAL
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CallForwardingReason {
- }
-
- /**
- * Call waiting function status
- */
- @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = {
- TelephonyManager.CALL_WAITING_STATUS_ACTIVE,
- TelephonyManager.CALL_WAITING_STATUS_INACTIVE,
- TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED,
- TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CallWaitingStatus {
- }
-
- /**
* UICC SIM Application Types
*/
@IntDef(prefix = { "APPTYPE_" }, value = {
diff --git a/telephony/java/android/telephony/CallForwardingInfo.java b/telephony/java/android/telephony/CallForwardingInfo.java
index 1dd7539420ac..7e777fae46eb 100644
--- a/telephony/java/android/telephony/CallForwardingInfo.java
+++ b/telephony/java/android/telephony/CallForwardingInfo.java
@@ -15,24 +15,24 @@
*/
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.os.Parcel;
import android.os.Parcelable;
-import android.telephony.Annotation.CallForwardingReason;
-import android.telephony.Annotation.CallForwardingStatus;
import com.android.telephony.Rlog;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* Defines the call forwarding information.
* @hide
*/
-@SystemApi
public final class CallForwardingInfo implements Parcelable {
private static final String TAG = "CallForwardingInfo";
@@ -41,7 +41,6 @@ public final class CallForwardingInfo implements Parcelable {
*
* @hide
*/
- @SystemApi
public static final int STATUS_INACTIVE = 0;
/**
@@ -49,7 +48,6 @@ public final class CallForwardingInfo implements Parcelable {
*
* @hide
*/
- @SystemApi
public static final int STATUS_ACTIVE = 1;
/**
@@ -58,7 +56,6 @@ public final class CallForwardingInfo implements Parcelable {
*
* @hide
*/
- @SystemApi
public static final int STATUS_FDN_CHECK_FAILURE = 2;
/**
@@ -66,7 +63,6 @@ public final class CallForwardingInfo implements Parcelable {
*
* @hide
*/
- @SystemApi
public static final int STATUS_UNKNOWN_ERROR = 3;
/**
@@ -74,7 +70,6 @@ public final class CallForwardingInfo implements Parcelable {
*
* @hide
*/
- @SystemApi
public static final int STATUS_NOT_SUPPORTED = 4;
/**
@@ -83,7 +78,6 @@ public final class CallForwardingInfo implements Parcelable {
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_UNCONDITIONAL = 0;
/**
@@ -92,7 +86,6 @@ public final class CallForwardingInfo implements Parcelable {
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_BUSY = 1;
/**
@@ -101,7 +94,6 @@ public final class CallForwardingInfo implements Parcelable {
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_NO_REPLY = 2;
/**
@@ -110,7 +102,6 @@ public final class CallForwardingInfo implements Parcelable {
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_NOT_REACHABLE = 3;
/**
@@ -120,7 +111,6 @@ public final class CallForwardingInfo implements Parcelable {
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_ALL = 4;
/**
@@ -130,20 +120,48 @@ public final class CallForwardingInfo implements Parcelable {
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_ALL_CONDITIONAL = 5;
/**
+ * Call forwarding function status
+ */
+ @IntDef(prefix = { "STATUS_" }, value = {
+ STATUS_ACTIVE,
+ STATUS_INACTIVE,
+ STATUS_UNKNOWN_ERROR,
+ STATUS_NOT_SUPPORTED,
+ STATUS_FDN_CHECK_FAILURE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallForwardingStatus {
+ }
+
+ /**
+ * Call forwarding reason types
+ */
+ @IntDef(flag = true, prefix = { "REASON_" }, value = {
+ REASON_UNCONDITIONAL,
+ REASON_BUSY,
+ REASON_NO_REPLY,
+ REASON_NOT_REACHABLE,
+ REASON_ALL,
+ REASON_ALL_CONDITIONAL
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallForwardingReason {
+ }
+
+ /**
* The call forwarding status.
*/
- private @CallForwardingStatus int mStatus;
+ private int mStatus;
/**
* The call forwarding reason indicates the condition under which calls will be forwarded.
* Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
* and conditions +CCFC
*/
- private @CallForwardingReason int mReason;
+ private int mReason;
/**
* The phone number to which calls will be forwarded.
@@ -166,7 +184,6 @@ public final class CallForwardingInfo implements Parcelable {
* @param timeSeconds the timeout (in seconds) before the forwarding is attempted
* @hide
*/
- @SystemApi
public CallForwardingInfo(@CallForwardingStatus int status, @CallForwardingReason int reason,
@Nullable String number, int timeSeconds) {
mStatus = status;
@@ -182,7 +199,6 @@ public final class CallForwardingInfo implements Parcelable {
*
* @hide
*/
- @SystemApi
public @CallForwardingStatus int getStatus() {
return mStatus;
}
@@ -196,7 +212,6 @@ public final class CallForwardingInfo implements Parcelable {
*
* @hide
*/
- @SystemApi
public @CallForwardingReason int getReason() {
return mReason;
}
@@ -209,7 +224,6 @@ public final class CallForwardingInfo implements Parcelable {
*
* @hide
*/
- @SystemApi
@Nullable
public String getNumber() {
return mNumber;
@@ -227,7 +241,6 @@ public final class CallForwardingInfo implements Parcelable {
*
* @hide
*/
- @SystemApi
@SuppressLint("MethodNameUnits")
public int getTimeoutSeconds() {
return mTimeSeconds;
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index de35c00c8059..8cbeba14405b 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1553,6 +1553,7 @@ public class CarrierConfigManager {
/**
* The string is used to compare with operator name.
* If it matches the pattern then show specific data icon.
+ * @hide
*/
public static final String KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING =
"show_carrier_data_icon_pattern_string";
@@ -2967,9 +2968,9 @@ public class CarrierConfigManager {
* UE wants to display 5G_Plus icon for scenario#1, and 5G icon for scenario#2; otherwise not
* define.
* The configuration is: "connected_mmwave:5G_Plus,connected:5G"
+ * @hide
*/
- public static final String KEY_5G_ICON_CONFIGURATION_STRING =
- "5g_icon_configuration_string";
+ public static final String KEY_5G_ICON_CONFIGURATION_STRING = "5g_icon_configuration_string";
/**
* Timeout in seconds for displaying 5G icon, default value is 0 which means the timer is
@@ -2981,12 +2982,14 @@ public class CarrierConfigManager {
*
* If 5G is reacquired during this timer, the timer is canceled and restarted when 5G is next
* lost. Allows us to momentarily lose 5G without blinking the icon.
+ * @hide
*/
public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT =
"5g_icon_display_grace_period_sec_int";
/**
* Controls time in milliseconds until DcTracker reevaluates 5G connection state.
+ * @hide
*/
public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = "5g_watchdog_time_long";
@@ -3723,7 +3726,7 @@ public class CarrierConfigManager {
sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0);
sDefaults.putInt(KEY_CDMA_DTMF_TONE_DELAY_INT, 100);
sDefaults.putBoolean(KEY_CALL_FORWARDING_MAP_NON_NUMBER_TO_VOICEMAIL_BOOL, false);
- sDefaults.putBoolean(KEY_IGNORE_RTT_MODE_SETTING_BOOL, false);
+ sDefaults.putBoolean(KEY_IGNORE_RTT_MODE_SETTING_BOOL, true);
sDefaults.putInt(KEY_CDMA_3WAYCALL_FLASH_DELAY_INT , 0);
sDefaults.putBoolean(KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL, false);
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index d672c77bed01..b4ce162274fb 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -25,10 +25,9 @@ import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import android.util.ArraySet;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -56,7 +55,7 @@ public final class CellIdentityLte extends CellIdentity {
// cell bandwidth, in kHz
private final int mBandwidth;
// cell bands
- private final List<Integer> mBands;
+ private final int[] mBands;
// a list of additional PLMN-IDs reported for this cell
private final ArraySet<String> mAdditionalPlmns;
@@ -73,7 +72,7 @@ public final class CellIdentityLte extends CellIdentity {
mPci = CellInfo.UNAVAILABLE;
mTac = CellInfo.UNAVAILABLE;
mEarfcn = CellInfo.UNAVAILABLE;
- mBands = Collections.emptyList();
+ mBands = new int[] {};
mBandwidth = CellInfo.UNAVAILABLE;
mAdditionalPlmns = new ArraySet<>();
mCsgInfo = null;
@@ -91,7 +90,7 @@ public final class CellIdentityLte extends CellIdentity {
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public CellIdentityLte(int mcc, int mnc, int ci, int pci, int tac) {
- this(ci, pci, tac, CellInfo.UNAVAILABLE, Collections.emptyList(), CellInfo.UNAVAILABLE,
+ this(ci, pci, tac, CellInfo.UNAVAILABLE, new int[] {}, CellInfo.UNAVAILABLE,
String.valueOf(mcc), String.valueOf(mnc), null, null, new ArraySet<>(),
null);
}
@@ -112,16 +111,17 @@ public final class CellIdentityLte extends CellIdentity {
*
* @hide
*/
- public CellIdentityLte(int ci, int pci, int tac, int earfcn, List<Integer> bands, int bandwidth,
- @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal,
- @Nullable String alphas, @NonNull Collection<String> additionalPlmns,
+ public CellIdentityLte(int ci, int pci, int tac, int earfcn, @NonNull int[] bands,
+ int bandwidth, @Nullable String mccStr, @Nullable String mncStr,
+ @Nullable String alphal, @Nullable String alphas,
+ @NonNull Collection<String> additionalPlmns,
@Nullable ClosedSubscriberGroupInfo csgInfo) {
super(TAG, CellInfo.TYPE_LTE, mccStr, mncStr, alphal, alphas);
mCi = inRangeOrUnavailable(ci, 0, MAX_CI);
mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
mEarfcn = inRangeOrUnavailable(earfcn, 0, MAX_EARFCN);
- mBands = new ArrayList<>(bands);
+ mBands = bands;
mBandwidth = inRangeOrUnavailable(bandwidth, 0, MAX_BANDWIDTH);
mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
for (String plmn : additionalPlmns) {
@@ -134,13 +134,13 @@ public final class CellIdentityLte extends CellIdentity {
/** @hide */
public CellIdentityLte(@NonNull android.hardware.radio.V1_0.CellIdentityLte cid) {
- this(cid.ci, cid.pci, cid.tac, cid.earfcn, Collections.emptyList(),
+ this(cid.ci, cid.pci, cid.tac, cid.earfcn, new int[] {},
CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", new ArraySet<>(), null);
}
/** @hide */
public CellIdentityLte(@NonNull android.hardware.radio.V1_2.CellIdentityLte cid) {
- this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, Collections.emptyList(),
+ this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, new int[] {},
cid.bandwidth, cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
cid.operatorNames.alphaShort, new ArraySet<>(), null);
}
@@ -148,9 +148,10 @@ public final class CellIdentityLte extends CellIdentity {
/** @hide */
public CellIdentityLte(@NonNull android.hardware.radio.V1_5.CellIdentityLte cid) {
this(cid.base.base.ci, cid.base.base.pci, cid.base.base.tac, cid.base.base.earfcn,
- cid.bands, cid.base.bandwidth, cid.base.base.mcc, cid.base.base.mnc,
- cid.base.operatorNames.alphaLong, cid.base.operatorNames.alphaShort,
- cid.additionalPlmns, cid.optionalCsgInfo.csgInfo() != null
+ cid.bands.stream().mapToInt(Integer::intValue).toArray(), cid.base.bandwidth,
+ cid.base.base.mcc, cid.base.base.mnc, cid.base.operatorNames.alphaLong,
+ cid.base.operatorNames.alphaShort, cid.additionalPlmns,
+ cid.optionalCsgInfo.csgInfo() != null
? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null);
}
@@ -228,11 +229,11 @@ public final class CellIdentityLte extends CellIdentity {
*
* Reference: 3GPP TS 36.101 section 5.5
*
- * @return List of band number or empty list if not available.
+ * @return Array of band number or empty array if not available.
*/
@NonNull
- public List<Integer> getBands() {
- return Collections.unmodifiableList(mBands);
+ public int[] getBands() {
+ return Arrays.copyOf(mBands, mBands.length);
}
/**
@@ -314,8 +315,8 @@ public final class CellIdentityLte extends CellIdentity {
@Override
public int hashCode() {
- return Objects.hash(mCi, mPci, mTac,
- mAdditionalPlmns.hashCode(), mCsgInfo, super.hashCode());
+ return Objects.hash(mCi, mPci, mTac, mEarfcn, Arrays.hashCode(mBands),
+ mBandwidth, mAdditionalPlmns.hashCode(), mCsgInfo, super.hashCode());
}
@Override
@@ -333,6 +334,7 @@ public final class CellIdentityLte extends CellIdentity {
&& mPci == o.mPci
&& mTac == o.mTac
&& mEarfcn == o.mEarfcn
+ && Arrays.equals(mBands, o.mBands)
&& mBandwidth == o.mBandwidth
&& TextUtils.equals(mMccStr, o.mMccStr)
&& TextUtils.equals(mMncStr, o.mMncStr)
@@ -368,7 +370,7 @@ public final class CellIdentityLte extends CellIdentity {
dest.writeInt(mPci);
dest.writeInt(mTac);
dest.writeInt(mEarfcn);
- dest.writeList(mBands);
+ dest.writeIntArray(mBands);
dest.writeInt(mBandwidth);
dest.writeArraySet(mAdditionalPlmns);
dest.writeParcelable(mCsgInfo, flags);
@@ -381,7 +383,7 @@ public final class CellIdentityLte extends CellIdentity {
mPci = in.readInt();
mTac = in.readInt();
mEarfcn = in.readInt();
- mBands = in.readArrayList(null);
+ mBands = in.createIntArray();
mBandwidth = in.readInt();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
mCsgInfo = in.readParcelable(null);
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index cba500a00d3a..69cf7e7d4814 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -24,10 +24,9 @@ import android.telephony.AccessNetworkConstants.NgranBands.NgranBand;
import android.telephony.gsm.GsmCellLocation;
import android.util.ArraySet;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -46,7 +45,7 @@ public final class CellIdentityNr extends CellIdentity {
private final int mPci;
private final int mTac;
private final long mNci;
- private final List<Integer> mBands;
+ private final int[] mBands;
// a list of additional PLMN-IDs reported for this cell
private final ArraySet<String> mAdditionalPlmns;
@@ -66,7 +65,7 @@ public final class CellIdentityNr extends CellIdentity {
*
* @hide
*/
- public CellIdentityNr(int pci, int tac, int nrArfcn, @NgranBand List<Integer> bands,
+ public CellIdentityNr(int pci, int tac, int nrArfcn, @NonNull @NgranBand int[] bands,
@Nullable String mccStr, @Nullable String mncStr, long nci,
@Nullable String alphal, @Nullable String alphas,
@NonNull Collection<String> additionalPlmns) {
@@ -74,7 +73,8 @@ public final class CellIdentityNr extends CellIdentity {
mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
mNrArfcn = inRangeOrUnavailable(nrArfcn, 0, MAX_NRARFCN);
- mBands = new ArrayList<>(bands);
+ // TODO: input validation for bands
+ mBands = bands;
mNci = inRangeOrUnavailable(nci, 0, MAX_NCI);
mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
for (String plmn : additionalPlmns) {
@@ -86,15 +86,16 @@ public final class CellIdentityNr extends CellIdentity {
/** @hide */
public CellIdentityNr(@NonNull android.hardware.radio.V1_4.CellIdentityNr cid) {
- this(cid.pci, cid.tac, cid.nrarfcn, Collections.emptyList(), cid.mcc, cid.mnc, cid.nci,
+ this(cid.pci, cid.tac, cid.nrarfcn, new int[] {}, cid.mcc, cid.mnc, cid.nci,
cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
new ArraySet<>());
}
/** @hide */
public CellIdentityNr(@NonNull android.hardware.radio.V1_5.CellIdentityNr cid) {
- this(cid.base.pci, cid.base.tac, cid.base.nrarfcn, cid.bands, cid.base.mcc, cid.base.mnc,
- cid.base.nci, cid.base.operatorNames.alphaLong,
+ this(cid.base.pci, cid.base.tac, cid.base.nrarfcn,
+ cid.bands.stream().mapToInt(Integer::intValue).toArray(), cid.base.mcc,
+ cid.base.mnc, cid.base.nci, cid.base.operatorNames.alphaLong,
cid.base.operatorNames.alphaShort, cid.additionalPlmns);
}
@@ -119,18 +120,22 @@ public final class CellIdentityNr extends CellIdentity {
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), mPci, mTac,
- mNrArfcn, mBands.hashCode(), mNci, mAdditionalPlmns.hashCode());
+ mNrArfcn, Arrays.hashCode(mBands), mNci, mAdditionalPlmns.hashCode());
}
@Override
public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+
if (!(other instanceof CellIdentityNr)) {
return false;
}
CellIdentityNr o = (CellIdentityNr) other;
return super.equals(o) && mPci == o.mPci && mTac == o.mTac && mNrArfcn == o.mNrArfcn
- && mBands.equals(o.mBands) && mNci == o.mNci
+ && Arrays.equals(mBands, o.mBands) && mNci == o.mNci
&& mAdditionalPlmns.equals(o.mAdditionalPlmns);
}
@@ -163,12 +168,12 @@ public final class CellIdentityNr extends CellIdentity {
* Reference: TS 38.101-1 table 5.2-1
* Reference: TS 38.101-2 table 5.2-1
*
- * @return List of band number or empty list if not available.
+ * @return Array of band number or empty array if not available.
*/
@NgranBand
@NonNull
- public List<Integer> getBands() {
- return Collections.unmodifiableList(mBands);
+ public int[] getBands() {
+ return Arrays.copyOf(mBands, mBands.length);
}
/**
@@ -242,7 +247,7 @@ public final class CellIdentityNr extends CellIdentity {
dest.writeInt(mPci);
dest.writeInt(mTac);
dest.writeInt(mNrArfcn);
- dest.writeList(mBands);
+ dest.writeIntArray(mBands);
dest.writeLong(mNci);
dest.writeArraySet(mAdditionalPlmns);
}
@@ -253,7 +258,7 @@ public final class CellIdentityNr extends CellIdentity {
mPci = in.readInt();
mTac = in.readInt();
mNrArfcn = in.readInt();
- mBands = in.readArrayList(null);
+ mBands = in.createIntArray();
mNci = in.readLong();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index 1c92705b9422..d00049c1ebe5 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -314,6 +314,8 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements
/**
* Get the signal strength as dBm
+ *
+ * @return min(CDMA RSSI, EVDO RSSI) of the measured cell.
*/
@Override
public int getDbm() {
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index 76d2df918423..9d55f109f751 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -145,6 +145,8 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P
/**
* Get the signal strength as dBm.
+ *
+ * @return the RSSI of the measured cell.
*/
@Override
public int getDbm() {
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 270eafe642b7..c667165e7a0e 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -208,7 +208,6 @@ public final class DataSpecificRegistrationInfo implements Parcelable {
* @return {@code true} if using carrier aggregation.
* @hide
*/
- @SystemApi
public boolean isUsingCarrierAggregation() {
return mIsUsingCarrierAggregation;
}
diff --git a/telephony/java/android/telephony/ImsManager.java b/telephony/java/android/telephony/ImsManager.java
index 704e5aa78188..34bac5de4c43 100644
--- a/telephony/java/android/telephony/ImsManager.java
+++ b/telephony/java/android/telephony/ImsManager.java
@@ -34,8 +34,9 @@ public class ImsManager {
private Context mContext;
/**
- * <p>Broadcast Action: Indicates that an IMS operation was rejected by the network due to it
- * not being authorized on the network.
+ * <p>Broadcast Action: Indicates that a previously allowed IMS operation was rejected by the
+ * network due to the network returning a "forbidden" response. This may be due to a
+ * provisioning change from the network.
* May include the {@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX} extra to also specify
* which subscription the operation was rejected for.
* <p class="note">
@@ -74,17 +75,17 @@ public class ImsManager {
"android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR";
/**
- * An extra key corresponding to a String value which contains the carrier specific title to be
- * displayed as part of the message shown to the user when there is an error registering for
- * WiFi calling.
+ * An extra key corresponding to a {@link CharSequence} value which contains the carrier
+ * specific title to be displayed as part of the message shown to the user when there is an
+ * error registering for WiFi calling.
*/
public static final String EXTRA_WFC_REGISTRATION_FAILURE_TITLE =
"android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_TITLE";
/**
- * An extra key corresponding to a String value which contains the carrier specific message to
- * be displayed as part of the message shown to the user when there is an error registering for
- * WiFi calling.
+ * An extra key corresponding to a {@link CharSequence} value which contains the carrier
+ * specific message to be displayed as part of the message shown to the user when there is an
+ * error registering for WiFi calling.
*/
public static final String EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE =
"android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_MESSAGE";
@@ -103,10 +104,7 @@ public class ImsManager {
* @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
* @throws IllegalArgumentException if the subscription is invalid.
* @return a ImsRcsManager instance with the specific subscription ID.
- * @hide
*/
- @SystemApi
- @TestApi
@NonNull
public ImsRcsManager getImsRcsManager(int subscriptionId) {
if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 3e901e241e01..93fbb00ff9d5 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -367,6 +367,7 @@ public final class NetworkRegistrationInfo implements Parcelable {
* Get the 5G NR connection state.
*
* @return the 5G NR connection state.
+ * @hide
*/
public @NRState int getNrState() {
return mNrState;
@@ -689,7 +690,7 @@ public final class NetworkRegistrationInfo implements Parcelable {
*/
public void updateNrState() {
mNrState = NR_STATE_NONE;
- if (mDataSpecificInfo.isEnDcAvailable) {
+ if (mDataSpecificInfo != null && mDataSpecificInfo.isEnDcAvailable) {
if (!mDataSpecificInfo.isDcNrRestricted && mDataSpecificInfo.isNrAvailable) {
mNrState = NR_STATE_NOT_RESTRICTED;
} else {
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index 708adebb6db3..a9abe89abab0 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -95,7 +95,6 @@ public final class PreciseDataConnectionState implements Parcelable {
* if there is no valid APN setting for the specific type, then this will be null
* @hide
*/
- @SystemApi
public PreciseDataConnectionState(@DataState int state,
@NetworkType int networkType,
@ApnType int apnTypes, @NonNull String apn,
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index bc8473865466..90ddf2cd4730 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -260,24 +260,6 @@ public class RadioAccessFamily implements Parcelable {
return raf;
}
- /**
- * Returns the highest capability of the RadioAccessFamily (4G > 3G > 2G).
- * @param raf The RadioAccessFamily that we wish to filter
- * @return The highest radio capability
- */
- public static int getHighestRafCapability(int raf) {
- if ((LTE & raf) > 0) {
- return TelephonyManager.NETWORK_CLASS_4_G;
- }
- if ((EVDO|HS|WCDMA & raf) > 0) {
- return TelephonyManager.NETWORK_CLASS_3_G;
- }
- if((GSM|CDMA & raf) > 0) {
- return TelephonyManager.NETWORK_CLASS_2_G;
- }
- return TelephonyManager.NETWORK_CLASS_UNKNOWN;
- }
-
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@PrefNetworkMode
public static int getNetworkTypeFromRaf(int raf) {
@@ -395,4 +377,34 @@ public class RadioAccessFamily implements Parcelable {
}
return result;
}
+
+ /**
+ * Compare two sets of network types to see which is more capable.
+ *
+ * This algorithm first tries to see see if a set has a strict superset of RAT support for
+ * each generation, from newest to oldest; if that results in a tie, then it returns the set
+ * that supports the most RAT types.
+ */
+ public static int compare(long networkTypeBitmaskL, long networkTypeBitmaskR) {
+ final long[] prioritizedNetworkClassBitmasks = new long[] {
+ TelephonyManager.NETWORK_CLASS_BITMASK_5G,
+ TelephonyManager.NETWORK_CLASS_BITMASK_4G,
+ TelephonyManager.NETWORK_CLASS_BITMASK_3G,
+ TelephonyManager.NETWORK_CLASS_BITMASK_2G,
+ };
+
+ long lhsUnique = networkTypeBitmaskL & ~networkTypeBitmaskR;
+ long rhsUnique = networkTypeBitmaskR & ~networkTypeBitmaskL;
+
+ // See if one has a strict super-set of capabilities, generation by generation.
+ for (long classBitmask : prioritizedNetworkClassBitmasks) {
+ int result = 0;
+ if ((lhsUnique & classBitmask) != 0) ++result;
+ if ((rhsUnique & classBitmask) != 0) --result;
+ if (result != 0) return result;
+ }
+
+ // Without a clear winner, return the one that supports the most types.
+ return Long.bitCount(networkTypeBitmaskL) - Long.bitCount(networkTypeBitmaskR);
+ }
}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 5cf33dec25ea..82470d41842d 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1421,7 +1421,6 @@ public class ServiceState implements Parcelable {
* @return the frequency range of 5G NR.
* @hide
*/
- @SystemApi
public @FrequencyRange int getNrFrequencyRange() {
return mNrFrequencyRange;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index ffbcbb0d2633..c37262c6d2cc 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -70,14 +70,13 @@ import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.Annotation.ApnType;
-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;
import android.telephony.Annotation.UiccAppType;
+import android.telephony.CallForwardingInfo.CallForwardingReason;
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
import android.telephony.data.ApnSetting;
import android.telephony.data.ApnSetting.MvnoType;
@@ -3011,64 +3010,6 @@ public class TelephonyManager {
}
/**
- * Network Class Definitions.
- * Do not change this order, it is used for sorting during emergency calling in
- * {@link TelephonyConnectionService#getFirstPhoneForEmergencyCall()}. Any newer technologies
- * should be added after the current definitions.
- */
- /** Unknown network class. {@hide} */
- public static final int NETWORK_CLASS_UNKNOWN = 0;
- /** Class of broadly defined "2G" networks. {@hide} */
- @UnsupportedAppUsage
- public static final int NETWORK_CLASS_2_G = 1;
- /** Class of broadly defined "3G" networks. {@hide} */
- @UnsupportedAppUsage
- public static final int NETWORK_CLASS_3_G = 2;
- /** Class of broadly defined "4G" networks. {@hide} */
- @UnsupportedAppUsage
- public static final int NETWORK_CLASS_4_G = 3;
- /** Class of broadly defined "5G" networks. {@hide} */
- public static final int NETWORK_CLASS_5_G = 4;
-
- /**
- * Return general class of network type, such as "3G" or "4G". In cases
- * where classification is contentious, this method is conservative.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static int getNetworkClass(int networkType) {
- switch (networkType) {
- case NETWORK_TYPE_GPRS:
- case NETWORK_TYPE_GSM:
- case NETWORK_TYPE_EDGE:
- case NETWORK_TYPE_CDMA:
- case NETWORK_TYPE_1xRTT:
- case NETWORK_TYPE_IDEN:
- return NETWORK_CLASS_2_G;
- case NETWORK_TYPE_UMTS:
- case NETWORK_TYPE_EVDO_0:
- case NETWORK_TYPE_EVDO_A:
- case NETWORK_TYPE_HSDPA:
- case NETWORK_TYPE_HSUPA:
- case NETWORK_TYPE_HSPA:
- case NETWORK_TYPE_EVDO_B:
- case NETWORK_TYPE_EHRPD:
- case NETWORK_TYPE_HSPAP:
- case NETWORK_TYPE_TD_SCDMA:
- return NETWORK_CLASS_3_G;
- case NETWORK_TYPE_LTE:
- case NETWORK_TYPE_IWLAN:
- case NETWORK_TYPE_LTE_CA:
- return NETWORK_CLASS_4_G;
- case NETWORK_TYPE_NR:
- return NETWORK_CLASS_5_G;
- default:
- return NETWORK_CLASS_UNKNOWN;
- }
- }
-
- /**
* Returns a string representation of the radio technology (network type)
* currently in use on the device.
* @return the name of the radio technology
@@ -7933,21 +7874,19 @@ public class TelephonyManager {
* app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* @param operatorNumeric the PLMN ID of the network to select.
+ * @param persistSelection whether the selection will persist until reboot.
+ * If true, only allows attaching to the selected PLMN until reboot; otherwise,
+ * attach to the chosen PLMN and resume normal network selection next time.
* @param ran the initial suggested radio access network type.
* If registration fails, the RAN is not available after, the RAN is not within the
- * network types specified by {@link #setPreferredNetworkTypeBitmask}, or the value is
+ * network types specified by the preferred network types, or the value is
* {@link AccessNetworkConstants.AccessNetworkType#UNKNOWN}, modem will select
* the next best RAN for network registration.
- * @param persistSelection whether the selection will persist until reboot.
- * If true, only allows attaching to the selected PLMN until reboot; otherwise,
- * attach to the chosen PLMN and resume normal network selection next time.
* @return {@code true} on success; {@code false} on any failure.
- * @hide
*/
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- @SystemApi
public boolean setNetworkSelectionModeManual(@NonNull String operatorNumeric,
- @AccessNetworkConstants.RadioAccessNetworkType int ran, boolean persistSelection) {
+ boolean persistSelection, @AccessNetworkConstants.RadioAccessNetworkType int ran) {
return setNetworkSelectionModeManual(new OperatorInfo("" /* operatorAlphaLong */,
"" /* operatorAlphaShort */, operatorNumeric, ran), persistSelection);
}
@@ -9808,32 +9747,12 @@ public class TelephonyManager {
}
/**
- * Get baseband version for the default phone using the legacy approach.
- * This change was added in P, to ensure backward compatiblity.
- *
- * @return baseband version.
- * @hide
- */
- private String getBasebandVersionLegacy(int phoneId) {
- if (SubscriptionManager.isValidPhoneId(phoneId)) {
- String prop = "gsm.version.baseband"
- + ((phoneId == 0) ? "" : Integer.toString(phoneId));
- return SystemProperties.get(prop);
- }
- return null;
- }
-
- /**
* Get baseband version by phone id.
*
* @return baseband version.
* @hide
*/
public String getBasebandVersionForPhone(int phoneId) {
- String version = getBasebandVersionLegacy(phoneId);
- if (version != null && !version.isEmpty()) {
- setBasebandVersionForPhone(phoneId, version);
- }
return getTelephonyProperty(phoneId, TelephonyProperties.baseband_version(), "");
}
@@ -11495,6 +11414,55 @@ public class TelephonyManager {
@SystemApi
public static final long NETWORK_TYPE_BITMASK_IWLAN = (1 << (NETWORK_TYPE_IWLAN -1));
+ /** @hide */
+ public static final long NETWORK_CLASS_BITMASK_2G = NETWORK_TYPE_BITMASK_GSM
+ | NETWORK_TYPE_BITMASK_GPRS
+ | NETWORK_TYPE_BITMASK_EDGE
+ | NETWORK_TYPE_BITMASK_CDMA
+ | NETWORK_TYPE_BITMASK_1xRTT;
+
+ /** @hide */
+ public static final long NETWORK_CLASS_BITMASK_3G = NETWORK_TYPE_BITMASK_EVDO_0
+ | NETWORK_TYPE_BITMASK_EVDO_A
+ | NETWORK_TYPE_BITMASK_EVDO_B
+ | NETWORK_TYPE_BITMASK_EHRPD
+ | NETWORK_TYPE_BITMASK_HSUPA
+ | NETWORK_TYPE_BITMASK_HSDPA
+ | NETWORK_TYPE_BITMASK_HSPA
+ | NETWORK_TYPE_BITMASK_HSPAP
+ | NETWORK_TYPE_BITMASK_UMTS
+ | NETWORK_TYPE_BITMASK_TD_SCDMA;
+
+ /** @hide */
+ public static final long NETWORK_CLASS_BITMASK_4G = NETWORK_TYPE_BITMASK_LTE
+ | NETWORK_TYPE_BITMASK_LTE_CA
+ | NETWORK_TYPE_BITMASK_IWLAN;
+
+ /** @hide */
+ public static final long NETWORK_CLASS_BITMASK_5G = NETWORK_TYPE_BITMASK_NR;
+
+ /** @hide */
+ public static final long NETWORK_STANDARDS_FAMILY_BITMASK_3GPP = NETWORK_TYPE_BITMASK_GSM
+ | NETWORK_TYPE_BITMASK_GPRS
+ | NETWORK_TYPE_BITMASK_EDGE
+ | NETWORK_TYPE_BITMASK_HSUPA
+ | NETWORK_TYPE_BITMASK_HSDPA
+ | NETWORK_TYPE_BITMASK_HSPA
+ | NETWORK_TYPE_BITMASK_HSPAP
+ | NETWORK_TYPE_BITMASK_UMTS
+ | NETWORK_TYPE_BITMASK_TD_SCDMA
+ | NETWORK_TYPE_BITMASK_LTE
+ | NETWORK_TYPE_BITMASK_LTE_CA
+ | NETWORK_TYPE_BITMASK_NR;
+
+ /** @hide */
+ public static final long NETWORK_STANDARDS_FAMILY_BITMASK_3GPP2 = NETWORK_TYPE_BITMASK_CDMA
+ | NETWORK_TYPE_BITMASK_1xRTT
+ | NETWORK_TYPE_BITMASK_EVDO_0
+ | NETWORK_TYPE_BITMASK_EVDO_A
+ | NETWORK_TYPE_BITMASK_EVDO_B
+ | NETWORK_TYPE_BITMASK_EHRPD;
+
/**
* @return Modem supported radio access family bitmask
*
@@ -12189,6 +12157,17 @@ public class TelephonyManager {
"android.telephony.extra.NETWORK_COUNTRY";
/**
+ * The extra used with an {@link #ACTION_NETWORK_COUNTRY_CHANGED} to specify the
+ * last known the country code in ISO-3166-1 alpha-2 format.
+ * <p class="note">
+ * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
+ *
+ * @hide
+ */
+ public static final String EXTRA_LAST_KNOWN_NETWORK_COUNTRY =
+ "android.telephony.extra.LAST_KNOWN_NETWORK_COUNTRY";
+
+ /**
* Indicate if the user is allowed to use multiple SIM cards at the same time to register
* on the network (e.g. Dual Standby or Dual Active) when the device supports it, or if the
* usage is restricted. This API is used to prevent usage of multiple SIM card, based on
@@ -12625,7 +12604,6 @@ public class TelephonyManager {
*
* @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@NonNull
public CallForwardingInfo getCallForwarding(@CallForwardingReason int callForwardingReason) {
@@ -12672,7 +12650,6 @@ public class TelephonyManager {
*
* @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public boolean setCallForwarding(@NonNull CallForwardingInfo callForwardingInfo) {
if (callForwardingInfo == null) {
@@ -12713,7 +12690,6 @@ public class TelephonyManager {
*
* @hide
*/
- @SystemApi
public static final int CALL_WAITING_STATUS_ACTIVE = 1;
/**
@@ -12721,7 +12697,6 @@ public class TelephonyManager {
*
* @hide
*/
- @SystemApi
public static final int CALL_WAITING_STATUS_INACTIVE = 2;
/**
@@ -12729,7 +12704,6 @@ public class TelephonyManager {
*
* @hide
*/
- @SystemApi
public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3;
/**
@@ -12737,10 +12711,24 @@ public class TelephonyManager {
*
* @hide
*/
- @SystemApi
public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4;
/**
+ * Call waiting function status
+ *
+ * @hide
+ */
+ @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = {
+ CALL_WAITING_STATUS_ACTIVE,
+ CALL_WAITING_STATUS_INACTIVE,
+ CALL_WAITING_STATUS_NOT_SUPPORTED,
+ CALL_WAITING_STATUS_UNKNOWN_ERROR
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallWaitingStatus {
+ }
+
+ /**
* Gets the status of voice call waiting function. Call waiting function enables the waiting
* for the incoming call when it reaches the user who is busy to make another call and allows
* users to decide whether to switch to the incoming call.
@@ -12748,7 +12736,6 @@ public class TelephonyManager {
* @return the status of call waiting function.
* @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public @CallWaitingStatus int getCallWaitingStatus() {
try {
@@ -12774,7 +12761,6 @@ public class TelephonyManager {
*
* @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public boolean setCallWaitingStatus(boolean isEnable) {
try {
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 9e466aea9776..1e8fdceac1e6 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -18,7 +18,6 @@ package android.telephony.ims;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -721,11 +720,16 @@ public final class ImsCallProfile implements Parcelable {
* @return A {@link Bundle} containing proprietary call extras that were not set by the
* platform.
*/
- public @Nullable Bundle getProprietaryCallExtras() {
+ public @NonNull Bundle getProprietaryCallExtras() {
if (mCallExtras == null) {
- return null;
+ return new Bundle();
+ }
+ Bundle proprietaryExtras = mCallExtras.getBundle(EXTRA_OEM_EXTRAS);
+ if (proprietaryExtras == null) {
+ return new Bundle();
}
- return mCallExtras.getBundle(EXTRA_OEM_EXTRAS);
+ // Make a copy so users do not accidentally change this copy of the extras.
+ return new Bundle(proprietaryExtras);
}
public ImsStreamMediaProfile getMediaProfile() {
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index 025721c89f70..81af99fb40b7 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -58,7 +58,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionProgressing(profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -71,7 +71,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionInitiated(profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -85,7 +85,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionInitiatedFailed(reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -98,7 +98,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionTerminated(reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -115,7 +115,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionHeld(profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -128,7 +128,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionHoldFailed(reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -141,7 +141,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionHoldReceived(profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -155,7 +155,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionResumed(profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -169,7 +169,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionResumeFailed(reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -182,7 +182,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionResumeReceived(profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -201,7 +201,7 @@ public class ImsCallSessionListener {
mListener.callSessionMergeStarted(newSession != null ?
newSession.getServiceImpl() : null, profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -216,7 +216,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionMergeStarted(newSession, profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -232,7 +232,7 @@ public class ImsCallSessionListener {
mListener.callSessionMergeComplete(newSession != null ?
newSession.getServiceImpl() : null);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -247,7 +247,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionMergeComplete(newSession);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -260,7 +260,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionMergeFailed(reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -273,7 +273,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionUpdated(profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -286,7 +286,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionUpdateFailed(reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -299,7 +299,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionUpdateReceived(profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -319,7 +319,7 @@ public class ImsCallSessionListener {
mListener.callSessionConferenceExtended(
newSession != null ? newSession.getServiceImpl() : null, profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -333,7 +333,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionConferenceExtended(newSession, profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -347,7 +347,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionConferenceExtendFailed(reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -364,7 +364,7 @@ public class ImsCallSessionListener {
mListener.callSessionConferenceExtendReceived(newSession != null
? newSession.getServiceImpl() : null, profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -379,7 +379,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionConferenceExtendReceived(newSession, profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -391,7 +391,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionInviteParticipantsRequestDelivered();
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -407,7 +407,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionInviteParticipantsRequestFailed(reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -419,7 +419,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionRemoveParticipantsRequestDelivered();
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -435,7 +435,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionInviteParticipantsRequestFailed(reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -448,7 +448,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionConferenceStateUpdated(state);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -465,7 +465,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionUssdMessageReceived(mode, ussdMessage);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -501,7 +501,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionMayHandover(srcNetworkType, targetNetworkType);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -537,7 +537,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionHandover(srcNetworkType, targetNetworkType, reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -570,7 +570,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionHandoverFailed(srcNetworkType, targetNetworkType, reasonInfo);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -587,7 +587,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionTtyModeReceived(mode);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -600,7 +600,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionMultipartyStateChanged(isMultiParty);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -614,7 +614,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionSuppServiceReceived(suppSrvNotification);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -628,7 +628,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionRttModifyRequestReceived(callProfile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -641,7 +641,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionRttModifyResponseReceived(status);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -654,7 +654,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionRttMessageReceived(rttMessage);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -667,7 +667,7 @@ public class ImsCallSessionListener {
try {
mListener.callSessionRttAudioIndicatorChanged(profile);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
@@ -680,7 +680,7 @@ public class ImsCallSessionListener {
try {
mListener.callQualityChanged(callQuality);
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ e.rethrowFromSystemServer();
}
}
}
diff --git a/telephony/java/android/telephony/ims/ImsException.java b/telephony/java/android/telephony/ims/ImsException.java
index 643f452d2e75..1c3d58d98b4a 100644
--- a/telephony/java/android/telephony/ims/ImsException.java
+++ b/telephony/java/android/telephony/ims/ImsException.java
@@ -47,11 +47,12 @@ public final class ImsException extends Exception {
public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1;
/**
- * This device or carrier configuration does not support IMS for this subscription.
+ * This device or carrier configuration does not support this feature for this subscription.
* <p>
- * This is a permanent configuration error and there should be no retry. Usually this is
- * because {@link PackageManager#FEATURE_TELEPHONY_IMS} is not available
- * or the device has no ImsService implementation to service this request.
+ * This is a permanent configuration error and there should be no retry until the subscription
+ * changes if this operation is denied due to a carrier configuration. If this is due to a
+ * device configuration, the feature {@link PackageManager#FEATURE_TELEPHONY_IMS} is not
+ * available or the device has no ImsService implementation to service this request.
*/
public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2;
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 494009f35dba..dc8d750f6be4 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -21,7 +21,6 @@ import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressAutoDoc;
import android.annotation.SuppressLint;
@@ -125,7 +124,7 @@ public class ImsMmTelManager implements RegistrationManager {
* @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
*/
@Override
- public void onUnregistered(@Nullable ImsReasonInfo info) {
+ public void onUnregistered(@NonNull ImsReasonInfo info) {
}
/**
@@ -137,7 +136,7 @@ public class ImsMmTelManager implements RegistrationManager {
@Override
public void onTechnologyChangeFailed(
@AccessNetworkConstants.TransportType int imsTransportType,
- @Nullable ImsReasonInfo info) {
+ @NonNull ImsReasonInfo info) {
}
}
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index a2ad21c03f98..ed9b94b3d85e 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -20,14 +20,16 @@ import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
+import android.annotation.SdkConstant;
import android.content.Context;
+import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.provider.Settings;
import android.telephony.AccessNetworkConstants;
+import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsRcsController;
@@ -46,14 +48,34 @@ import java.util.function.Consumer;
* (UCE) service, as well as managing user settings.
*
* Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager.
- * @hide
*/
-@SystemApi
-@TestApi
public class ImsRcsManager implements RegistrationManager {
private static final String TAG = "ImsRcsManager";
/**
+ * Activity Action: Show the opt-in dialog for enabling or disabling RCS contact discovery
+ * using User Capability Exchange (UCE).
+ * <p>
+ * An application that depends on contact discovery being enabled may send this intent
+ * using {@link Context#startActivity(Intent)} to ask the user to opt-in for contacts upload for
+ * capability exchange if it is currently disabled. Whether or not this setting has been enabled
+ * can be queried using {@link RcsUceAdapter#isUceSettingEnabled()}.
+ * <p>
+ * This intent should only be sent if the carrier supports RCS capability exchange, which can be
+ * queried using the key {@link CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL}. Otherwise, the
+ * setting will not be present.
+ * <p>
+ * Input: A mandatory {@link Settings#EXTRA_SUB_ID} extra containing the subscription that the
+ * setting will be be shown for.
+ * <p>
+ * Output: Nothing
+ * @see RcsUceAdapter
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN =
+ "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
+
+ /**
* Receives RCS availability status updates from the ImsService.
*
* @see #isAvailable(int)
@@ -145,11 +167,10 @@ public class ImsRcsManager implements RegistrationManager {
*/
@NonNull
public RcsUceAdapter getUceAdapter() {
- return new RcsUceAdapter(mSubId);
+ return new RcsUceAdapter(mContext, mSubId);
}
/**
- * {@inheritDoc}
* @hide
*/
@Override
@@ -181,7 +202,6 @@ public class ImsRcsManager implements RegistrationManager {
}
/**
- * {@inheritDoc
* @hide
*/
@Override
@@ -206,7 +226,6 @@ public class ImsRcsManager implements RegistrationManager {
}
/**
- * {@inheritDoc}
* @hide
*/
@Override
@@ -239,7 +258,6 @@ public class ImsRcsManager implements RegistrationManager {
}
/**
- * {@inheritDoc}
* @hide
*/
@Override
diff --git a/telephony/java/android/telephony/ims/ImsUtListener.java b/telephony/java/android/telephony/ims/ImsUtListener.java
index bc12404461c7..460a032ce7e0 100644
--- a/telephony/java/android/telephony/ims/ImsUtListener.java
+++ b/telephony/java/android/telephony/ims/ImsUtListener.java
@@ -49,7 +49,8 @@ public class ImsUtListener {
* {@link ImsSsInfo#CLIR_STATUS_TEMPORARILY_RESTRICTED}, and
* {@link ImsSsInfo#CLIR_STATUS_TEMPORARILY_ALLOWED}.
* @deprecated Use {@link #onLineIdentificationSupplementaryServiceResponse(int, ImsSsInfo)}
- * instead.
+ * instead, this key has been added for backwards compatibility with older proprietary
+ * implementations only and is being phased out.
*/
@Deprecated
public static final String BUNDLE_KEY_CLIR = "queryClir";
@@ -60,7 +61,8 @@ public class ImsUtListener {
* response. The value will be an instance of {@link ImsSsInfo}, which contains the response to
* the query.
* @deprecated Use {@link #onLineIdentificationSupplementaryServiceResponse(int, ImsSsInfo)}
- * instead.
+ * instead, this key has been added for backwards compatibility with older proprietary
+ * implementations only and is being phased out.
*/
@Deprecated
public static final String BUNDLE_KEY_SSINFO = "imsSsInfo";
@@ -123,7 +125,7 @@ public class ImsUtListener {
try {
mServiceInterface.lineIdentificationSupplementaryServiceResponse(id, configuration);
} catch (RemoteException e) {
- Log.w(LOG_TAG, "onLineIdentificationSupplementaryServicesResponse: remote exception");
+ e.rethrowFromSystemServer();
}
}
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 6125001850db..ad54cbf3daea 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -306,13 +306,13 @@ public class ProvisioningManager {
/**
* An integer key associated with the carrier configured expiration time in seconds for
- * RCS presence published offline availability in RCS presence.
+ * published offline availability in RCS presence provided, which is provided to the network.
* <p>
* Value is in Integer format.
* @see #setProvisioningIntValue(int, int)
* @see #getProvisioningIntValue(int)
*/
- public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16;
+ public static final int KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC = 16;
/**
* An integer key associated with whether or not capability discovery is provisioned for this
@@ -327,8 +327,10 @@ public class ProvisioningManager {
public static final int KEY_RCS_CAPABILITY_DISCOVERY_ENABLED = 17;
/**
- * An integer key associated with the period of time the capability information of each contact
- * is cached on the device.
+ * An integer key associated with the period of time in seconds the capability information of
+ * each contact is cached on the device.
+ * <p>
+ * Seconds are used because this is usually measured in the span of days.
* <p>
* Value is in Integer format.
* @see #setProvisioningIntValue(int, int)
@@ -338,7 +340,8 @@ public class ProvisioningManager {
/**
* An integer key associated with the period of time in seconds that the availability
- * information of a contact is cached on the device.
+ * information of a contact is cached on the device, which is based on the carrier provisioning
+ * configuration from the network.
* <p>
* Value is in Integer format.
* @see #setProvisioningIntValue(int, int)
@@ -348,7 +351,8 @@ public class ProvisioningManager {
/**
* An integer key associated with the carrier configured interval in seconds expected between
- * successive capability polling attempts.
+ * successive capability polling attempts, which is based on the carrier provisioning
+ * configuration from the network.
* <p>
* Value is in Integer format.
* @see #setProvisioningIntValue(int, int)
@@ -358,7 +362,7 @@ public class ProvisioningManager {
/**
* An integer key representing the minimum time allowed between two consecutive presence publish
- * messages from the device.
+ * messages from the device in milliseconds.
* <p>
* Value is in Integer format.
* @see #setProvisioningIntValue(int, int)
@@ -379,7 +383,7 @@ public class ProvisioningManager {
/**
* An integer associated with the expiration timer used during the SIP subscription of a
* Request Contained List (RCL), which is used to retrieve the RCS capabilities of the contact
- * book.
+ * book. This timer value is sent in seconds to the network.
* <p>
* Value is in Integer format.
* @see #setProvisioningIntValue(int, int)
@@ -471,7 +475,8 @@ public class ProvisioningManager {
public static final int KEY_SIP_KEEP_ALIVE_ENABLED = 32;
/**
- * Registration retry Base Time value in seconds.
+ * Registration retry Base Time value in seconds, which is based off of the carrier
+ * configuration.
* Value is in Integer format.
* @see #setProvisioningIntValue(int, int)
* @see #getProvisioningIntValue(int)
@@ -479,7 +484,8 @@ public class ProvisioningManager {
public static final int KEY_REGISTRATION_RETRY_BASE_TIME_SEC = 33;
/**
- * Registration retry Max Time value in seconds.
+ * Registration retry Max Time value in seconds, which is based off of the carrier
+ * configuration.
* Value is in Integer format.
* @see #setProvisioningIntValue(int, int)
* @see #getProvisioningIntValue(int)
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 32fd8638f761..70edb758bb70 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -43,10 +43,7 @@ import java.util.concurrent.Executor;
* Manages RCS User Capability Exchange for the subscription specified.
*
* @see ImsRcsManager#getUceAdapter() for information on creating an instance of this class.
- * @hide
*/
-@SystemApi
-@TestApi
public class RcsUceAdapter {
private static final String TAG = "RcsUceAdapter";
@@ -216,6 +213,7 @@ public class RcsUceAdapter {
}
}
+ private final Context mContext;
private final int mSubId;
/**
@@ -223,7 +221,8 @@ public class RcsUceAdapter {
* {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
* @hide
*/
- RcsUceAdapter(int subId) {
+ RcsUceAdapter(Context context, int subId) {
+ mContext = context;
mSubId = subId;
}
@@ -291,7 +290,8 @@ public class RcsUceAdapter {
};
try {
- imsRcsController.requestCapabilities(mSubId, contactNumbers, internalCallback);
+ imsRcsController.requestCapabilities(mSubId, mContext.getOpPackageName(),
+ null /*featureId*/, contactNumbers, internalCallback);
} catch (RemoteException e) {
Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e);
throw new ImsException("Remote IMS Service is not available",
@@ -341,7 +341,7 @@ public class RcsUceAdapter {
* available. This can happen if the ImsService has crashed, for example, or if the subscription
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
*/
- @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
public boolean isUceSettingEnabled() throws ImsException {
IImsRcsController imsRcsController = getIImsRcsController();
if (imsRcsController == null) {
@@ -349,9 +349,10 @@ public class RcsUceAdapter {
throw new ImsException("Can not find remote IMS service",
ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
-
try {
- return imsRcsController.isUceSettingEnabled(mSubId);
+ // Telephony.SimInfo#IMS_RCS_UCE_ENABLED can also be used to listen to changes to this.
+ return imsRcsController.isUceSettingEnabled(mSubId, mContext.getOpPackageName(),
+ null /*featureId*/);
} catch (RemoteException e) {
Log.e(TAG, "Error calling IImsRcsController#isUceSettingEnabled", e);
throw new ImsException("Remote IMS Service is not available",
@@ -362,6 +363,10 @@ public class RcsUceAdapter {
/**
* Change the user’s setting for whether or not UCE is enabled for the associated subscription.
* <p>
+ * If an application Requires UCE, they may launch an Activity using the Intent
+ * {@link ImsRcsManager#ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN}, which will ask the user if
+ * they wish to enable this feature.
+ * <p>
* Note: This setting does not affect whether or not the device publishes its service
* capabilities if the subscription supports presence publication.
*
@@ -371,7 +376,10 @@ public class RcsUceAdapter {
* {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
* available. This can happen if the ImsService has crashed, for example, or if the subscription
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
+ * @hide
*/
+ @SystemApi
+ @TestApi
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setUceSettingEnabled(boolean isEnabled) throws ImsException {
IImsRcsController imsRcsController = getIImsRcsController();
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index 5c86ba732701..1dbaff5df802 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -196,11 +196,11 @@ public interface RegistrationManager {
}
/**
- * Notifies the framework when the IMS Provider is deregistered from the IMS network.
+ * Notifies the framework when the IMS Provider is unregistered from the IMS network.
*
* @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
*/
- public void onUnregistered(@Nullable ImsReasonInfo info) {
+ public void onUnregistered(@NonNull ImsReasonInfo info) {
}
/**
@@ -211,7 +211,7 @@ public interface RegistrationManager {
*/
public void onTechnologyChangeFailed(
@AccessNetworkConstants.TransportType int imsTransportType,
- @Nullable ImsReasonInfo info) {
+ @NonNull ImsReasonInfo info) {
}
/**
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
index 6f6aa44371fa..483c66eedc0c 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -42,8 +42,9 @@ interface IImsRcsController {
boolean isAvailable(int subId, int capability);
// ImsUceAdapter specific
- void requestCapabilities(int subId, in List<Uri> contactNumbers, IRcsUceControllerCallback c);
+ void requestCapabilities(int subId, String callingPackage, String callingFeatureId,
+ in List<Uri> contactNumbers, IRcsUceControllerCallback c);
int getUcePublishState(int subId);
- boolean isUceSettingEnabled(int subId);
+ boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId);
void setUceSettingEnabled(int subId, boolean isEnabled);
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 14a64d2585ed..7069e0ab9b1e 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -175,9 +175,11 @@ public class ImsRegistrationImplBase {
*/
public final void onDeregistered(ImsReasonInfo info) {
updateToDisconnectedState(info);
+ // ImsReasonInfo should never be null.
+ final ImsReasonInfo reasonInfo = (info != null) ? info : new ImsReasonInfo();
mCallbacks.broadcastAction((c) -> {
try {
- c.onDeregistered(info);
+ c.onDeregistered(reasonInfo);
} catch (RemoteException e) {
Log.w(LOG_TAG, e + " " + "onRegistrationDisconnected() - Skipping " +
"callback.");
@@ -194,9 +196,10 @@ public class ImsRegistrationImplBase {
*/
public final void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech,
ImsReasonInfo info) {
+ final ImsReasonInfo reasonInfo = (info != null) ? info : new ImsReasonInfo();
mCallbacks.broadcastAction((c) -> {
try {
- c.onTechnologyChangeFailed(imsRadioTech, info);
+ c.onTechnologyChangeFailed(imsRadioTech, reasonInfo);
} catch (RemoteException e) {
Log.w(LOG_TAG, e + " " + "onRegistrationChangeFailed() - Skipping " +
"callback.");
diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java
index 96f77d809183..d0cec52dfc86 100644
--- a/telephony/java/com/android/ims/ImsConfig.java
+++ b/telephony/java/com/android/ims/ImsConfig.java
@@ -270,11 +270,12 @@ public class ImsConfig {
/**
* Requested expiration for Published Offline availability.
* Value is in Integer format.
- * @deprecated use {@link ProvisioningManager#KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC}.
+ * @deprecated use
+ * {@link ProvisioningManager#KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC}.
*/
@Deprecated
public static final int PUBLISH_TIMER_EXTENDED =
- ProvisioningManager.KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC;
+ ProvisioningManager.KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC;
/**
*
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index 2b5720a47eb6..8de27e8eb281 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -445,14 +445,20 @@ public class LinkPropertiesTest {
// Check comparisons work.
LinkProperties lp2 = new LinkProperties(lp);
assertAllRoutesHaveInterface("wlan0", lp2);
- assertEquals(0, lp.compareAllRoutes(lp2).added.size());
- assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
+ // LinkProperties#compareAllRoutes exists both in R and before R, but the return type
+ // changed in R, so a test compiled with the R version of LinkProperties cannot run on Q.
+ if (isAtLeastR()) {
+ assertEquals(0, lp.compareAllRoutes(lp2).added.size());
+ assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
+ }
lp2.setInterfaceName("p2p0");
assertAllRoutesHaveInterface("p2p0", lp2);
assertAllRoutesNotHaveInterface("wlan0", lp2);
- assertEquals(3, lp.compareAllRoutes(lp2).added.size());
- assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
+ if (isAtLeastR()) {
+ assertEquals(3, lp.compareAllRoutes(lp2).added.size());
+ assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
+ }
// Remove route with incorrect interface, no route removed.
lp.removeRoute(new RouteInfo(prefix2, null, null));
@@ -480,6 +486,8 @@ public class LinkPropertiesTest {
assertEquals(1, rmnet0.getLinkAddresses().size());
assertEquals(1, rmnet0.getAllAddresses().size());
assertEquals(1, rmnet0.getAllLinkAddresses().size());
+ assertEquals(1, rmnet0.getAllInterfaceNames().size());
+ assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
rmnet0.addStackedLink(clat4);
assertEquals(1, rmnet0.getStackedLinks().size());
@@ -487,6 +495,9 @@ public class LinkPropertiesTest {
assertEquals(1, rmnet0.getLinkAddresses().size());
assertEquals(2, rmnet0.getAllAddresses().size());
assertEquals(2, rmnet0.getAllLinkAddresses().size());
+ assertEquals(2, rmnet0.getAllInterfaceNames().size());
+ assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
+ assertEquals("clat4", rmnet0.getAllInterfaceNames().get(1));
rmnet0.addStackedLink(clat4);
assertEquals(1, rmnet0.getStackedLinks().size());
@@ -494,6 +505,9 @@ public class LinkPropertiesTest {
assertEquals(1, rmnet0.getLinkAddresses().size());
assertEquals(2, rmnet0.getAllAddresses().size());
assertEquals(2, rmnet0.getAllLinkAddresses().size());
+ assertEquals(2, rmnet0.getAllInterfaceNames().size());
+ assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
+ assertEquals("clat4", rmnet0.getAllInterfaceNames().get(1));
assertEquals(0, clat4.getStackedLinks().size());
@@ -513,6 +527,8 @@ public class LinkPropertiesTest {
assertEquals(1, rmnet0.getLinkAddresses().size());
assertEquals(1, rmnet0.getAllAddresses().size());
assertEquals(1, rmnet0.getAllLinkAddresses().size());
+ assertEquals(1, rmnet0.getAllInterfaceNames().size());
+ assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
assertFalse(rmnet0.removeStackedLink("clat4"));
}
@@ -936,7 +952,7 @@ public class LinkPropertiesTest {
}
- @Test
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
public void testCompareResult() {
// Either adding or removing items
compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1),
@@ -1197,4 +1213,48 @@ public class LinkPropertiesTest {
lp.clear();
assertNull(lp.getCaptivePortalData());
}
+
+ private LinkProperties makeIpv4LinkProperties() {
+ final LinkProperties linkProperties = new LinkProperties();
+ linkProperties.setInterfaceName(NAME);
+ linkProperties.addLinkAddress(LINKADDRV4);
+ linkProperties.addDnsServer(DNS1);
+ linkProperties.addRoute(new RouteInfo(GATEWAY1));
+ linkProperties.addRoute(new RouteInfo(GATEWAY2));
+ return linkProperties;
+ }
+
+ private LinkProperties makeIpv6LinkProperties() {
+ final LinkProperties linkProperties = new LinkProperties();
+ linkProperties.setInterfaceName(NAME);
+ linkProperties.addLinkAddress(LINKADDRV6);
+ linkProperties.addDnsServer(DNS6);
+ linkProperties.addRoute(new RouteInfo(GATEWAY61));
+ linkProperties.addRoute(new RouteInfo(GATEWAY62));
+ return linkProperties;
+ }
+
+ @Test
+ public void testHasIpv4DefaultRoute() {
+ final LinkProperties Ipv4 = makeIpv4LinkProperties();
+ assertTrue(Ipv4.hasIpv4DefaultRoute());
+ final LinkProperties Ipv6 = makeIpv6LinkProperties();
+ assertFalse(Ipv6.hasIpv4DefaultRoute());
+ }
+
+ @Test
+ public void testHasIpv4DnsServer() {
+ final LinkProperties Ipv4 = makeIpv4LinkProperties();
+ assertTrue(Ipv4.hasIpv4DnsServer());
+ final LinkProperties Ipv6 = makeIpv6LinkProperties();
+ assertFalse(Ipv6.hasIpv4DnsServer());
+ }
+
+ @Test
+ public void testHasIpv6DnsServer() {
+ final LinkProperties Ipv4 = makeIpv4LinkProperties();
+ assertFalse(Ipv4.hasIpv6DnsServer());
+ final LinkProperties Ipv6 = makeIpv6LinkProperties();
+ assertTrue(Ipv6.hasIpv6DnsServer());
+ }
}
diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
new file mode 100644
index 000000000000..ef15b668e24c
--- /dev/null
+++ b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+package android.net
+
+import android.net.wifi.aware.DiscoverySession
+import android.net.wifi.aware.PeerHandle
+import android.net.wifi.aware.WifiAwareNetworkSpecifier
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+
+import com.android.testutils.assertParcelSane
+
+import java.lang.IllegalStateException
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class MatchAllNetworkSpecifierTest {
+ @Test
+ fun testParcel() {
+ assertParcelSane(MatchAllNetworkSpecifier(), 0)
+ }
+
+ @Test(expected = IllegalStateException::class)
+ fun testSatisfiedBy() {
+ val specifier = MatchAllNetworkSpecifier()
+ val discoverySession = Mockito.mock(DiscoverySession::class.java)
+ val peerHandle = Mockito.mock(PeerHandle::class.java)
+ val wifiAwareNetworkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession,
+ peerHandle).build()
+ specifier.satisfiedBy(wifiAwareNetworkSpecifier)
+ }
+}
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 9fe1883010b7..916c33981171 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -463,7 +463,9 @@ public class NetworkCapabilitiesTest {
nc1.setSSID(TEST_SSID);
nc2.combineCapabilities(nc1);
- assertTrue(TEST_SSID.equals(nc2.getSSID()));
+ if (isAtLeastR()) {
+ assertTrue(TEST_SSID.equals(nc2.getSsid()));
+ }
// Because they now have the same SSID, the following call should not throw
nc2.combineCapabilities(nc1);
@@ -601,12 +603,16 @@ public class NetworkCapabilitiesTest {
// from nc2.
assertFalse(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING));
- assertTrue(TEST_SSID.equals(nc2.getSSID()));
+ if (isAtLeastR()) {
+ assertTrue(TEST_SSID.equals(nc2.getSsid()));
+ }
nc1.setSSID(DIFFERENT_TEST_SSID);
nc2.set(nc1);
assertEquals(nc1, nc2);
- assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSSID()));
+ if (isAtLeastR()) {
+ assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSsid()));
+ }
nc1.setUids(uidRange(10, 13));
nc2.set(nc1); // Overwrites, as opposed to combineCapabilities
diff --git a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
index f4f804aff08d..84805442e5c7 100644
--- a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
@@ -21,17 +21,31 @@ import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
+
@RunWith(AndroidJUnit4.class)
@SmallTest
public class ApfCapabilitiesTest {
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getContext();
+ }
+
@Test
public void testConstructAndParcel() {
final ApfCapabilities caps = new ApfCapabilities(123, 456, 789);
@@ -59,4 +73,27 @@ public class ApfCapabilitiesTest {
caps = new ApfCapabilities(4 /* apfVersionSupported */, 5, 6);
assertTrue(caps.hasDataAccess());
}
+
+ @Test
+ public void testGetApfDrop8023Frames() {
+ // Get com.android.internal.R.bool.config_apfDrop802_3Frames. The test cannot directly
+ // use R.bool.config_apfDrop802_3Frames because that is not a stable resource ID.
+ final int resId = mContext.getResources().getIdentifier("config_apfDrop802_3Frames",
+ "bool", "android");
+ final boolean shouldDrop8023Frames = mContext.getResources().getBoolean(resId);
+ final boolean actual = ApfCapabilities.getApfDrop8023Frames();
+ assertEquals(shouldDrop8023Frames, actual);
+ }
+
+ @Test
+ public void testGetApfEtherTypeBlackList() {
+ // Get com.android.internal.R.array.config_apfEthTypeBlackList. The test cannot directly
+ // use R.array.config_apfEthTypeBlackList because that is not a stable resource ID.
+ final int resId = mContext.getResources().getIdentifier("config_apfEthTypeBlackList",
+ "array", "android");
+ final int[] blacklistedEtherTypeArray = mContext.getResources().getIntArray(resId);
+ final int[] actual = ApfCapabilities.getApfEtherTypeBlackList();
+ assertNotNull(actual);
+ assertTrue(Arrays.equals(blacklistedEtherTypeArray, actual));
+ }
}
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
index 23caf4952991..eec3cdbe8d7f 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
@@ -24,7 +24,6 @@ import android.net.Network
import android.net.metrics.IpConnectivityLog
import android.net.util.SharedLog
import android.os.IBinder
-import com.android.networkstack.metrics.DataStallStatsUtils
import com.android.networkstack.netlink.TcpSocketTracker
import com.android.server.NetworkStackService
import com.android.server.NetworkStackService.NetworkMonitorConnector
@@ -91,7 +90,6 @@ class TestNetworkStackService : Service() {
mock(IpConnectivityLog::class.java), mock(SharedLog::class.java),
mock(NetworkStackService.NetworkStackServiceManager::class.java),
NetworkMonitorDeps(privateDnsBypassNetwork),
- mock(DataStallStatsUtils::class.java),
mock(TcpSocketTracker::class.java))
cb.onNetworkMonitorCreated(NetworkMonitorConnector(nm, TestPermissionChecker()))
}
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index e632aafde70e..cea8c5713a6b 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -66,10 +66,10 @@ public final class TcpKeepalivePacketDataTest {
fail("InvalidPacketException: " + e);
}
- assertEquals(InetAddress.getByAddress(testInfo.srcAddress), resultData.srcAddress);
- assertEquals(InetAddress.getByAddress(testInfo.dstAddress), resultData.dstAddress);
- assertEquals(testInfo.srcPort, resultData.srcPort);
- assertEquals(testInfo.dstPort, resultData.dstPort);
+ assertEquals(InetAddress.getByAddress(testInfo.srcAddress), resultData.getSrcAddress());
+ assertEquals(InetAddress.getByAddress(testInfo.dstAddress), resultData.getDstAddress());
+ assertEquals(testInfo.srcPort, resultData.getSrcPort());
+ assertEquals(testInfo.dstPort, resultData.getDstPort());
assertEquals(testInfo.seq, resultData.tcpSeq);
assertEquals(testInfo.ack, resultData.tcpAck);
assertEquals(testInfo.rcvWnd, resultData.tcpWnd);
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 71b72b84de81..23098ec067d2 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -46,6 +46,7 @@ import android.net.LinkAddress;
import android.net.Network;
import android.net.NetworkUtils;
import android.os.Binder;
+import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor;
import android.system.Os;
import android.test.mock.MockContext;
@@ -135,6 +136,7 @@ public class IpSecServiceParameterizedTest {
};
INetd mMockNetd;
+ INetworkManagementService mNetworkManager;
PackageManager mMockPkgMgr;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
@@ -160,9 +162,10 @@ public class IpSecServiceParameterizedTest {
@Before
public void setUp() throws Exception {
mMockNetd = mock(INetd.class);
+ mNetworkManager = mock(INetworkManagementService.class);
mMockPkgMgr = mock(PackageManager.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
- mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
+ mIpSecService = new IpSecService(mMockContext, mNetworkManager, mMockIpSecSrvConfig);
// Injecting mock netd
when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -609,6 +612,7 @@ public class IpSecServiceParameterizedTest {
anyInt(),
anyInt(),
anyInt());
+ verify(mNetworkManager).setInterfaceUp(createTunnelResp.interfaceName);
}
@Test
diff --git a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
index 22a2c94fc194..788e4efe097e 100644
--- a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
+import android.os.INetworkManagementService;
import android.os.RemoteException;
import androidx.test.filters.SmallTest;
@@ -61,7 +62,8 @@ public class IpSecServiceRefcountedResourceTest {
public void setUp() throws Exception {
mMockContext = mock(Context.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
- mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
+ mIpSecService = new IpSecService(
+ mMockContext, mock(INetworkManagementService.class), mMockIpSecSrvConfig);
}
private void assertResourceState(
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 4a35015044ff..536e98327e1f 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -42,6 +42,7 @@ import android.net.IpSecManager;
import android.net.IpSecSpiResponse;
import android.net.IpSecUdpEncapResponse;
import android.os.Binder;
+import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.system.ErrnoException;
@@ -115,6 +116,7 @@ public class IpSecServiceTest {
}
Context mMockContext;
+ INetworkManagementService mMockNetworkManager;
INetd mMockNetd;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
@@ -122,9 +124,10 @@ public class IpSecServiceTest {
@Before
public void setUp() throws Exception {
mMockContext = mock(Context.class);
+ mMockNetworkManager = mock(INetworkManagementService.class);
mMockNetd = mock(INetd.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
- mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
+ mIpSecService = new IpSecService(mMockContext, mMockNetworkManager, mMockIpSecSrvConfig);
// Injecting mock netd
when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -132,7 +135,7 @@ public class IpSecServiceTest {
@Test
public void testIpSecServiceCreate() throws InterruptedException {
- IpSecService ipSecSrv = IpSecService.create(mMockContext);
+ IpSecService ipSecSrv = IpSecService.create(mMockContext, mMockNetworkManager);
assertNotNull(ipSecSrv);
}
@@ -604,8 +607,8 @@ public class IpSecServiceTest {
@Test
public void testOpenUdpEncapSocketTagsSocket() throws Exception {
IpSecService.UidFdTagger mockTagger = mock(IpSecService.UidFdTagger.class);
- IpSecService testIpSecService =
- new IpSecService(mMockContext, mMockIpSecSrvConfig, mockTagger);
+ IpSecService testIpSecService = new IpSecService(
+ mMockContext, mMockNetworkManager, mMockIpSecSrvConfig, mockTagger);
IpSecUdpEncapResponse udpEncapResp =
testIpSecService.openUdpEncapsulationSocket(0, new Binder());