diff options
436 files changed, 15490 insertions, 6544 deletions
diff --git a/Android.bp b/Android.bp index 75274eb84f63..c9ae9bad7deb 100644 --- a/Android.bp +++ b/Android.bp @@ -294,6 +294,17 @@ filegroup { ] } +java_library { + name: "framework-updatable-stubs-module_libs_api", + static_libs: [ + "framework-sdkextensions-stubs-module_libs_api", + "framework-tethering-stubs-module_libs_api", + "updatable_media_stubs", + ], + sdk_version: "module_current", + visibility: [":__pkg__"], +} + filegroup { name: "framework-all-sources", srcs: [ @@ -324,9 +335,11 @@ java_defaults { "rs/java", "sax/java", "telecomm/java", - "telephony/java", "wifi/java", "wifi/aidl-export", + + // TODO(b/147699819): remove this + "telephony/java", ], }, } @@ -396,7 +409,6 @@ java_defaults { "app-compat-annotations", "ext", "unsupportedappusage", - "updatable_media_stubs", ], jarjar_rules: ":framework-jarjar-rules", @@ -455,9 +467,6 @@ java_library { name: "framework-minus-apex", defaults: ["framework-defaults"], srcs: [":framework-non-updatable-sources"], - libs: [ - "framework-tethering-stubs", - ], installable: true, javac_shard_size: 150, required: [ @@ -465,6 +474,7 @@ java_library { "libcore-platform-compat-config", "services-platform-compat-config", ], + libs: ["framework-updatable-stubs-module_libs_api"], static_libs: [ // If MimeMap ever becomes its own APEX, then this dependency would need to be removed // in favor of an API stubs dependency in java_library "framework" below. @@ -494,9 +504,7 @@ java_library { installable: false, // this lib is a build-only library static_libs: [ "framework-minus-apex", - "updatable_media_stubs", - "framework-sdkextensions-stubs-systemapi", - "framework-tethering-stubs", + "framework-updatable-stubs-module_libs_api", ], sdk_version: "core_platform", apex_available: ["//apex_available:platform"], @@ -511,48 +519,14 @@ java_library { visibility: [ // DO NOT ADD ANY MORE ENTRIES TO THIS LIST "//external/robolectric-shadows:__subpackages__", - "//frameworks/base/packages/Tethering/common/TetheringLib:__subpackages__", + "//frameworks/base", "//frameworks/layoutlib:__subpackages__", - "//frameworks/opt/net/ike:__subpackages__", - ], -} - -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 @@ -614,6 +588,7 @@ gensrcs { filegroup { name: "framework-annotations", srcs: [ + "core/java/android/annotation/Hide.java", "core/java/android/annotation/NonNull.java", "core/java/android/annotation/Nullable.java", "core/java/android/annotation/IntDef.java", @@ -638,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", @@ -667,6 +643,18 @@ filegroup { ], } +filegroup { + name: "framework-services-net-module-wifi-shared-srcs", + srcs: [ + "core/java/android/net/DhcpResults.java", + "core/java/android/net/shared/Inet4AddressUtils.java", + "core/java/android/net/shared/InetAddressUtils.java", + "core/java/android/net/util/IpUtils.java", + "core/java/android/util/LocalLog.java", + "core/java/com/android/internal/util/Preconditions.java", + ], +} + // keep these files in sync with the package/Tethering/jarjar-rules.txt for the tethering module. filegroup { name: "framework-tethering-shared-srcs", @@ -1001,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 84b36255df51..f0810713f39f 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -41,14 +41,15 @@ packages_to_document = [ ] stubs_defaults { - name: "metalava-non-updatable-api-stubs-default", + name: "metalava-base-api-stubs-default", srcs: [ ":framework-non-updatable-sources", "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, @@ -57,21 +58,24 @@ stubs_defaults { merge_annotations_dirs: [ "metalava-manual", ], - api_levels_annotations_enabled: true, - api_levels_annotations_dirs: [ - "sdk-dir", - "api-versions-jars-dir", - ], + api_levels_annotations_enabled: false, filter_packages: packages_to_document, } stubs_defaults { - name: "metalava-api-stubs-default", - defaults: ["metalava-non-updatable-api-stubs-default"], + name: "metalava-full-api-stubs-default", + defaults: ["metalava-base-api-stubs-default"], srcs: [":framework-updatable-sources"], sdk_version: "core_platform", } +stubs_defaults { + name: "metalava-non-updatable-api-stubs-default", + defaults: ["metalava-base-api-stubs-default"], + sdk_version: "core_platform", + libs: ["framework-all"], +} + ///////////////////////////////////////////////////////////////////// // *-api-stubs-docs modules providing source files for the stub libraries ///////////////////////////////////////////////////////////////////// @@ -81,7 +85,7 @@ stubs_defaults { // modules droidstubs { name: "api-stubs-docs", - defaults: ["metalava-api-stubs-default"], + defaults: ["metalava-full-api-stubs-default"], api_filename: "public_api.txt", private_api_filename: "private.txt", removed_api_filename: "removed.txt", @@ -120,11 +124,10 @@ module_libs = " " + droidstubs { name: "system-api-stubs-docs", - defaults: ["metalava-api-stubs-default"], + defaults: ["metalava-full-api-stubs-default"], api_tag_name: "SYSTEM", api_filename: "system-api.txt", private_api_filename: "system-private.txt", - private_dex_api_filename: "system-private-dex.txt", removed_api_filename: "system-removed.txt", arg_files: [ "core/res/AndroidManifest.xml", @@ -151,7 +154,7 @@ droidstubs { droidstubs { name: "test-api-stubs-docs", - defaults: ["metalava-api-stubs-default"], + defaults: ["metalava-full-api-stubs-default"], api_tag_name: "TEST", api_filename: "test-api.txt", removed_api_filename: "test-removed.txt", @@ -184,7 +187,8 @@ droidstubs { droidstubs { name: "module-lib-api", - defaults: ["metalava-api-stubs-default"], + 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: { @@ -212,7 +216,7 @@ droidstubs { droidstubs { name: "module-lib-api-stubs-docs", - defaults: ["metalava-api-stubs-default"], + defaults: ["metalava-non-updatable-api-stubs-default"], arg_files: ["core/res/AndroidManifest.xml"], args: metalava_framework_docs_args + priv_apps + module_libs, } @@ -225,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, @@ -262,6 +268,7 @@ java_library_static { name: "android_module_lib_stubs_current", srcs: [ ":module-lib-api-stubs-docs" ], defaults: ["framework-stubs-default"], + libs: ["android_system_stubs_current"], } ///////////////////////////////////////////////////////////////////// @@ -313,12 +320,10 @@ java_library_static { droidstubs { name: "hiddenapi-lists-docs", - defaults: ["metalava-api-stubs-default"], + defaults: ["metalava-full-api-stubs-default"], arg_files: [ "core/res/AndroidManifest.xml", ], - dex_api_filename: "public-dex.txt", - private_dex_api_filename: "private-dex.txt", removed_dex_api_filename: "removed-dex.txt", args: metalava_framework_docs_args + " --show-unannotated " + @@ -328,7 +333,7 @@ droidstubs { droidstubs { name: "hiddenapi-mappings", - defaults: ["metalava-api-stubs-default"], + defaults: ["metalava-full-api-stubs-default"], srcs: [ ":opt-telephony-common-srcs", ], diff --git a/apex/Android.bp b/apex/Android.bp index 051986e758d3..a6461f39d553 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -43,13 +43,45 @@ stubs_defaults { name: "framework-module-stubs-defaults-publicapi", args: mainline_stubs_args, installable: false, + sdk_version: "current", + check_api: { + current: { + api_file: "api/current.txt", + removed_api_file: "api/removed.txt", + }, + }, } stubs_defaults { name: "framework-module-stubs-defaults-systemapi", args: mainline_stubs_args + priv_apps, - srcs: [":framework-annotations"], + libs: ["framework-annotations-lib"], installable: false, + sdk_version: "system_current", + check_api: { + current: { + api_file: "api/system-current.txt", + removed_api_file: "api/system-removed.txt", + }, + }, +} + +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 @@ -60,13 +92,21 @@ stubs_defaults { stubs_defaults { name: "framework-module-api-defaults-module_libs_api", args: mainline_stubs_args + module_libs, - srcs: [":framework-annotations"], + libs: ["framework-annotations-lib"], installable: false, + sdk_version: "module_current", + check_api: { + current: { + api_file: "api/module-lib-current.txt", + removed_api_file: "api/module-lib-removed.txt", + }, + }, } stubs_defaults { name: "framework-module-stubs-defaults-module_libs_api", args: mainline_stubs_args + module_libs + priv_apps, - srcs: [":framework-annotations"], + libs: ["framework-annotations-lib"], installable: false, + sdk_version: "module_current", } 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/apex/sdkextensions/framework/api/current.txt b/apex/sdkextensions/framework/api/current.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/apex/sdkextensions/framework/api/current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/apex/sdkextensions/framework/api/module-lib-current.txt b/apex/sdkextensions/framework/api/module-lib-current.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/apex/sdkextensions/framework/api/module-lib-current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/apex/sdkextensions/framework/api/module-lib-removed.txt b/apex/sdkextensions/framework/api/module-lib-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/apex/sdkextensions/framework/api/module-lib-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/apex/sdkextensions/framework/api/removed.txt b/apex/sdkextensions/framework/api/removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/apex/sdkextensions/framework/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/apex/sdkextensions/framework/api/system-current.txt b/apex/sdkextensions/framework/api/system-current.txt new file mode 100644 index 000000000000..bbff4c5ae6f4 --- /dev/null +++ b/apex/sdkextensions/framework/api/system-current.txt @@ -0,0 +1,9 @@ +// Signature format: 2.0 +package android.os.ext { + + public class SdkExtensions { + method public static int getExtensionVersion(int); + } + +} + diff --git a/apex/sdkextensions/framework/api/system-removed.txt b/apex/sdkextensions/framework/api/system-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/apex/sdkextensions/framework/api/system-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/api/current.txt b/api/current.txt index 0f37db2b586f..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(); @@ -19555,8 +19558,7 @@ package android.icu.number { method public T numberFormatterSecond(android.icu.number.UnlocalizedNumberFormatter); } - public abstract class Precision implements java.lang.Cloneable { - method public Object clone(); + public abstract class Precision { method public static android.icu.number.CurrencyPrecision currency(android.icu.util.Currency.CurrencyUsage); method public static android.icu.number.FractionPrecision fixedFraction(int); method public static android.icu.number.Precision fixedSignificantDigits(int); @@ -19579,8 +19581,7 @@ package android.icu.number { method public static android.icu.number.Scale powerOfTen(int); } - public class ScientificNotation extends android.icu.number.Notation implements java.lang.Cloneable { - method public Object clone(); + public class ScientificNotation extends android.icu.number.Notation { method public android.icu.number.ScientificNotation withExponentSignDisplay(android.icu.number.NumberFormatter.SignDisplay); method public android.icu.number.ScientificNotation withMinExponentDigits(int); } @@ -28708,7 +28709,7 @@ package android.net { public abstract static class ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback { ctor public ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback(); - method public void onConnectivityReport(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityReport); + method public void onConnectivityReportAvailable(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityReport); method public void onDataStallSuspected(@NonNull android.net.ConnectivityDiagnosticsManager.DataStallReport); method public void onNetworkConnectivityReported(@NonNull android.net.Network, boolean); } @@ -29145,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(); @@ -29157,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 @@ -44682,6 +44673,38 @@ package android.telephony { field public static final int PRIORITY_MED = 2; // 0x2 } + public final class BarringInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.telephony.BarringInfo.BarringServiceInfo getBarringServiceInfo(int); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int BARRING_SERVICE_TYPE_CS_FALLBACK = 5; // 0x5 + field public static final int BARRING_SERVICE_TYPE_CS_SERVICE = 0; // 0x0 + field public static final int BARRING_SERVICE_TYPE_CS_VOICE = 2; // 0x2 + field public static final int BARRING_SERVICE_TYPE_EMERGENCY = 8; // 0x8 + field public static final int BARRING_SERVICE_TYPE_MMTEL_VIDEO = 7; // 0x7 + field public static final int BARRING_SERVICE_TYPE_MMTEL_VOICE = 6; // 0x6 + field public static final int BARRING_SERVICE_TYPE_MO_DATA = 4; // 0x4 + field public static final int BARRING_SERVICE_TYPE_MO_SIGNALLING = 3; // 0x3 + field public static final int BARRING_SERVICE_TYPE_PS_SERVICE = 1; // 0x1 + field public static final int BARRING_SERVICE_TYPE_SMS = 9; // 0x9 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.BarringInfo> CREATOR; + } + + public static final class BarringInfo.BarringServiceInfo implements android.os.Parcelable { + method public int describeContents(); + method public int getBarringType(); + method public int getConditionalBarringFactor(); + method public int getConditionalBarringTimeSeconds(); + method public boolean isBarred(); + method public boolean isConditionallyBarred(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int BARRING_TYPE_CONDITIONAL = 1; // 0x1 + field public static final int BARRING_TYPE_NONE = 0; // 0x0 + field public static final int BARRING_TYPE_UNCONDITIONAL = 2; // 0x2 + field public static final int BARRING_TYPE_UNKNOWN = -1; // 0xffffffff + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.BarringInfo.BarringServiceInfo> CREATOR; + } + public class CarrierConfigManager { method @Nullable public android.os.PersistableBundle getConfig(); method @Nullable public android.os.PersistableBundle getConfigByComponentForSubId(@NonNull String, int); @@ -44694,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"; @@ -44892,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"; @@ -44967,7 +44986,7 @@ package android.telephony { } public final class CellIdentityGsm extends android.telephony.CellIdentity { - method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns(); + method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns(); method public int getArfcn(); method public int getBsic(); method public int getCid(); @@ -44983,8 +45002,8 @@ package android.telephony { } public final class CellIdentityLte extends android.telephony.CellIdentity { - method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns(); - method @NonNull public java.util.List<java.lang.Integer> getBands(); + method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns(); + method @NonNull public int[] getBands(); method public int getBandwidth(); method public int getCi(); method @Nullable public android.telephony.ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo(); @@ -45001,8 +45020,8 @@ package android.telephony { } public final class CellIdentityNr extends android.telephony.CellIdentity { - method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns(); - method @NonNull public java.util.List<java.lang.Integer> getBands(); + method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns(); + method @NonNull public int[] getBands(); method @Nullable public String getMccString(); method @Nullable public String getMncString(); method public long getNci(); @@ -45014,7 +45033,7 @@ package android.telephony { } public final class CellIdentityTdscdma extends android.telephony.CellIdentity { - method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns(); + method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns(); method public int getCid(); method @Nullable public android.telephony.ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo(); method public int getCpid(); @@ -45028,7 +45047,7 @@ package android.telephony { } public final class CellIdentityWcdma extends android.telephony.CellIdentity { - method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns(); + method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns(); method public int getCid(); method @Nullable public android.telephony.ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo(); method public int getLac(); @@ -45317,7 +45336,7 @@ 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(); method public boolean isRoaming(); @@ -45444,6 +45463,7 @@ package android.telephony { ctor public PhoneStateListener(); ctor public PhoneStateListener(@NonNull java.util.concurrent.Executor); method public void onActiveDataSubscriptionIdChanged(int); + method public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo); method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onCallDisconnectCauseChanged(int, int); method public void onCallForwardingIndicatorChanged(boolean); method public void onCallStateChanged(int, String); @@ -45462,6 +45482,7 @@ package android.telephony { method public void onSignalStrengthsChanged(android.telephony.SignalStrength); method public void onUserMobileDataStateChanged(boolean); field public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000 + field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int LISTEN_BARRING_INFO = -2147483648; // 0x80000000 field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000 field public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8 field public static final int LISTEN_CALL_STATE = 32; // 0x20 @@ -45484,6 +45505,7 @@ package android.telephony { public final class PreciseDataConnectionState implements android.os.Parcelable { method public int describeContents(); + method @Nullable public android.telephony.data.ApnSetting getApnSetting(); method public int getLastCauseCode(); method @Nullable public android.net.LinkProperties getLinkProperties(); method public int getNetworkType(); @@ -45840,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); @@ -45860,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); } @@ -45900,6 +45922,7 @@ package android.telephony { method public String getMmsUserAgent(); method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNai(); method public String getNetworkCountryIso(); + method @NonNull public String getNetworkCountryIso(int); method public String getNetworkOperator(); method public String getNetworkOperatorName(); method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public int getNetworkSelectionMode(); @@ -45965,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>); @@ -46010,6 +46034,7 @@ package android.telephony { field public static final int DATA_DISCONNECTING = 4; // 0x4 field public static final int DATA_SUSPENDED = 3; // 0x3 field public static final int DATA_UNKNOWN = -1; // 0xffffffff + field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT"; field public static final String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT"; field public static final String EXTRA_CARRIER_ID = "android.telephony.extra.CARRIER_ID"; field public static final String EXTRA_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME"; @@ -46019,7 +46044,6 @@ package android.telephony { field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT"; field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY"; field public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT"; - field public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED = "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED"; field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE"; field public static final String EXTRA_SPECIFIC_CARRIER_ID = "android.telephony.extra.SPECIFIC_CARRIER_ID"; field public static final String EXTRA_SPECIFIC_CARRIER_NAME = "android.telephony.extra.SPECIFIC_CARRIER_NAME"; @@ -46062,7 +46086,6 @@ package android.telephony { field public static final int NETWORK_TYPE_UNKNOWN = 0; // 0x0 field public static final int PHONE_TYPE_CDMA = 2; // 0x2 field public static final int PHONE_TYPE_GSM = 1; // 0x1 - field public static final int PHONE_TYPE_IMS = 5; // 0x5 field public static final int PHONE_TYPE_NONE = 0; // 0x0 field public static final int PHONE_TYPE_SIP = 3; // 0x3 field public static final int SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION = 2; // 0x2 @@ -46354,10 +46377,42 @@ package android.telephony.euicc { field public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2; // 0x2 field public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; // 0x0 field public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1; // 0x1 + field public static final int ERROR_ADDRESS_MISSING = 10011; // 0x271b + field public static final int ERROR_CARRIER_LOCKED = 10000; // 0x2710 + field public static final int ERROR_CERTIFICATE_ERROR = 10012; // 0x271c + field public static final int ERROR_CONNECTION_ERROR = 10014; // 0x271e + field public static final int ERROR_DISALLOWED_BY_PPR = 10010; // 0x271a + field public static final int ERROR_EUICC_INSUFFICIENT_MEMORY = 10004; // 0x2714 + field public static final int ERROR_EUICC_MISSING = 10006; // 0x2716 + field public static final int ERROR_INCOMPATIBLE_CARRIER = 10003; // 0x2713 + field public static final int ERROR_INSTALL_PROFILE = 10009; // 0x2719 + field public static final int ERROR_INVALID_ACTIVATION_CODE = 10001; // 0x2711 + field public static final int ERROR_INVALID_CONFIRMATION_CODE = 10002; // 0x2712 + field public static final int ERROR_INVALID_RESPONSE = 10015; // 0x271f + field public static final int ERROR_NO_PROFILES_AVAILABLE = 10013; // 0x271d + field public static final int ERROR_OPERATION_BUSY = 10016; // 0x2720 + field public static final int ERROR_SIM_MISSING = 10008; // 0x2718 + field public static final int ERROR_TIME_OUT = 10005; // 0x2715 + field public static final int ERROR_UNSUPPORTED_VERSION = 10007; // 0x2717 field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE"; field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION"; + field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_ERROR_CODE"; + field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_OPERATION_CODE"; + field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE"; + field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE"; field public static final String EXTRA_USE_QR_SCANNER = "android.telephony.euicc.extra.USE_QR_SCANNER"; field public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon"; + field public static final int OPERATION_APDU = 8; // 0x8 + field public static final int OPERATION_DOWNLOAD = 5; // 0x5 + field public static final int OPERATION_EUICC_CARD = 3; // 0x3 + field public static final int OPERATION_EUICC_GSMA = 7; // 0x7 + field public static final int OPERATION_HTTP = 11; // 0xb + field public static final int OPERATION_METADATA = 6; // 0x6 + field public static final int OPERATION_SIM_SLOT = 2; // 0x2 + field public static final int OPERATION_SMDX = 9; // 0x9 + field public static final int OPERATION_SMDX_SUBJECT_REASON_CODE = 10; // 0xa + field public static final int OPERATION_SWITCH = 4; // 0x4 + field public static final int OPERATION_SYSTEM = 1; // 0x1 } } @@ -46461,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"; @@ -46489,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(); @@ -46672,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>); @@ -46686,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/module-lib-current.txt b/api/module-lib-current.txt index 1d646d476a77..355fa18ca249 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -29,7 +29,7 @@ package android.net { field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR; } - public class TetheringConstants { + public final class TetheringConstants { field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType"; field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback"; field public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType"; @@ -72,19 +72,20 @@ package android.net { field public static final int TETHERING_WIFI = 0; // 0x0 field public static final int TETHERING_WIFI_P2P = 3; // 0x3 field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc - field public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; // 0x9 - field public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; // 0x8 + field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9 + field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8 field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa - field public static final int TETHER_ERROR_MASTER_ERROR = 5; // 0x5 + field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5 field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0 - field public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb + field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2 field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6 field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4 field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1 + field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10 field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3 field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7 field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2 @@ -96,40 +97,42 @@ package android.net { method public void onTetheringEntitlementResult(int); } - public abstract static class TetheringManager.StartTetheringCallback { - ctor public TetheringManager.StartTetheringCallback(); - method public void onTetheringFailed(int); - method public void onTetheringStarted(); + public static interface TetheringManager.StartTetheringCallback { + method public default void onTetheringFailed(int); + method public default void onTetheringStarted(); } - public abstract static class TetheringManager.TetheringEventCallback { - ctor public TetheringManager.TetheringEventCallback(); - method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>); - method public void onError(@NonNull String, int); - method public void onOffloadStatusChanged(int); - method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps); - method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>); - method public void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>); - method public void onTetheringSupported(boolean); - method public void onUpstreamChanged(@Nullable android.net.Network); + public static interface TetheringManager.TetheringEventCallback { + method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>); + method public default void onError(@NonNull String, int); + method public default void onOffloadStatusChanged(int); + method public default void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps); + method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheringSupported(boolean); + method public default void onUpstreamChanged(@Nullable android.net.Network); } - @Deprecated public static class TetheringManager.TetheringInterfaceRegexps { - ctor @Deprecated public TetheringManager.TetheringInterfaceRegexps(@NonNull String[], @NonNull String[], @NonNull String[]); - method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs(); - method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs(); - method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs(); + public static class TetheringManager.TetheringInterfaceRegexps { + method @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs(); + method @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs(); + method @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs(); } public static class TetheringManager.TetheringRequest { + method @Nullable public android.net.LinkAddress getClientStaticIpv4Address(); + method @Nullable public android.net.LinkAddress getLocalIpv4Address(); + method public boolean getShouldShowEntitlementUi(); + method public int getTetheringType(); + method public boolean isExemptFromEntitlementCheck(); } public static class TetheringManager.TetheringRequest.Builder { ctor public TetheringManager.TetheringRequest.Builder(int); method @NonNull public android.net.TetheringManager.TetheringRequest build(); method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean); - method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean); - method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress); + method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean); + method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress); } } diff --git a/api/system-current.txt b/api/system-current.txt index 4191c55c3752..6ab5b1ed25e2 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -134,6 +134,7 @@ package android { field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD"; field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP"; field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK"; + field public static final String NETWORK_STATS_PROVIDER = "android.permission.NETWORK_STATS_PROVIDER"; field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP"; field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS"; field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE"; @@ -186,7 +187,7 @@ package android { field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES"; field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS"; field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS"; - field public static final String SECURE_ELEMENT_PRIVILEGED = "android.permission.SECURE_ELEMENT_PRIVILEGED"; + field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION"; field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY"; field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS"; field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION"; @@ -228,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 } @@ -278,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 { @@ -323,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 { @@ -998,8 +994,8 @@ package android.app.compat { public final class CompatChanges { method public static boolean isChangeEnabled(long); - method public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle); - method public static boolean isChangeEnabled(long, int); + method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle); + method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, int); } } @@ -1239,7 +1235,8 @@ package android.app.usage { } public class NetworkStatsManager { - method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.net.netstats.provider.NetworkStatsProviderCallback registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.AbstractNetworkStatsProvider); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider); } public static final class UsageEvents.Event { @@ -1290,16 +1287,8 @@ package android.app.usage { package android.bluetooth { public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void disableOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void enableOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice); - method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothDevice getActiveDevice(); - method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@Nullable android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int getOptionalCodecsEnabled(@Nullable android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setCodecConfigPreference(@Nullable android.bluetooth.BluetoothDevice, @Nullable android.bluetooth.BluetoothCodecConfig); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setOptionalCodecsEnabled(@Nullable android.bluetooth.BluetoothDevice, int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int supportsOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); field public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0; // 0x0 field public static final int OPTIONAL_CODECS_PREF_DISABLED = 0; // 0x0 field public static final int OPTIONAL_CODECS_PREF_ENABLED = 1; // 0x1 @@ -1310,28 +1299,23 @@ package android.bluetooth { public final class BluetoothA2dpSink implements android.bluetooth.BluetoothProfile { method public void finalize(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isAudioPlaying(@Nullable android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice, int); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isAudioPlaying(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED"; } public final class BluetoothAdapter { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice); method public boolean disableBLE(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice); method public boolean enableBLE(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public long getDiscoveryEndMillis(); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public long getDiscoveryEndMillis(); method public boolean isBleScanAlwaysAvailable(); method public boolean isLeEnabled(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeActiveDevice(int); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setActiveDevice(@NonNull android.bluetooth.BluetoothDevice, int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setScanMode(int, long); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setScanMode(int); field public static final String ACTION_BLE_STATE_CHANGED = "android.bluetooth.adapter.action.BLE_STATE_CHANGED"; field public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE = "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE"; field public static final int ACTIVE_DEVICE_ALL = 2; // 0x2 @@ -1343,70 +1327,17 @@ package android.bluetooth { method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]); } - public final class BluetoothCodecConfig implements android.os.Parcelable { - ctor public BluetoothCodecConfig(int, int, int, int, int, long, long, long, long); - ctor public BluetoothCodecConfig(int); - method public int getBitsPerSample(); - method @NonNull public String getCodecName(); - method public int getCodecPriority(); - method public long getCodecSpecific1(); - method public int getCodecType(); - method public int getSampleRate(); - method public boolean isMandatoryCodec(); - field public static final int BITS_PER_SAMPLE_16 = 1; // 0x1 - field public static final int BITS_PER_SAMPLE_24 = 2; // 0x2 - field public static final int BITS_PER_SAMPLE_32 = 4; // 0x4 - field public static final int BITS_PER_SAMPLE_NONE = 0; // 0x0 - field public static final int CHANNEL_MODE_MONO = 1; // 0x1 - field public static final int CHANNEL_MODE_NONE = 0; // 0x0 - field public static final int CHANNEL_MODE_STEREO = 2; // 0x2 - field public static final int CODEC_PRIORITY_DEFAULT = 0; // 0x0 - field public static final int CODEC_PRIORITY_DISABLED = -1; // 0xffffffff - field public static final int CODEC_PRIORITY_HIGHEST = 1000000; // 0xf4240 - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecConfig> CREATOR; - field public static final int SAMPLE_RATE_176400 = 16; // 0x10 - field public static final int SAMPLE_RATE_192000 = 32; // 0x20 - field public static final int SAMPLE_RATE_44100 = 1; // 0x1 - field public static final int SAMPLE_RATE_48000 = 2; // 0x2 - field public static final int SAMPLE_RATE_88200 = 4; // 0x4 - field public static final int SAMPLE_RATE_96000 = 8; // 0x8 - field public static final int SAMPLE_RATE_NONE = 0; // 0x0 - field public static final int SOURCE_CODEC_TYPE_AAC = 1; // 0x1 - field public static final int SOURCE_CODEC_TYPE_APTX = 2; // 0x2 - field public static final int SOURCE_CODEC_TYPE_APTX_HD = 3; // 0x3 - field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240 - field public static final int SOURCE_CODEC_TYPE_LDAC = 4; // 0x4 - field public static final int SOURCE_CODEC_TYPE_MAX = 5; // 0x5 - field public static final int SOURCE_CODEC_TYPE_SBC = 0; // 0x0 - } - - public final class BluetoothCodecStatus implements android.os.Parcelable { - ctor public BluetoothCodecStatus(@Nullable android.bluetooth.BluetoothCodecConfig, @Nullable android.bluetooth.BluetoothCodecConfig[], @Nullable android.bluetooth.BluetoothCodecConfig[]); - method @Nullable public android.bluetooth.BluetoothCodecConfig getCodecConfig(); - method @Nullable public android.bluetooth.BluetoothCodecConfig[] getCodecsLocalCapabilities(); - method @Nullable public android.bluetooth.BluetoothCodecConfig[] getCodecsSelectableCapabilities(); - field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecStatus> CREATOR; - field public static final String EXTRA_CODEC_STATUS = "android.bluetooth.extra.CODEC_STATUS"; - } - public final class BluetoothDevice implements android.os.Parcelable { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelBondProcess(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelPairing(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getBatteryLevel(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getMessageAccessPermission(); method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public byte[] getMetadata(int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getPhonebookAccessPermission(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getSimAccessPermission(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isBondingInitiatedLocally(); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getSimAccessPermission(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeBond(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setAlias(@NonNull String); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMessageAccessPermission(int); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, @NonNull byte[]); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPin(@NonNull String); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSilenceMode(boolean); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSimAccessPermission(int); field public static final int ACCESS_ALLOWED = 1; // 0x1 @@ -1436,17 +1367,15 @@ package android.bluetooth { public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean connect(android.bluetooth.BluetoothDevice); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnect(android.bluetooth.BluetoothDevice); - method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothDevice getActiveDevice(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPriority(android.bluetooth.BluetoothDevice, int); } public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile { - method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH) public java.util.List<android.bluetooth.BluetoothDevice> getActiveDevices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public long getHiSyncId(@Nullable android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public long getHiSyncId(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); } public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile { @@ -1455,9 +1384,9 @@ package android.bluetooth { public final class BluetoothHidHost implements android.bluetooth.BluetoothProfile { method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED"; } @@ -1465,14 +1394,14 @@ package android.bluetooth { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void close(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) protected void finalize(); method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice, int); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED"; } - public final class BluetoothPan implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile { + public final class BluetoothPan implements android.bluetooth.BluetoothProfile { method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isTetheringOn(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setBluetoothTethering(boolean); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); @@ -1486,7 +1415,7 @@ package android.bluetooth { } public class BluetoothPbap implements android.bluetooth.BluetoothProfile { - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int); field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED"; } @@ -1608,9 +1537,7 @@ 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 NETWORK_STACK_SERVICE = "network_stack"; field public static final String OEM_LOCK_SERVICE = "oem_lock"; field public static final String PERMISSION_SERVICE = "permission"; field public static final String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block"; @@ -1669,7 +1596,6 @@ package android.content { field public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP"; field public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED"; field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED"; - field @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED"; field public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST"; field public static final String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS"; field public static final String EXTRA_CALLING_PACKAGE = "android.intent.extra.CALLING_PACKAGE"; @@ -4422,7 +4348,7 @@ package android.net { method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported(); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public int registerNetworkProvider(@NonNull android.net.NetworkProvider); method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback); - method @Deprecated public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, int, int, @NonNull android.os.Handler); + method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi(); method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle); @@ -4473,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 { @@ -4530,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 { @@ -4556,6 +4482,7 @@ package android.net { public final class LinkProperties implements android.os.Parcelable { ctor public LinkProperties(@Nullable android.net.LinkProperties); + ctor public LinkProperties(@Nullable android.net.LinkProperties, boolean); method public boolean addDnsServer(@NonNull java.net.InetAddress); method public boolean addLinkAddress(@NonNull android.net.LinkAddress); method public boolean addPcscfServer(@NonNull java.net.InetAddress); @@ -4578,7 +4505,6 @@ package android.net { method public boolean isIpv6Provisioned(); method public boolean isProvisioned(); method public boolean isReachable(@NonNull java.net.InetAddress); - method @NonNull public android.net.LinkProperties makeSensitiveFieldsParcelingCopy(); method public boolean removeDnsServer(@NonNull java.net.InetAddress); method public boolean removeLinkAddress(@NonNull android.net.LinkAddress); method public boolean removeRoute(@NonNull android.net.RouteInfo); @@ -4608,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 { @@ -4617,7 +4543,6 @@ package android.net { method @Nullable public android.net.Network getNetwork(); method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData); method public void onAutomaticReconnectDisabled(); - method public void onBandwidthUpdateRequested(); method public void onNetworkUnwanted(); method public void onRemoveKeepalivePacketFilter(int); method public void onSaveAcceptUnvalidated(boolean); @@ -4631,23 +4556,17 @@ package android.net { method public void sendNetworkScore(int); method public void sendSocketKeepaliveEvent(int, int); method public void setConnected(); - method @Deprecated public void setLegacyExtraInfo(@Nullable String); - method @Deprecated public void setLegacySubtype(int, @NonNull String); method public void unregister(); field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2 field public static final int VALIDATION_STATUS_VALID = 1; // 0x1 - field public final int providerId; } public final class NetworkAgentConfig implements android.os.Parcelable { method public int describeContents(); method public int getLegacyType(); method @NonNull public String getLegacyTypeName(); - method @Nullable public String getSubscriberId(); method public boolean isExplicitlySelected(); - method public boolean isNat64DetectionEnabled(); method public boolean isPartialConnectivityAcceptable(); - method public boolean isProvisioningNotificationEnabled(); method public boolean isUnvalidatedConnectivityAcceptable(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR; @@ -4656,31 +4575,42 @@ package android.net { public static class NetworkAgentConfig.Builder { ctor public NetworkAgentConfig.Builder(); method @NonNull public android.net.NetworkAgentConfig build(); - method @NonNull public android.net.NetworkAgentConfig.Builder disableNat64Detection(); - method @NonNull public android.net.NetworkAgentConfig.Builder disableProvisioningNotification(); method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean); method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int); method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String); method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean); - method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String); method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean); } public final class NetworkCapabilities implements android.os.Parcelable { - method public boolean deduceRestrictedCapability(); - method @NonNull public java.util.List<java.lang.Integer> getAdministratorUids(); - method @Nullable public String getSSID(); + method @NonNull public int[] getAdministratorUids(); + 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 java.util.List<java.lang.Integer>); - 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); @@ -4692,27 +4622,9 @@ package android.net { field public final android.net.WifiKey wifiKey; } - public class NetworkPolicyManager { - method @NonNull public android.telephony.SubscriptionPlan[] getSubscriptionPlans(int, @NonNull String); - method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void registerSubscriptionCallback(@NonNull android.net.NetworkPolicyManager.SubscriptionCallback); - method public void setSubscriptionOverride(int, int, int, long, @NonNull String); - method public void setSubscriptionPlans(int, @NonNull android.telephony.SubscriptionPlan[], @NonNull String); - method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void unregisterSubscriptionCallback(@NonNull android.net.NetworkPolicyManager.SubscriptionCallback); - field public static final int SUBSCRIPTION_OVERRIDE_CONGESTED = 2; // 0x2 - field public static final int SUBSCRIPTION_OVERRIDE_UNMETERED = 1; // 0x1 - } - - public static class NetworkPolicyManager.SubscriptionCallback { - ctor public NetworkPolicyManager.SubscriptionCallback(); - method public void onSubscriptionOverride(int, int, int); - method public void onSubscriptionPlansChanged(int, @NonNull android.telephony.SubscriptionPlan[]); - } - public class NetworkProvider { ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String); method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest); - method @Nullable public android.os.Messenger getMessenger(); - method @NonNull public String getName(); method public int getProviderId(); method public void onNetworkRequested(@NonNull android.net.NetworkRequest, int, int); method public void onRequestWithdrawn(@NonNull android.net.NetworkRequest); @@ -4767,20 +4679,20 @@ package android.net { } public class NetworkStack { + method @Nullable public static android.os.IBinder getService(); field public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK"; } public final class NetworkStats implements android.os.Parcelable { ctor public NetworkStats(long, int); method @NonNull public android.net.NetworkStats add(@NonNull android.net.NetworkStats); - method @NonNull public android.net.NetworkStats addValues(@NonNull android.net.NetworkStats.Entry); + method @NonNull public android.net.NetworkStats addEntry(@NonNull android.net.NetworkStats.Entry); method public int describeContents(); method @NonNull public android.net.NetworkStats subtract(@NonNull android.net.NetworkStats); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStats> CREATOR; field public static final int DEFAULT_NETWORK_NO = 0; // 0x0 field public static final int DEFAULT_NETWORK_YES = 1; // 0x1 - field @Nullable public static final String IFACE_ALL; field public static final String IFACE_VT = "vt_data0"; field public static final int METERED_NO = 0; // 0x0 field public static final int METERED_YES = 1; // 0x1 @@ -4892,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); @@ -4909,19 +4820,20 @@ package android.net { field public static final int TETHERING_WIFI = 0; // 0x0 field public static final int TETHERING_WIFI_P2P = 3; // 0x3 field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc - field public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; // 0x9 - field public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; // 0x8 + field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9 + field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8 field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa - field public static final int TETHER_ERROR_MASTER_ERROR = 5; // 0x5 + field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5 field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0 - field public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb + field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2 field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6 field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4 field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1 + field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10 field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3 field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7 field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2 @@ -4933,40 +4845,35 @@ package android.net { method public void onTetheringEntitlementResult(int); } - public abstract static class TetheringManager.StartTetheringCallback { - ctor public TetheringManager.StartTetheringCallback(); - method public void onTetheringFailed(int); - method public void onTetheringStarted(); + public static interface TetheringManager.StartTetheringCallback { + method public default void onTetheringFailed(int); + method public default void onTetheringStarted(); } - public abstract static class TetheringManager.TetheringEventCallback { - ctor public TetheringManager.TetheringEventCallback(); - method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>); - method public void onError(@NonNull String, int); - method public void onOffloadStatusChanged(int); - method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps); - method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>); - method public void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>); - method public void onTetheringSupported(boolean); - method public void onUpstreamChanged(@Nullable android.net.Network); - } - - @Deprecated public static class TetheringManager.TetheringInterfaceRegexps { - ctor @Deprecated public TetheringManager.TetheringInterfaceRegexps(@NonNull String[], @NonNull String[], @NonNull String[]); - method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs(); - method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs(); - method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs(); + public static interface TetheringManager.TetheringEventCallback { + method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>); + method public default void onError(@NonNull String, int); + method public default void onOffloadStatusChanged(int); + method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheringSupported(boolean); + method public default void onUpstreamChanged(@Nullable android.net.Network); } public static class TetheringManager.TetheringRequest { + method @Nullable public android.net.LinkAddress getClientStaticIpv4Address(); + method @Nullable public android.net.LinkAddress getLocalIpv4Address(); + method public boolean getShouldShowEntitlementUi(); + method public int getTetheringType(); + method public boolean isExemptFromEntitlementCheck(); } public static class TetheringManager.TetheringRequest.Builder { ctor public TetheringManager.TetheringRequest.Builder(int); method @NonNull public android.net.TetheringManager.TetheringRequest build(); method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean); - method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean); - method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress); } public class TrafficStats { @@ -5180,21 +5087,17 @@ package android.net.metrics { package android.net.netstats.provider { - public abstract class AbstractNetworkStatsProvider { - ctor public AbstractNetworkStatsProvider(); - method public abstract void requestStatsUpdate(int); - method public abstract void setAlert(long); - method public abstract void setLimit(@NonNull String, long); + public abstract class NetworkStatsProvider { + ctor public NetworkStatsProvider(); + method public void notifyAlertReached(); + method public void notifyLimitReached(); + method public void notifyStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats); + method public abstract void onRequestStatsUpdate(int); + method public abstract void onSetAlert(long); + method public abstract void onSetLimit(@NonNull String, long); field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff } - public class NetworkStatsProviderCallback { - method public void onAlertReached(); - method public void onLimitReached(); - method public void onStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats); - method public void unregister(); - } - } package android.net.sip { @@ -5983,13 +5886,15 @@ package android.os { field public static final String ACTION_UPDATE_CARRIER_PROVISIONING_URLS = "android.intent.action.UPDATE_CARRIER_PROVISIONING_URLS"; field public static final String ACTION_UPDATE_CONVERSATION_ACTIONS = "android.intent.action.UPDATE_CONVERSATION_ACTIONS"; field public static final String ACTION_UPDATE_CT_LOGS = "android.intent.action.UPDATE_CT_LOGS"; - field public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB = "android.os.action.UPDATE_EMERGENCY_NUMBER_DB"; + field @RequiresPermission("android.permission.UPDATE_CONFIG") public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB = "android.os.action.UPDATE_EMERGENCY_NUMBER_DB"; field public static final String ACTION_UPDATE_INTENT_FIREWALL = "android.intent.action.UPDATE_INTENT_FIREWALL"; field public static final String ACTION_UPDATE_LANG_ID = "android.intent.action.UPDATE_LANG_ID"; field public static final String ACTION_UPDATE_NETWORK_WATCHLIST = "android.intent.action.UPDATE_NETWORK_WATCHLIST"; field public static final String ACTION_UPDATE_PINS = "android.intent.action.UPDATE_PINS"; field public static final String ACTION_UPDATE_SMART_SELECTION = "android.intent.action.UPDATE_SMART_SELECTION"; field public static final String ACTION_UPDATE_SMS_SHORT_CODES = "android.intent.action.UPDATE_SMS_SHORT_CODES"; + field public static final String EXTRA_REQUIRED_HASH = "android.os.extra.REQUIRED_HASH"; + field public static final String EXTRA_VERSION = "android.os.extra.VERSION"; } public class Environment { @@ -6645,18 +6550,6 @@ package android.printservice.recommendation { package android.provider { - public class BlockedNumberContract { - field public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact"; - field public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number"; - field public static final String RES_BLOCK_STATUS = "block_status"; - field public static final int STATUS_BLOCKED_IN_LIST = 1; // 0x1 - field public static final int STATUS_BLOCKED_NOT_IN_CONTACTS = 5; // 0x5 - field public static final int STATUS_BLOCKED_PAYPHONE = 4; // 0x4 - field public static final int STATUS_BLOCKED_RESTRICTED = 2; // 0x2 - field public static final int STATUS_BLOCKED_UNKNOWN_NUMBER = 3; // 0x3 - field public static final int STATUS_NOT_BLOCKED = 0; // 0x0 - } - public static final class ContactsContract.MetadataSync implements android.provider.BaseColumns android.provider.ContactsContract.MetadataSyncColumns { field public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_metadata"; field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact_metadata"; @@ -6938,32 +6831,6 @@ package android.provider { field public static final int VOLUME_HUSH_VIBRATE = 1; // 0x1 } - public static interface Telephony.CarrierColumns extends android.provider.BaseColumns { - field @NonNull public static final android.net.Uri CONTENT_URI; - field public static final String EXPIRATION_TIME = "expiration_time"; - field public static final String KEY_IDENTIFIER = "key_identifier"; - field public static final String KEY_TYPE = "key_type"; - field public static final String LAST_MODIFIED = "last_modified"; - field public static final String MCC = "mcc"; - field public static final String MNC = "mnc"; - field public static final String MVNO_MATCH_DATA = "mvno_match_data"; - field public static final String MVNO_TYPE = "mvno_type"; - field public static final String PUBLIC_KEY = "public_key"; - } - - public static final class Telephony.CarrierId.All implements android.provider.BaseColumns { - field public static final String APN = "apn"; - field @NonNull public static final android.net.Uri CONTENT_URI; - field public static final String GID1 = "gid1"; - field public static final String GID2 = "gid2"; - field public static final String ICCID_PREFIX = "iccid_prefix"; - field public static final String IMSI_PREFIX_XPATTERN = "imsi_prefix_xpattern"; - field public static final String MCCMNC = "mccmnc"; - field public static final String PLMN = "plmn"; - field public static final String PRIVILEGE_ACCESS_RULE = "privilege_access_rule"; - field public static final String SPN = "spn"; - } - public static final class Telephony.Carriers implements android.provider.BaseColumns { field public static final String APN_SET_ID = "apn_set_id"; field public static final int CARRIER_EDITED = 4; // 0x4 @@ -7034,76 +6901,6 @@ package android.provider { field @NonNull public static final String ENABLE_TEST_ALERT_PREF = "enable_test_alerts"; } - public static final class Telephony.SimInfo { - field public static final String ACCESS_RULES = "access_rules"; - field public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS = "access_rules_from_carrier_configs"; - field public static final String ALLOWED_NETWORK_TYPES = "allowed_network_types"; - field public static final String CARD_ID = "card_id"; - field public static final String CARRIER_ID = "carrier_id"; - field public static final String CARRIER_NAME = "carrier_name"; - field public static final String CB_ALERT_REMINDER_INTERVAL = "alert_reminder_interval"; - field public static final String CB_ALERT_SOUND_DURATION = "alert_sound_duration"; - field public static final String CB_ALERT_SPEECH = "enable_alert_speech"; - field public static final String CB_ALERT_VIBRATE = "enable_alert_vibrate"; - field public static final String CB_AMBER_ALERT = "enable_cmas_amber_alerts"; - field public static final String CB_CHANNEL_50_ALERT = "enable_channel_50_alerts"; - field public static final String CB_CMAS_TEST_ALERT = "enable_cmas_test_alerts"; - field public static final String CB_EMERGENCY_ALERT = "enable_emergency_alerts"; - field public static final String CB_ETWS_TEST_ALERT = "enable_etws_test_alerts"; - field public static final String CB_EXTREME_THREAT_ALERT = "enable_cmas_extreme_threat_alerts"; - field public static final String CB_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog"; - field public static final String CB_SEVERE_THREAT_ALERT = "enable_cmas_severe_threat_alerts"; - field public static final String COLOR = "color"; - field @NonNull public static final android.net.Uri CONTENT_URI; - field public static final String DATA_ENABLED_OVERRIDE_RULES = "data_enabled_override_rules"; - field public static final String DATA_ROAMING = "data_roaming"; - field public static final int DATA_ROAMING_DEFAULT = 0; // 0x0 - field public static final int DATA_ROAMING_DISABLE = 0; // 0x0 - field public static final int DATA_ROAMING_ENABLE = 1; // 0x1 - field public static final String DISPLAY_NAME = "display_name"; - field public static final String EHPLMNS = "ehplmns"; - field public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled"; - field public static final String GROUP_OWNER = "group_owner"; - field public static final String GROUP_UUID = "group_uuid"; - field public static final String HPLMNS = "hplmns"; - field public static final String ICC_ID = "icc_id"; - field public static final String IMSI = "imsi"; - field public static final String IMS_RCS_UCE_ENABLED = "ims_rcs_uce_enabled"; - field public static final String ISO_COUNTRY_CODE = "iso_country_code"; - field public static final String IS_EMBEDDED = "is_embedded"; - field public static final String IS_OPPORTUNISTIC = "is_opportunistic"; - field public static final String IS_REMOVABLE = "is_removable"; - field public static final String MCC = "mcc"; - field public static final String MCC_STRING = "mcc_string"; - field public static final String MNC = "mnc"; - field public static final String MNC_STRING = "mnc_string"; - field public static final String NAME_SOURCE = "name_source"; - field public static final int NAME_SOURCE_CARRIER = 3; // 0x3 - field public static final int NAME_SOURCE_DEFAULT = 0; // 0x0 - field public static final int NAME_SOURCE_SIM_PNN = 4; // 0x4 - field public static final int NAME_SOURCE_SIM_SPN = 1; // 0x1 - field public static final int NAME_SOURCE_USER_INPUT = 2; // 0x2 - field public static final String NUMBER = "number"; - field public static final String PROFILE_CLASS = "profile_class"; - field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff - field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2 - field public static final int PROFILE_CLASS_PROVISIONING = 1; // 0x1 - field public static final int PROFILE_CLASS_TESTING = 0; // 0x0 - field public static final int PROFILE_CLASS_UNSET = -1; // 0xffffffff - field public static final int SIM_NOT_INSERTED = -1; // 0xffffffff - field public static final String SIM_SLOT_INDEX = "sim_id"; - field public static final String SUBSCRIPTION_TYPE = "subscription_type"; - field public static final int SUBSCRIPTION_TYPE_LOCAL_SIM = 0; // 0x0 - field public static final int SUBSCRIPTION_TYPE_REMOTE_SIM = 1; // 0x1 - field public static final String UICC_APPLICATIONS_ENABLED = "uicc_applications_enabled"; - field public static final String UNIQUE_KEY_SUBSCRIPTION_ID = "_id"; - field public static final String VT_IMS_ENABLED = "vt_ims_enabled"; - field public static final String WFC_IMS_ENABLED = "wfc_ims_enabled"; - field public static final String WFC_IMS_MODE = "wfc_ims_mode"; - field public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled"; - field public static final String WFC_IMS_ROAMING_MODE = "wfc_ims_roaming_mode"; - } - public static final class Telephony.Sms.Intents { field public static final String ACTION_SMS_EMERGENCY_CB_RECEIVED = "android.provider.action.SMS_EMERGENCY_CB_RECEIVED"; } @@ -7129,7 +6926,7 @@ package android.provider { package android.se.omapi { public final class Reader { - method @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED) public boolean reset(); + method @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION) public boolean reset(); } } @@ -7509,6 +7306,7 @@ package android.service.euicc { public abstract class EuiccService extends android.app.Service { ctor public EuiccService(); method public void dump(@NonNull java.io.PrintWriter); + method public int encodeSmdxSubjectAndReasonCode(@NonNull String, @NonNull String); method @CallSuper public android.os.IBinder onBind(android.content.Intent); method public abstract int onDeleteSubscription(int, String); method public android.service.euicc.DownloadSubscriptionResult onDownloadSubscription(int, @NonNull android.telephony.euicc.DownloadableSubscription, boolean, boolean, @Nullable android.os.Bundle); @@ -8209,6 +8007,11 @@ package android.telephony { field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0 } + public final class BarringInfo implements android.os.Parcelable { + ctor public BarringInfo(); + method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy(); + } + public final class CallAttributes implements android.os.Parcelable { ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality); method public int describeContents(); @@ -8219,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); @@ -8727,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; } @@ -8884,6 +8665,7 @@ package android.telephony { method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int); @@ -8948,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 @@ -8958,19 +8739,6 @@ package android.telephony { field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000 } - public final class PinResult implements android.os.Parcelable { - ctor public PinResult(int, int); - method public int describeContents(); - method public int getAttemptsRemaining(); - method @NonNull public static android.telephony.PinResult getDefaultFailedResult(); - method public int getType(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PinResult> CREATOR; - field public static final int PIN_RESULT_TYPE_FAILURE = 2; // 0x2 - field public static final int PIN_RESULT_TYPE_INCORRECT = 1; // 0x1 - field public static final int PIN_RESULT_TYPE_SUCCESS = 0; // 0x0 - } - public final class PreciseCallState implements android.os.Parcelable { ctor public PreciseCallState(int, int, int, int, int); method public int describeContents(); @@ -8992,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(); @@ -9099,15 +8866,12 @@ package android.telephony { } public class ServiceState implements android.os.Parcelable { - method @NonNull public android.telephony.ServiceState createLocationInfoSanitizedCopy(boolean); method public void fillInNotifierBundle(@NonNull android.os.Bundle); method public int getDataNetworkType(); - method public int getDataRegistrationState(); method public boolean getDataRoamingFromRegistration(); 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); @@ -9251,7 +9015,8 @@ package android.telephony { method public boolean enableCellBroadcastRange(int, int, int); method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public java.util.List<android.telephony.SmsMessage> getMessagesFromIcc(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc(); - method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String); + method @Deprecated public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String); + method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String, @Nullable String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>); } @@ -9269,7 +9034,7 @@ package android.telephony { public class SubscriptionManager { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean canDisablePhysicalSubscription(); - method public boolean canManageSubscription(@Nullable android.telephony.SubscriptionInfo, @Nullable String); + method public boolean canManageSubscription(@NonNull android.telephony.SubscriptionInfo, @NonNull String); method @NonNull public int[] getActiveAndHiddenSubscriptionIdList(); method @NonNull public int[] getActiveSubscriptionIdList(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String); @@ -9284,10 +9049,10 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(boolean, int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(int, boolean); field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED"; field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI; - field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff + field @Deprecated public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2 field public static final int PROFILE_CLASS_PROVISIONING = 1; // 0x1 field public static final int PROFILE_CLASS_TESTING = 0; // 0x0 @@ -9328,7 +9093,6 @@ package android.telephony { public class TelephonyManager { method public int addDevicePolicyOverrideApn(@NonNull android.content.Context, @NonNull android.telephony.data.ApnSetting); method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int changeIccLockPassword(@NonNull String, @NonNull String); method public int checkCarrierPrivilegesForPackage(String); method public int checkCarrierPrivilegesForPackageAnyPhone(String); method public void dial(String); @@ -9339,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); @@ -9352,7 +9114,6 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int); method public String getCdmaPrlVersion(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaRoamingMode(); method public int getCurrentPhoneType(); method public int getCurrentPhoneType(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState(); @@ -9362,14 +9123,13 @@ package android.telephony { method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); - method public int getEmergencyNumberDbVersion(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String[] getIsimImpu(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); method public int getMaxNumberOfSimultaneouslyActiveSims(); method public static long getMaxNumberVerificationTimeoutMillis(); - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getNetworkCountryIso(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask(); method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState(); method public int getSimApplicationState(); @@ -9391,13 +9151,11 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int); method public boolean isCurrentSimOperator(@NonNull String, int, @Nullable String); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataAllowedInVoiceCall(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionEnabled(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionAllowed(); method public boolean isDataConnectivityPossible(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isGlobalModeEnabled(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean isIccLockEnabled(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isManualNetworkSelectionAllowed(); @@ -9421,25 +9179,18 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int); + method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig(); method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings(); 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 void setAlwaysReportSignalStrength(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 boolean setCdmaRoamingMode(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCdmaSubscriptionMode(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setDataAllowedDuringVoiceCall(boolean); 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 int setIccLockEnabled(boolean, @NonNull String); 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); @@ -9453,15 +9204,13 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyPinReportPinResult(@NonNull String); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyPukReportPinResult(@NonNull String, @NonNull String); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff(); + method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor); method public void updateServiceLocation(); - method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateTestOtaEmergencyNumberDbFilePath(@NonNull String); field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED"; field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; field public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE"; @@ -9475,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 @@ -9486,10 +9231,6 @@ package android.telephony { field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1 field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0 field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff - field public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1 - field public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0 - field public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff - field public static final int CHANGE_ICC_LOCK_SUCCESS = 2147483647; // 0x7fffffff field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION"; field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID"; field @Deprecated public static final String EXTRA_APN_PROTOCOL = "apnProto"; @@ -9545,7 +9286,6 @@ package android.telephony { field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L - field public static final int PHONE_TYPE_THIRD_PARTY = 4; // 0x4 field public static final int RADIO_POWER_OFF = 0; // 0x0 field public static final int RADIO_POWER_ON = 1; // 0x1 field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2 @@ -9625,23 +9365,6 @@ package android.telephony.cdma { package android.telephony.data { - public class ApnSetting implements android.os.Parcelable { - method @NonNull public static String getApnTypesStringFromBitmask(int); - field public static final String TYPE_ALL_STRING = "*"; - field public static final String TYPE_CBS_STRING = "cbs"; - field public static final String TYPE_DEFAULT_STRING = "default"; - field public static final String TYPE_DUN_STRING = "dun"; - field public static final String TYPE_EMERGENCY_STRING = "emergency"; - field public static final String TYPE_FOTA_STRING = "fota"; - field public static final String TYPE_HIPRI_STRING = "hipri"; - field public static final String TYPE_IA_STRING = "ia"; - field public static final String TYPE_IMS_STRING = "ims"; - field public static final String TYPE_MCX_STRING = "mcx"; - field public static final String TYPE_MMS_STRING = "mms"; - field public static final String TYPE_SUPL_STRING = "supl"; - field public static final String TYPE_XCAP_STRING = "xcap"; - } - public final class DataCallResponse implements android.os.Parcelable { method public int describeContents(); method @NonNull public java.util.List<android.net.LinkAddress> getAddresses(); @@ -9967,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); @@ -10128,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"; } @@ -10156,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"; } @@ -10428,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 @@ -10536,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 0c7db06bc0ba..9ed451c2f47e 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -657,7 +657,6 @@ package android.content { field public static final String BUGREPORT_SERVICE = "bugreport"; field public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "content_capture"; field public static final String ETHERNET_SERVICE = "ethernet"; - field public static final String NETWORK_STACK_SERVICE = "network_stack"; field public static final String PERMISSION_SERVICE = "permission"; field public static final String ROLLBACK_SERVICE = "rollback"; field public static final String STATUS_BAR_SERVICE = "statusbar"; @@ -1441,6 +1440,7 @@ package android.net { public class EthernetManager { method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback); + method public void setIncludeTestInterfaces(boolean); } public static interface EthernetManager.TetheredInterfaceCallback { @@ -1477,6 +1477,7 @@ package android.net { public final class LinkProperties implements android.os.Parcelable { ctor public LinkProperties(@Nullable android.net.LinkProperties); + ctor public LinkProperties(@Nullable android.net.LinkProperties, boolean); method public boolean addDnsServer(@NonNull java.net.InetAddress); method public boolean addLinkAddress(@NonNull android.net.LinkAddress); method @Nullable public android.net.Uri getCaptivePortalApiUrl(); @@ -1491,7 +1492,6 @@ package android.net { method public boolean isIpv6Provisioned(); method public boolean isProvisioned(); method public boolean isReachable(@NonNull java.net.InetAddress); - method @NonNull public android.net.LinkProperties makeSensitiveFieldsParcelingCopy(); method public boolean removeDnsServer(@NonNull java.net.InetAddress); method public boolean removeLinkAddress(@NonNull android.net.LinkAddress); method public boolean removeRoute(@NonNull android.net.RouteInfo); @@ -1506,17 +1506,42 @@ 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); field public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK"; } @@ -1590,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); @@ -1607,19 +1631,20 @@ package android.net { field public static final int TETHERING_WIFI = 0; // 0x0 field public static final int TETHERING_WIFI_P2P = 3; // 0x3 field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc - field public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; // 0x9 - field public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; // 0x8 + field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9 + field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8 field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa - field public static final int TETHER_ERROR_MASTER_ERROR = 5; // 0x5 + field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5 field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0 - field public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb + field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2 field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6 field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4 field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1 + field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10 field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3 field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7 field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2 @@ -1631,40 +1656,35 @@ package android.net { method public void onTetheringEntitlementResult(int); } - public abstract static class TetheringManager.StartTetheringCallback { - ctor public TetheringManager.StartTetheringCallback(); - method public void onTetheringFailed(int); - method public void onTetheringStarted(); - } - - public abstract static class TetheringManager.TetheringEventCallback { - ctor public TetheringManager.TetheringEventCallback(); - method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>); - method public void onError(@NonNull String, int); - method public void onOffloadStatusChanged(int); - method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps); - method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>); - method public void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>); - method public void onTetheringSupported(boolean); - method public void onUpstreamChanged(@Nullable android.net.Network); + public static interface TetheringManager.StartTetheringCallback { + method public default void onTetheringFailed(int); + method public default void onTetheringStarted(); } - @Deprecated public static class TetheringManager.TetheringInterfaceRegexps { - ctor @Deprecated public TetheringManager.TetheringInterfaceRegexps(@NonNull String[], @NonNull String[], @NonNull String[]); - method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs(); - method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs(); - method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs(); + public static interface TetheringManager.TetheringEventCallback { + method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>); + method public default void onError(@NonNull String, int); + method public default void onOffloadStatusChanged(int); + method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheringSupported(boolean); + method public default void onUpstreamChanged(@Nullable android.net.Network); } public static class TetheringManager.TetheringRequest { + method @Nullable public android.net.LinkAddress getClientStaticIpv4Address(); + method @Nullable public android.net.LinkAddress getLocalIpv4Address(); + method public boolean getShouldShowEntitlementUi(); + method public int getTetheringType(); + method public boolean isExemptFromEntitlementCheck(); } public static class TetheringManager.TetheringRequest.Builder { ctor public TetheringManager.TetheringRequest.Builder(int); method @NonNull public android.net.TetheringManager.TetheringRequest build(); method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean); - method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean); - method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress); + method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean); + method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress); } public class TrafficStats { @@ -3095,6 +3115,15 @@ package android.telephony { field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0 } + public final class BarringInfo implements android.os.Parcelable { + ctor public BarringInfo(); + ctor public BarringInfo(@Nullable android.telephony.CellIdentity, @NonNull android.util.SparseArray<android.telephony.BarringInfo.BarringServiceInfo>); + } + + public static final class BarringInfo.BarringServiceInfo implements android.os.Parcelable { + ctor public BarringInfo.BarringServiceInfo(int, boolean, int, int); + } + public final class CallQuality implements android.os.Parcelable { ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int); ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean); @@ -3181,6 +3210,7 @@ package android.telephony { method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int); @@ -3219,7 +3249,8 @@ package android.telephony { public final class SmsManager { method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String); - method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String); + method @Deprecated public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String); + method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String, @Nullable String); field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1 field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0 field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3 @@ -3244,17 +3275,17 @@ package android.telephony { method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent); method @Nullable public static android.content.ComponentName getDefaultRespondViaMessageApplication(@NonNull android.content.Context, boolean); method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context); - method public int getEmergencyNumberDbVersion(); + method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getEmergencyNumberDbVersion(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag(); - method @NonNull @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNetworkCountryIso(int); method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion(); method public boolean modifyDevicePolicyOverrideApn(@NonNull android.content.Context, int, @NonNull android.telephony.data.ApnSetting); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile(); + method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void resetOtaEmergencyNumberDbFilePath(); method @Deprecated public void setCarrierTestOverride(String, String, String, String, String, String, String); method public void setCarrierTestOverride(String, String, String, String, String, String, String, String, String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>); - method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void updateTestOtaEmergencyNumberDbFilePath(@NonNull String); + method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor); field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1 field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0 @@ -3318,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); @@ -3480,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"; } @@ -3508,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); @@ -3776,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 @@ -3884,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/config/preloaded-classes-blacklist b/config/preloaded-classes-blacklist index 7cfde8a119f2..5e54559d4b9b 100644 --- a/config/preloaded-classes-blacklist +++ b/config/preloaded-classes-blacklist @@ -4,4 +4,4 @@ android.os.AsyncTask android.os.FileObserver android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask android.widget.Magnifier -sun.nio.fs.UnixChannelFactory + diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index ae1b0ccf4b6d..9d63bc2ef85a 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -3880,7 +3880,6 @@ public class ActivityManager { * {@code false} otherwise. * @hide */ - @SystemApi @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/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 7a736d69bbb5..4d972b13dcd3 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -347,14 +347,6 @@ final class SystemServiceRegistry { } }); - registerService(Context.NETWORK_STACK_SERVICE, IBinder.class, - new StaticServiceFetcher<IBinder>() { - @Override - public IBinder createService() { - return ServiceManager.getService(Context.NETWORK_STACK_SERVICE); - } - }); - registerService(Context.TETHERING_SERVICE, TetheringManager.class, new CachedServiceFetcher<TetheringManager>() { @Override diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 5afd82f198a7..dee013c98546 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -5311,6 +5311,10 @@ public class DevicePolicyManager { throwIfParentInstance("isAlwaysOnVpnLockdownEnabled"); if (mService != null) { try { + // Starting from Android R, the caller can pass the permission check in + // DevicePolicyManagerService if it holds android.permission.MAINLINE_NETWORK_STACK. + // Note that the android.permission.MAINLINE_NETWORK_STACK is a signature permission + // which is used by the NetworkStack mainline module. return mService.isAlwaysOnVpnLockdownEnabled(admin); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); diff --git a/core/java/android/app/compat/CompatChanges.java b/core/java/android/app/compat/CompatChanges.java index e289a2775b79..6689507daadc 100644 --- a/core/java/android/app/compat/CompatChanges.java +++ b/core/java/android/app/compat/CompatChanges.java @@ -17,6 +17,7 @@ package android.app.compat; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.compat.Compatibility; import android.content.Context; @@ -59,14 +60,13 @@ public final class CompatChanges { * <p> Note that this involves a binder call to the system server (unless running in the system * server). If the binder call fails, a {@code RuntimeException} will be thrown. * - * <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it - * doesn't, a {@code RuntimeException} will be thrown. - * * @param changeId The ID of the compatibility change in question. * @param packageName The package name of the app in question. * @param user The user that the operation is done for. * @return {@code true} if the change is enabled for the current app. */ + @RequiresPermission(allOf = {android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG, + android.Manifest.permission.LOG_COMPAT_CHANGE}) public static boolean isChangeEnabled(long changeId, @NonNull String packageName, @NonNull UserHandle user) { IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface( @@ -89,9 +89,6 @@ public final class CompatChanges { * <p> Note that this involves a binder call to the system server (unless running in the system * server). If the binder call fails, {@code RuntimeException} will be thrown. * - * <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it - * doesn't, a {@code RuntimeException} will be thrown. - * * <p> Returns {@code true} if there are no installed packages for the required UID, or if the * change is enabled for ALL of the installed packages associated with the provided UID. Please * use a more specific API if you want a different behaviour for multi-package UIDs. @@ -100,6 +97,8 @@ public final class CompatChanges { * @param uid The UID of the app in question. * @return {@code true} if the change is enabled for the current app. */ + @RequiresPermission(allOf = {android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG, + android.Manifest.permission.LOG_COMPAT_CHANGE}) public static boolean isChangeEnabled(long changeId, int uid) { IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface( ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); diff --git a/core/java/android/app/role/OWNERS b/core/java/android/app/role/OWNERS new file mode 100644 index 000000000000..b94d98827d71 --- /dev/null +++ b/core/java/android/app/role/OWNERS @@ -0,0 +1,6 @@ +svetoslavganov@google.com +moltmann@google.com +zhanghai@google.com +evanseverson@google.com +eugenesusla@google.com +ntmyren@google.com diff --git a/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java index 22e2efb1dedd..002c66361233 100644 --- a/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java +++ b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java @@ -30,7 +30,7 @@ import java.util.List; import java.util.Objects; /** - * A time signal from a manual (user provided) source. + * A time zone suggestion from a manual (user provided) source. * * <p>{@code zoneId} contains the suggested time zone ID, e.g. "America/Los_Angeles". * @@ -124,7 +124,7 @@ public final class ManualTimeZoneSuggestion implements Parcelable { @Override public String toString() { - return "ManualTimeSuggestion{" + return "ManualTimeZoneSuggestion{" + "mZoneId=" + mZoneId + ", mDebugInfo=" + mDebugInfo + '}'; diff --git a/core/java/android/app/timezonedetector/TimeZoneDetector.java b/core/java/android/app/timezonedetector/TimeZoneDetector.java index 20761ad2d447..34a7586192fe 100644 --- a/core/java/android/app/timezonedetector/TimeZoneDetector.java +++ b/core/java/android/app/timezonedetector/TimeZoneDetector.java @@ -41,21 +41,21 @@ public interface TimeZoneDetector { } /** - * Suggests the current time zone, determined using telephony signals, to the detector. The - * detector may ignore the signal based on system settings, whether better information is - * available, and so on. + * Suggests the current time zone, determined using the user's manually entered information, to + * the detector. The detector may ignore the signal based on system settings. * * @hide */ - @RequiresPermission(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE) - void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion); + @RequiresPermission(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE) + void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion); /** - * Suggests the current time zone, determined for the user's manually information, to the - * detector. The detector may ignore the signal based on system settings. + * Suggests the current time zone, determined using telephony signals, to the detector. The + * detector may ignore the signal based on system settings, whether better information is + * available, and so on. * * @hide */ - @RequiresPermission(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE) - void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion); + @RequiresPermission(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE) + void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion); } diff --git a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java index 0ada88500193..54cf1f380d97 100644 --- a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java +++ b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java @@ -40,24 +40,24 @@ public final class TimeZoneDetectorImpl implements TimeZoneDetector { } @Override - public void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion) { + public void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion) { if (DEBUG) { - Log.d(TAG, "suggestTelephonyTimeZone called: " + timeZoneSuggestion); + Log.d(TAG, "suggestManualTimeZone called: " + timeZoneSuggestion); } try { - mITimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion); + mITimeZoneDetectorService.suggestManualTimeZone(timeZoneSuggestion); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override - public void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion) { + public void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion) { if (DEBUG) { - Log.d(TAG, "suggestManualTimeZone called: " + timeZoneSuggestion); + Log.d(TAG, "suggestTelephonyTimeZone called: " + timeZoneSuggestion); } try { - mITimeZoneDetectorService.suggestManualTimeZone(timeZoneSuggestion); + mITimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 5b98188300c9..d6e77624a967 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -29,10 +29,10 @@ import android.net.ConnectivityManager; import android.net.DataUsageRequest; import android.net.INetworkStatsService; import android.net.NetworkIdentity; +import android.net.NetworkStack; import android.net.NetworkTemplate; -import android.net.netstats.provider.AbstractNetworkStatsProvider; -import android.net.netstats.provider.NetworkStatsProviderCallback; -import android.net.netstats.provider.NetworkStatsProviderWrapper; +import android.net.netstats.provider.INetworkStatsProviderCallback; +import android.net.netstats.provider.NetworkStatsProvider; import android.os.Binder; import android.os.Handler; import android.os.Looper; @@ -527,32 +527,53 @@ public class NetworkStatsManager { /** * Registers a custom provider of {@link android.net.NetworkStats} to provide network statistics - * to the system. To unregister, invoke {@link NetworkStatsProviderCallback#unregister()}. + * to the system. To unregister, invoke {@link #unregisterNetworkStatsProvider}. * Note that no de-duplication of statistics between providers is performed, so each provider - * must only report network traffic that is not being reported by any other provider. + * must only report network traffic that is not being reported by any other provider. Also note + * that the provider cannot be re-registered after unregistering. * * @param tag a human readable identifier of the custom network stats provider. This is only * used for debugging. - * @param provider the subclass of {@link AbstractNetworkStatsProvider} that needs to be + * @param provider the subclass of {@link NetworkStatsProvider} that needs to be * registered to the system. - * @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the - * system or unregister the provider. * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) - @NonNull public NetworkStatsProviderCallback registerNetworkStatsProvider( + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STATS_PROVIDER, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) + @NonNull public void registerNetworkStatsProvider( @NonNull String tag, - @NonNull AbstractNetworkStatsProvider provider) { + @NonNull NetworkStatsProvider provider) { try { - final NetworkStatsProviderWrapper wrapper = new NetworkStatsProviderWrapper(provider); - return new NetworkStatsProviderCallback( - mService.registerNetworkStatsProvider(tag, wrapper)); + if (provider.getProviderCallbackBinder() != null) { + throw new IllegalArgumentException("provider is already registered"); + } + final INetworkStatsProviderCallback cbBinder = + mService.registerNetworkStatsProvider(tag, provider.getProviderBinder()); + provider.setProviderCallbackBinder(cbBinder); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Unregisters an instance of {@link NetworkStatsProvider}. + * + * @param provider the subclass of {@link NetworkStatsProvider} that needs to be + * unregistered to the system. + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STATS_PROVIDER, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) + @NonNull public void unregisterNetworkStatsProvider(@NonNull NetworkStatsProvider provider) { + try { + provider.getProviderCallbackBinderOrThrow().unregister(); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } - // Unreachable code, but compiler doesn't know about it. - return null; } private static NetworkTemplate createTemplate(int networkType, String subscriberId) { diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index d8c653c6d0d5..5374d6d55ee3 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -433,7 +433,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * is active * @hide */ - @SystemApi + @UnsupportedAppUsage @Nullable @RequiresPermission(Manifest.permission.BLUETOOTH) public BluetoothDevice getActiveDevice() { @@ -462,7 +462,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @return true if priority is set, false on error * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); @@ -481,7 +481,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); @@ -517,7 +517,18 @@ public final class BluetoothA2dp implements BluetoothProfile { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); - return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device)); + try { + final IBluetoothA2dp service = getService(); + if (service != null && isEnabled() + && isValidDevice(device)) { + return BluetoothAdapter.connectionPolicyToPriority(service.getPriority(device)); + } + if (service == null) Log.w(TAG, "Proxy not attached to service"); + return BluetoothProfile.PRIORITY_OFF; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return BluetoothProfile.PRIORITY_OFF; + } } /** @@ -532,7 +543,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); try { @@ -640,11 +651,12 @@ public final class BluetoothA2dp implements BluetoothProfile { * @return the current codec status * @hide */ - @SystemApi + @UnsupportedAppUsage @Nullable @RequiresPermission(Manifest.permission.BLUETOOTH) - public BluetoothCodecStatus getCodecStatus(@Nullable BluetoothDevice device) { + public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) { if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")"); + verifyDeviceNotNull(device, "getCodecStatus"); try { final IBluetoothA2dp service = getService(); if (service != null && isEnabled()) { @@ -668,11 +680,16 @@ public final class BluetoothA2dp implements BluetoothProfile { * @param codecConfig the codec configuration preference * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) - public void setCodecConfigPreference(@Nullable BluetoothDevice device, - @Nullable BluetoothCodecConfig codecConfig) { + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH) + public void setCodecConfigPreference(@NonNull BluetoothDevice device, + @NonNull BluetoothCodecConfig codecConfig) { if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")"); + verifyDeviceNotNull(device, "setCodecConfigPreference"); + if (codecConfig == null) { + Log.e(TAG, "setCodecConfigPreference: Codec config can't be null"); + throw new IllegalArgumentException("codecConfig cannot be null"); + } try { final IBluetoothA2dp service = getService(); if (service != null && isEnabled()) { @@ -693,10 +710,11 @@ public final class BluetoothA2dp implements BluetoothProfile { * active A2DP Bluetooth device. * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) - public void enableOptionalCodecs(@Nullable BluetoothDevice device) { + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH) + public void enableOptionalCodecs(@NonNull BluetoothDevice device) { if (DBG) Log.d(TAG, "enableOptionalCodecs(" + device + ")"); + verifyDeviceNotNull(device, "enableOptionalCodecs"); enableDisableOptionalCodecs(device, true); } @@ -707,10 +725,11 @@ public final class BluetoothA2dp implements BluetoothProfile { * active A2DP Bluetooth device. * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) - public void disableOptionalCodecs(@Nullable BluetoothDevice device) { + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH) + public void disableOptionalCodecs(@NonNull BluetoothDevice device) { if (DBG) Log.d(TAG, "disableOptionalCodecs(" + device + ")"); + verifyDeviceNotNull(device, "disableOptionalCodecs"); enableDisableOptionalCodecs(device, false); } @@ -747,10 +766,11 @@ public final class BluetoothA2dp implements BluetoothProfile { * OPTIONAL_CODECS_SUPPORTED. * @hide */ - @SystemApi + @UnsupportedAppUsage @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) @OptionalCodecsSupportStatus - public int supportsOptionalCodecs(@Nullable BluetoothDevice device) { + public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) { + verifyDeviceNotNull(device, "isOptionalCodecsSupported"); try { final IBluetoothA2dp service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { @@ -772,10 +792,11 @@ public final class BluetoothA2dp implements BluetoothProfile { * OPTIONAL_CODECS_PREF_DISABLED. * @hide */ - @SystemApi + @UnsupportedAppUsage @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) @OptionalCodecsPreferenceStatus - public int getOptionalCodecsEnabled(@Nullable BluetoothDevice device) { + public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) { + verifyDeviceNotNull(device, "isOptionalCodecsEnabled"); try { final IBluetoothA2dp service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { @@ -798,10 +819,11 @@ public final class BluetoothA2dp implements BluetoothProfile { * OPTIONAL_CODECS_PREF_DISABLED. * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) - public void setOptionalCodecsEnabled(@Nullable BluetoothDevice device, + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + public void setOptionalCodecsEnabled(@NonNull BluetoothDevice device, @OptionalCodecsPreferenceStatus int value) { + verifyDeviceNotNull(device, "setOptionalCodecsEnabled"); try { if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED @@ -854,6 +876,13 @@ public final class BluetoothA2dp 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/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java index ab492309ba3d..53f87e6bc05b 100755 --- a/core/java/android/bluetooth/BluetoothA2dpSink.java +++ b/core/java/android/bluetooth/BluetoothA2dpSink.java @@ -17,7 +17,7 @@ package android.bluetooth; import android.Manifest; -import android.annotation.Nullable; +import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; @@ -120,7 +120,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile { * @return false on immediate error, true otherwise * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connect(BluetoothDevice device) { if (DBG) log("connect(" + device + ")"); final IBluetoothA2dpSink service = getService(); @@ -277,7 +277,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile { * @return true if priority is set, false on error * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); @@ -297,7 +297,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile { */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) - public boolean setConnectionPolicy(@Nullable BluetoothDevice device, + public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); final IBluetoothA2dpSink service = getService(); @@ -327,7 +327,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile { * @return priority of the device * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device)); @@ -346,7 +346,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile { */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) - public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) { + public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); final IBluetoothA2dpSink service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { @@ -371,7 +371,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile { */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) - public boolean isAudioPlaying(@Nullable BluetoothDevice device) { + public boolean isAudioPlaying(@NonNull BluetoothDevice device) { final IBluetoothA2dpSink service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { try { diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 0a9dbb608b9c..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); } @@ -1214,7 +1191,7 @@ public final class BluetoothAdapter { * @return true to indicate that the config file was successfully cleared * @hide */ - @SystemApi + @UnsupportedAppUsage @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset() { try { @@ -1506,8 +1483,9 @@ public final class BluetoothAdapter { * @return true if the scan mode was set, false otherwise * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @UnsupportedAppUsage(publicAlternatives = "Use {@link #ACTION_REQUEST_DISCOVERABLE}, which " + + "shows UI that confirms the user wants to go into discoverable mode.") + @RequiresPermission(Manifest.permission.BLUETOOTH) public boolean setScanMode(@ScanMode int mode, long durationMillis) { if (getState() != STATE_ON) { return false; @@ -1555,8 +1533,8 @@ public final class BluetoothAdapter { * @return true if the scan mode was set, false otherwise * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH) public boolean setScanMode(@ScanMode int mode) { if (getState() != STATE_ON) { return false; @@ -1620,7 +1598,7 @@ public final class BluetoothAdapter { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public long getDiscoveryEndMillis() { try { mServiceLock.readLock().lock(); @@ -1872,7 +1850,6 @@ public final class BluetoothAdapter { * * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connectAllEnabledProfiles(@NonNull BluetoothDevice device) { try { @@ -1901,7 +1878,6 @@ public final class BluetoothAdapter { * * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnectAllEnabledProfiles(@NonNull BluetoothDevice device) { try { diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java index 93e76fa5ba7d..d2a15357aa1f 100644 --- a/core/java/android/bluetooth/BluetoothCodecConfig.java +++ b/core/java/android/bluetooth/BluetoothCodecConfig.java @@ -18,7 +18,6 @@ package android.bluetooth; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -34,7 +33,6 @@ import java.util.Objects; * * {@hide} */ -@SystemApi public final class BluetoothCodecConfig implements Parcelable { // Add an entry for each source codec here. // NOTE: The values should be same as those listed in the following file: diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java index b6e77391da5d..1e394b830d51 100644 --- a/core/java/android/bluetooth/BluetoothCodecStatus.java +++ b/core/java/android/bluetooth/BluetoothCodecStatus.java @@ -17,7 +17,6 @@ package android.bluetooth; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -32,7 +31,6 @@ import java.util.Objects; * * {@hide} */ -@SystemApi public final class BluetoothCodecStatus implements Parcelable { /** * Extra for the codec configuration intents of the individual profiles. diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 2a3f2be64228..a2cf7d9cc248 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -35,8 +35,6 @@ import android.os.Process; import android.os.RemoteException; import android.util.Log; -import com.android.internal.annotations.VisibleForTesting; - import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.annotation.Retention; @@ -1103,8 +1101,8 @@ public final class BluetoothDevice implements Parcelable { * @return true on success, false on error * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH) public boolean setAlias(@NonNull String alias) { final IBluetooth service = sService; if (service == null) { @@ -1145,8 +1143,8 @@ public final class BluetoothDevice implements Parcelable { * not have any battery reporting service, or return value is invalid * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH) public int getBatteryLevel() { final IBluetooth service = sService; if (service == null) { @@ -1236,8 +1234,8 @@ public final class BluetoothDevice implements Parcelable { * * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH) public boolean isBondingInitiatedLocally() { final IBluetooth service = sService; if (service == null) { @@ -1531,7 +1529,7 @@ public final class BluetoothDevice implements Parcelable { * @return true pin has been set false for error * @hide */ - @SystemApi + @UnsupportedAppUsage @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean setPin(@NonNull String pin) { byte[] pinBytes = convertPinToBytes(pin); @@ -1568,8 +1566,8 @@ public final class BluetoothDevice implements Parcelable { * * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean cancelPairing() { final IBluetooth service = sService; if (service == null) { @@ -1600,8 +1598,8 @@ public final class BluetoothDevice implements Parcelable { * #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}. * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH) public @AccessPermission int getPhonebookAccessPermission() { final IBluetooth service = sService; if (service == null) { @@ -1708,8 +1706,8 @@ public final class BluetoothDevice implements Parcelable { * @return Whether the message access is allowed to this device. * @hide */ - @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @UnsupportedAppUsage + @RequiresPermission(Manifest.permission.BLUETOOTH) public @AccessPermission int getMessageAccessPermission() { final IBluetooth service = sService; if (service == null) { @@ -1758,7 +1756,7 @@ public final class BluetoothDevice implements Parcelable { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresPermission(Manifest.permission.BLUETOOTH) public @AccessPermission int getSimAccessPermission() { final IBluetooth service = sService; if (service == null) { @@ -2013,7 +2011,7 @@ public final class BluetoothDevice implements Parcelable { * @return the pin code as a UTF-8 byte array, or null if it is an invalid Bluetooth pin. * @hide */ - @VisibleForTesting + @UnsupportedAppUsage public static byte[] convertPinToBytes(String pin) { if (pin == null) { return null; diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java index 1ba2bb5e31ad..6ce05f984cca 100644 --- a/core/java/android/bluetooth/BluetoothHeadset.java +++ b/core/java/android/bluetooth/BluetoothHeadset.java @@ -572,7 +572,22 @@ public final class BluetoothHeadset implements BluetoothProfile { @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); - return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); + final IBluetoothHeadset service = mService; + if (service != null && isEnabled() && isValidDevice(device)) { + if (priority != BluetoothProfile.PRIORITY_OFF + && priority != BluetoothProfile.PRIORITY_ON) { + return false; + } + try { + return service.setPriority( + device, BluetoothAdapter.priorityToConnectionPolicy(priority)); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + return false; + } + } + if (service == null) Log.w(TAG, "Proxy not attached to service"); + return false; } /** @@ -588,7 +603,7 @@ public final class BluetoothHeadset implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); @@ -624,7 +639,17 @@ public final class BluetoothHeadset implements BluetoothProfile { @RequiresPermission(Manifest.permission.BLUETOOTH) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); - return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device)); + final IBluetoothHeadset service = mService; + if (service != null && isEnabled() && isValidDevice(device)) { + try { + return BluetoothAdapter.connectionPolicyToPriority(service.getPriority(device)); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + return BluetoothProfile.PRIORITY_OFF; + } + } + if (service == null) Log.w(TAG, "Proxy not attached to service"); + return BluetoothProfile.PRIORITY_OFF; } /** @@ -639,7 +664,7 @@ public final class BluetoothHeadset implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); final IBluetoothHeadset service = mService; @@ -1126,16 +1151,13 @@ public final class BluetoothHeadset implements BluetoothProfile { /** * Get the connected device that is active. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} - * permission. - * * @return the connected device that is active or null if no device * is active. * @hide */ - @SystemApi + @UnsupportedAppUsage @Nullable - @RequiresPermission(android.Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH) public BluetoothDevice getActiveDevice() { if (VDBG) { Log.d(TAG, "getActiveDevice"); diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java index fbda9e9d6dd7..85e0e08b19c8 100644 --- a/core/java/android/bluetooth/BluetoothHeadsetClient.java +++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java @@ -17,6 +17,7 @@ package android.bluetooth; import android.Manifest; +import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; @@ -442,6 +443,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * @param device a remote device we want connect to * @return <code>true</code> if command has been issued successfully; <code>false</code> * otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent. + * + * @hide */ @UnsupportedAppUsage public boolean connect(BluetoothDevice device) { @@ -466,6 +469,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * @param device a remote device we want disconnect * @return <code>true</code> if command has been issued successfully; <code>false</code> * otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent. + * + * @hide */ @UnsupportedAppUsage public boolean disconnect(BluetoothDevice device) { @@ -564,7 +569,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * @return true if priority is set, false on error * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); @@ -583,8 +588,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) - public boolean setConnectionPolicy(BluetoothDevice device, + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); final IBluetoothHeadsetClient service = @@ -634,7 +639,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { */ @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH) - public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) { + public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); final IBluetoothHeadsetClient service = getService(); diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java index 38498bc147b2..fa62a02499e0 100644 --- a/core/java/android/bluetooth/BluetoothHearingAid.java +++ b/core/java/android/bluetooth/BluetoothHearingAid.java @@ -162,13 +162,11 @@ public final class BluetoothHearingAid implements BluetoothProfile { * the state. Users can get the connection state of the profile * from this intent. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} - * permission. - * * @param device Remote Bluetooth Device * @return false on immediate error, true otherwise * @hide */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connect(BluetoothDevice device) { if (DBG) log("connect(" + device + ")"); final IBluetoothHearingAid service = getService(); @@ -202,13 +200,11 @@ public final class BluetoothHearingAid implements BluetoothProfile { * {@link #STATE_DISCONNECTING} can be used to distinguish between the * two scenarios. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} - * permission. - * * @param device Remote Bluetooth Device * @return false on immediate error, true otherwise * @hide */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnect(BluetoothDevice device) { if (DBG) log("disconnect(" + device + ")"); final IBluetoothHearingAid service = getService(); @@ -327,15 +323,12 @@ public final class BluetoothHearingAid implements BluetoothProfile { /** * Get the connected physical Hearing Aid devices that are active * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH} - * permission. - * * @return the list of active devices. The first element is the left active * device; the second element is the right active device. If either or both side * is not active, it will be null on that position. Returns empty list on error. * @hide */ - @SystemApi + @UnsupportedAppUsage @RequiresPermission(Manifest.permission.BLUETOOTH) public @NonNull List<BluetoothDevice> getActiveDevices() { if (VDBG) log("getActiveDevices()"); @@ -363,7 +356,7 @@ public final class BluetoothHearingAid implements BluetoothProfile { * @return true if priority is set, false on error * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); @@ -382,10 +375,11 @@ public final class BluetoothHearingAid implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) 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() @@ -414,7 +408,7 @@ public final class BluetoothHearingAid implements BluetoothProfile { * @return priority of the device * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device)); @@ -432,9 +426,10 @@ public final class BluetoothHearingAid implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) + @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() @@ -496,18 +491,22 @@ public final class BluetoothHearingAid implements BluetoothProfile { } /** - * Get the CustomerId of the device. + * Get the HiSyncId (unique hearing aid device identifier) of the device. + * + * <a href=https://source.android.com/devices/bluetooth/asha#hisyncid>HiSyncId documentation + * can be found here</a> * * @param device Bluetooth device - * @return the CustomerId of the device + * @return the HiSyncId of the device * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) - public long getHiSyncId(@Nullable BluetoothDevice device) { + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public long getHiSyncId(@NonNull BluetoothDevice device) { if (VDBG) { - log("getCustomerId(" + device + ")"); + log("getHiSyncId(" + device + ")"); } + verifyDeviceNotNull(device, "getConnectionPolicy"); final IBluetoothHearingAid service = getService(); try { if (service == null) { @@ -581,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/bluetooth/BluetoothHidHost.java b/core/java/android/bluetooth/BluetoothHidHost.java index e9e1f6866908..9561d9383846 100644 --- a/core/java/android/bluetooth/BluetoothHidHost.java +++ b/core/java/android/bluetooth/BluetoothHidHost.java @@ -263,13 +263,11 @@ public final class BluetoothHidHost implements BluetoothProfile { * the state. Users can get the connection state of the profile * from this intent. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} - * permission. - * * @param device Remote Bluetooth Device * @return false on immediate error, true otherwise * @hide */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connect(BluetoothDevice device) { if (DBG) log("connect(" + device + ")"); final IBluetoothHidHost service = getService(); @@ -303,13 +301,11 @@ public final class BluetoothHidHost implements BluetoothProfile { * {@link #STATE_DISCONNECTING} can be used to distinguish between the * two scenarios. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} - * permission. - * * @param device Remote Bluetooth Device * @return false on immediate error, true otherwise * @hide */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnect(BluetoothDevice device) { if (DBG) log("disconnect(" + device + ")"); final IBluetoothHidHost service = getService(); @@ -327,7 +323,10 @@ public final class BluetoothHidHost implements BluetoothProfile { /** * {@inheritDoc} + * + * @hide */ + @SystemApi @Override @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public @NonNull List<BluetoothDevice> getConnectedDevices() { @@ -368,7 +367,10 @@ public final class BluetoothHidHost implements BluetoothProfile { /** * {@inheritDoc} + * + * @hide */ + @SystemApi @Override @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@NonNull BluetoothDevice device) { @@ -400,7 +402,7 @@ public final class BluetoothHidHost implements BluetoothProfile { * @return true if priority is set, false on error * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); @@ -419,7 +421,7 @@ public final class BluetoothHidHost implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); @@ -453,7 +455,7 @@ public final class BluetoothHidHost implements BluetoothProfile { * @return priority of the device * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device)); @@ -471,7 +473,7 @@ public final class BluetoothHidHost implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); if (device == null) { diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java index cc2b6155a7ea..14a71c44673b 100644 --- a/core/java/android/bluetooth/BluetoothMap.java +++ b/core/java/android/bluetooth/BluetoothMap.java @@ -18,7 +18,6 @@ package android.bluetooth; import android.Manifest; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; @@ -328,7 +327,7 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable { * @return true if priority is set, false on error * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); @@ -347,8 +346,8 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) - public boolean setConnectionPolicy(@Nullable BluetoothDevice device, + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); final IBluetoothMap service = getService(); @@ -378,7 +377,7 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable { * @return priority of the device * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device)); @@ -396,8 +395,8 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) - public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) { + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); final IBluetoothMap service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java index 8d2aaddd38d2..19240dc0bbc7 100644 --- a/core/java/android/bluetooth/BluetoothMapClient.java +++ b/core/java/android/bluetooth/BluetoothMapClient.java @@ -17,6 +17,7 @@ package android.bluetooth; import android.Manifest; +import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.app.PendingIntent; @@ -140,7 +141,10 @@ public final class BluetoothMapClient implements BluetoothProfile { /** * Initiate connection. Initiation of outgoing connections is not * supported for MAP server. + * + * @hide */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connect(BluetoothDevice device) { if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE"); final IBluetoothMapClient service = getService(); @@ -162,7 +166,10 @@ public final class BluetoothMapClient implements BluetoothProfile { * * @param device Remote Bluetooth Device * @return false on error, true otherwise + * + * @hide */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnect(BluetoothDevice device) { if (DBG) Log.d(TAG, "disconnect(" + device + ")"); final IBluetoothMapClient service = getService(); @@ -251,7 +258,7 @@ public final class BluetoothMapClient implements BluetoothProfile { * @return true if priority is set, false on error * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")"); return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); @@ -270,8 +277,8 @@ public final class BluetoothMapClient implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) - public boolean setConnectionPolicy(BluetoothDevice device, + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { if (DBG) Log.d(TAG, "setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); final IBluetoothMapClient service = getService(); @@ -301,7 +308,7 @@ public final class BluetoothMapClient implements BluetoothProfile { * @return priority of the device * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public int getPriority(BluetoothDevice device) { if (VDBG) Log.d(TAG, "getPriority(" + device + ")"); return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device)); @@ -319,8 +326,8 @@ public final class BluetoothMapClient implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) - public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) { + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) Log.d(TAG, "getConnectionPolicy(" + device + ")"); final IBluetoothMapClient service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java index 7af770e69efe..a80f5b7f36d4 100644 --- a/core/java/android/bluetooth/BluetoothPan.java +++ b/core/java/android/bluetooth/BluetoothPan.java @@ -19,7 +19,6 @@ package android.bluetooth; import android.Manifest; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; @@ -30,7 +29,6 @@ import android.content.Context; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; -import android.util.CloseGuard; import android.util.Log; import java.lang.annotation.Retention; @@ -51,11 +49,10 @@ import java.util.List; * @hide */ @SystemApi -public final class BluetoothPan implements BluetoothProfile, AutoCloseable { +public final class BluetoothPan implements BluetoothProfile { private static final String TAG = "BluetoothPan"; private static final boolean DBG = true; private static final boolean VDBG = false; - private CloseGuard mCloseGuard; /** * Intent used to broadcast the change in connection state of the Pan @@ -168,16 +165,13 @@ public final class BluetoothPan implements BluetoothProfile, AutoCloseable { mAdapter = BluetoothAdapter.getDefaultAdapter(); mContext = context; mProfileConnector.connect(context, listener); - mCloseGuard = new CloseGuard(); - mCloseGuard.open("close"); } /** * Closes the connection to the service and unregisters callbacks - * - * @hide */ - public void close() { + @UnsupportedAppUsage + void close() { if (VDBG) log("close()"); mProfileConnector.disconnect(); } @@ -188,9 +182,6 @@ public final class BluetoothPan implements BluetoothProfile, AutoCloseable { /** @hide */ protected void finalize() { - if (mCloseGuard != null) { - mCloseGuard.warnIfOpen(); - } close(); } @@ -204,9 +195,6 @@ public final class BluetoothPan implements BluetoothProfile, AutoCloseable { * the state. Users can get the connection state of the profile * from this intent. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} - * permission. - * * @param device Remote Bluetooth Device * @return false on immediate error, true otherwise * @hide @@ -245,9 +233,6 @@ public final class BluetoothPan implements BluetoothProfile, AutoCloseable { * {@link #STATE_DISCONNECTING} can be used to distinguish between the * two scenarios. * - * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} - * permission. - * * @param device Remote Bluetooth Device * @return false on immediate error, true otherwise * @hide @@ -353,7 +338,7 @@ public final class BluetoothPan implements BluetoothProfile, AutoCloseable { @SystemApi @Override @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) - public int getConnectionState(@Nullable BluetoothDevice device) { + public int getConnectionState(@NonNull BluetoothDevice device) { if (VDBG) log("getState(" + device + ")"); final IBluetoothPan service = getService(); if (service != null && isEnabled() && isValidDevice(device)) { diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java index 277a5a8f1625..d58a89350195 100644 --- a/core/java/android/bluetooth/BluetoothPbap.java +++ b/core/java/android/bluetooth/BluetoothPbap.java @@ -18,7 +18,6 @@ package android.bluetooth; import android.Manifest; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SuppressLint; @@ -239,7 +238,7 @@ public class BluetoothPbap implements BluetoothProfile { @SystemApi @Override @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) - public @BtProfileState int getConnectionState(@Nullable BluetoothDevice device) { + public @BtProfileState int getConnectionState(@NonNull BluetoothDevice device) { log("getConnectionState: device=" + device); try { final IBluetoothPbap service = mService; diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java index 9563c68ce657..d3452ffb4586 100644 --- a/core/java/android/bluetooth/BluetoothPbapClient.java +++ b/core/java/android/bluetooth/BluetoothPbapClient.java @@ -17,6 +17,7 @@ package android.bluetooth; import android.Manifest; +import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.content.Context; @@ -101,7 +102,10 @@ public final class BluetoothPbapClient implements BluetoothProfile { * @param device a remote device we want connect to * @return <code>true</code> if command has been issued successfully; <code>false</code> * otherwise; + * + * @hide */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connect(BluetoothDevice device) { if (DBG) { log("connect(" + device + ") for PBAP Client."); @@ -126,7 +130,10 @@ public final class BluetoothPbapClient implements BluetoothProfile { * * @param device Remote Bluetooth Device * @return false on error, true otherwise + * + * @hide */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnect(BluetoothDevice device) { if (DBG) { log("disconnect(" + device + ")" + new Exception()); @@ -251,7 +258,7 @@ public final class BluetoothPbapClient implements BluetoothProfile { * @return true if priority is set, false on error * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); @@ -270,8 +277,8 @@ public final class BluetoothPbapClient implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) - public boolean setConnectionPolicy(BluetoothDevice device, + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { if (DBG) { log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); @@ -305,7 +312,7 @@ public final class BluetoothPbapClient implements BluetoothProfile { * @return priority of the device * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device)); @@ -323,8 +330,8 @@ public final class BluetoothPbapClient implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) - public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) { + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) { log("getConnectionPolicy(" + device + ")"); } diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java index bfc3a4d25c23..6e0348158f48 100644 --- a/core/java/android/bluetooth/BluetoothSap.java +++ b/core/java/android/bluetooth/BluetoothSap.java @@ -310,7 +310,7 @@ public final class BluetoothSap implements BluetoothProfile { * @return true if priority is set, false on error * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority)); @@ -329,7 +329,7 @@ public final class BluetoothSap implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")"); @@ -360,7 +360,7 @@ public final class BluetoothSap implements BluetoothProfile { * @return priority of the device * @hide */ - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device)); @@ -378,7 +378,7 @@ public final class BluetoothSap implements BluetoothProfile { * @hide */ @SystemApi - @RequiresPermission(Manifest.permission.BLUETOOTH) + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); final IBluetoothSap service = getService(); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index c19c2848a0ae..b79965eb4c21 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3864,15 +3864,13 @@ public abstract class Context { * @hide * @see NetworkStackClient */ - @SystemApi - @TestApi public static final String NETWORK_STACK_SERVICE = "network_stack"; /** - * Use with {@link android.os.ServiceManager.getService()} to retrieve a - * {@link ITetheringConnector} IBinder for communicating with the tethering service + * Use with {@link #getSystemService(String)} to retrieve a {@link android.net.TetheringManager} + * for managing tethering functions. * @hide - * @see TetheringClient + * @see android.net.TetheringManager */ @SystemApi public static final String TETHERING_SERVICE = "tethering"; @@ -3947,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/Intent.java b/core/java/android/content/Intent.java index ba91014a8756..467aa15ea242 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -3622,9 +3622,7 @@ public class Intent implements Parcelable, Cloneable { * {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast. * @hide */ - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @SystemApi + @UnsupportedAppUsage public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED"; diff --git a/core/java/android/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/hardware/usb/OWNERS b/core/java/android/hardware/usb/OWNERS new file mode 100644 index 000000000000..8ee72b577f3c --- /dev/null +++ b/core/java/android/hardware/usb/OWNERS @@ -0,0 +1,6 @@ +badhri@google.com +elaurent@google.com +moltmann@google.com +albertccwang@google.com +jameswei@google.com +howardyen@google.com
\ No newline at end of file diff --git a/core/java/android/inputmethodservice/OWNERS b/core/java/android/inputmethodservice/OWNERS new file mode 100644 index 000000000000..444719701df2 --- /dev/null +++ b/core/java/android/inputmethodservice/OWNERS @@ -0,0 +1,3 @@ +set noparent + +include ../../../../services/core/java/com/android/server/inputmethod/OWNERS diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.java b/core/java/android/net/ConnectivityDiagnosticsManager.java index d009144034f0..6f0a4f974442 100644 --- a/core/java/android/net/ConnectivityDiagnosticsManager.java +++ b/core/java/android/net/ConnectivityDiagnosticsManager.java @@ -136,7 +136,7 @@ public class ConnectivityDiagnosticsManager { * {@link #NETWORK_VALIDATION_RESULT_PARTIALLY_VALID}, * {@link #NETWORK_VALIDATION_RESULT_SKIPPED}. * - * @see android.net.NetworkCapabilities#CAPABILITY_VALIDATED + * @see android.net.NetworkCapabilities#NET_CAPABILITY_VALIDATED */ @NetworkValidationResult public static final String KEY_NETWORK_VALIDATION_RESULT = "networkValidationResult"; @@ -233,8 +233,8 @@ public class ConnectivityDiagnosticsManager { * Constructor for ConnectivityReport. * * <p>Apps should obtain instances through {@link - * ConnectivityDiagnosticsCallback#onConnectivityReport} instead of instantiating their own - * instances (unless for testing purposes). + * ConnectivityDiagnosticsCallback#onConnectivityReportAvailable} instead of instantiating + * their own instances (unless for testing purposes). * * @param network The Network for which this ConnectivityReport applies * @param reportTimestamp The timestamp for the report @@ -368,7 +368,14 @@ public class ConnectivityDiagnosticsManager { /** Class that includes information for a suspected data stall on a specific Network */ public static final class DataStallReport implements Parcelable { + /** + * Indicates that the Data Stall was detected using DNS events. + */ public static final int DETECTION_METHOD_DNS_EVENTS = 1; + + /** + * Indicates that the Data Stall was detected using TCP metrics. + */ public static final int DETECTION_METHOD_TCP_METRICS = 2; /** @hide */ @@ -615,10 +622,10 @@ public class ConnectivityDiagnosticsManager { /** @hide */ @VisibleForTesting - public void onConnectivityReport(@NonNull ConnectivityReport report) { + public void onConnectivityReportAvailable(@NonNull ConnectivityReport report) { Binder.withCleanCallingIdentity(() -> { mExecutor.execute(() -> { - mCb.onConnectivityReport(report); + mCb.onConnectivityReportAvailable(report); }); }); } @@ -659,7 +666,7 @@ public class ConnectivityDiagnosticsManager { * * @param report The ConnectivityReport containing information about a connectivity check */ - public void onConnectivityReport(@NonNull ConnectivityReport report) {} + public void onConnectivityReportAvailable(@NonNull ConnectivityReport report) {} /** * Called when the platform suspects a data stall on some Network. diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index d8a97de0b7df..0f48ac229026 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -145,16 +145,6 @@ public class ConnectivityManager { public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; /** - * A temporary hack until SUPL system can get off the legacy APIS. - * They do too many network requests and the long list of apps listening - * and waking due to the CONNECTIVITY_ACTION broadcast makes it expensive. - * Use this broadcast intent instead for SUPL requests. - * @hide - */ - public static final String CONNECTIVITY_ACTION_SUPL = - "android.net.conn.CONNECTIVITY_CHANGE_SUPL"; - - /** * The device has connected to a network that has presented a captive * portal, which is blocking Internet connectivity. The user was presented * with a notification that network sign in is required, @@ -1517,84 +1507,6 @@ public class ConnectivityManager { return null; } - /** - * Guess what the network request was trying to say so that the resulting - * network is accessible via the legacy (deprecated) API such as - * requestRouteToHost. - * - * This means we should try to be fairly precise about transport and - * capability but ignore things such as networkSpecifier. - * If the request has more than one transport or capability it doesn't - * match the old legacy requests (they selected only single transport/capability) - * so this function cannot map the request to a single legacy type and - * the resulting network will not be available to the legacy APIs. - * - * This code is only called from the requestNetwork API (L and above). - * - * Setting a legacy type causes CONNECTIVITY_ACTION broadcasts, which are expensive - * because they wake up lots of apps - see http://b/23350688 . So we currently only - * do this for SUPL requests, which are the only ones that we know need it. If - * omitting these broadcasts causes unacceptable app breakage, then for backwards - * compatibility we can send them: - * - * if (targetSdkVersion < Build.VERSION_CODES.M) && // legacy API unsupported >= M - * targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP)) // requestNetwork not present < L - * - * TODO - This should be removed when the legacy APIs are removed. - */ - private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) { - if (netCap == null) { - return TYPE_NONE; - } - - if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { - return TYPE_NONE; - } - - // Do this only for SUPL, until GnssLocationProvider is fixed. http://b/25876485 . - if (!netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) { - // NOTE: if this causes app breakage, we should not just comment out this early return; - // instead, we should make this early return conditional on the requesting app's target - // SDK version, as described in the comment above. - return TYPE_NONE; - } - - String type = null; - int result = TYPE_NONE; - - if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) { - type = "enableCBS"; - result = TYPE_MOBILE_CBS; - } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) { - type = "enableIMS"; - result = TYPE_MOBILE_IMS; - } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) { - type = "enableFOTA"; - result = TYPE_MOBILE_FOTA; - } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) { - type = "enableDUN"; - result = TYPE_MOBILE_DUN; - } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) { - type = "enableSUPL"; - result = TYPE_MOBILE_SUPL; - // back out this hack for mms as they no longer need this and it's causing - // device slowdowns - b/23350688 (note, supl still needs this) - //} else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) { - // type = "enableMMS"; - // result = TYPE_MOBILE_MMS; - } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) { - type = "enableHIPRI"; - result = TYPE_MOBILE_HIPRI; - } - if (type != null) { - NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type); - if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) { - return result; - } - } - return TYPE_NONE; - } - private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) { if (netCap == null) return TYPE_NONE; if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) { @@ -2576,13 +2488,13 @@ public class ConnectivityManager { } @Override - public void onTetheringFailed(final int resultCode) { + public void onTetheringFailed(final int error) { callback.onTetheringFailed(); } }; final TetheringRequest request = new TetheringRequest.Builder(type) - .setSilentProvisioning(!showProvisioningUi).build(); + .setShouldShowEntitlementUi(showProvisioningUi).build(); mTetheringManager.startTethering(request, executor, tetheringCallback); } @@ -2802,11 +2714,12 @@ public class ConnectivityManager { public static final int TETHER_ERROR_UNAVAIL_IFACE = TetheringManager.TETHER_ERROR_UNAVAIL_IFACE; /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_MASTER_ERROR}. + * @deprecated Use {@link TetheringManager#TETHER_ERROR_INTERNAL_ERROR}. * {@hide} */ @Deprecated - public static final int TETHER_ERROR_MASTER_ERROR = TetheringManager.TETHER_ERROR_MASTER_ERROR; + public static final int TETHER_ERROR_MASTER_ERROR = + TetheringManager.TETHER_ERROR_INTERNAL_ERROR; /** * @deprecated Use {@link TetheringManager#TETHER_ERROR_TETHER_IFACE_ERROR}. * {@hide} @@ -2822,19 +2735,19 @@ public class ConnectivityManager { public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR; /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_ENABLE_NAT_ERROR}. + * @deprecated Use {@link TetheringManager#TETHER_ERROR_ENABLE_FORWARDING_ERROR}. * {@hide} */ @Deprecated public static final int TETHER_ERROR_ENABLE_NAT_ERROR = - TetheringManager.TETHER_ERROR_ENABLE_NAT_ERROR; + TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR; /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_DISABLE_NAT_ERROR}. + * @deprecated Use {@link TetheringManager#TETHER_ERROR_DISABLE_FORWARDING_ERROR}. * {@hide} */ @Deprecated public static final int TETHER_ERROR_DISABLE_NAT_ERROR = - TetheringManager.TETHER_ERROR_DISABLE_NAT_ERROR; + TetheringManager.TETHER_ERROR_DISABLE_FORWARDING_ERROR; /** * @deprecated Use {@link TetheringManager#TETHER_ERROR_IFACE_CFG_ERROR}. * {@hide} @@ -2843,13 +2756,13 @@ public class ConnectivityManager { public static final int TETHER_ERROR_IFACE_CFG_ERROR = TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR; /** - * @deprecated Use {@link TetheringManager#TETHER_ERROR_PROVISION_FAILED}. + * @deprecated Use {@link TetheringManager#TETHER_ERROR_PROVISIONING_FAILED}. * {@hide} */ @SystemApi @Deprecated public static final int TETHER_ERROR_PROVISION_FAILED = - TetheringManager.TETHER_ERROR_PROVISION_FAILED; + TetheringManager.TETHER_ERROR_PROVISIONING_FAILED; /** * @deprecated Use {@link TetheringManager#TETHER_ERROR_DHCPSERVER_ERROR}. * {@hide} @@ -2881,7 +2794,14 @@ public class ConnectivityManager { @UnsupportedAppUsage @Deprecated public int getLastTetherError(String iface) { - return mTetheringManager.getLastTetherError(iface); + int error = mTetheringManager.getLastTetherError(iface); + if (error == TetheringManager.TETHER_ERROR_UNKNOWN_TYPE) { + // TETHER_ERROR_UNKNOWN_TYPE was introduced with TetheringManager and has never been + // returned by ConnectivityManager. Convert it to the legacy TETHER_ERROR_UNKNOWN_IFACE + // instead. + error = TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; + } + return error; } /** @hide */ @@ -3774,29 +3694,29 @@ public class ConnectivityManager { /** * Helper function to request a network with a particular legacy type. * - * @deprecated This is temporarily public for tethering to backwards compatibility that uses - * the NetworkRequest API to request networks with legacy type and relies on - * CONNECTIVITY_ACTION broadcasts instead of NetworkCallbacks. New caller should use + * This API is only for use in internal system code that requests networks with legacy type and + * relies on CONNECTIVITY_ACTION broadcasts instead of NetworkCallbacks. New caller should use * {@link #requestNetwork(NetworkRequest, NetworkCallback, Handler)} instead. * - * TODO: update said system code to rely on NetworkCallbacks and make this method private. - * @param request {@link NetworkRequest} describing this request. - * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note - * the callback must not be shared - it uniquely specifies this request. * @param timeoutMs The time in milliseconds to attempt looking for a suitable network * before {@link NetworkCallback#onUnavailable()} is called. The timeout must * be a positive value (i.e. >0). * @param legacyType to specify the network type(#TYPE_*). * @param handler {@link Handler} to specify the thread upon which the callback will be invoked. + * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note + * the callback must not be shared - it uniquely specifies this request. * * @hide */ @SystemApi - @Deprecated + @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull NetworkRequest request, - @NonNull NetworkCallback networkCallback, int timeoutMs, int legacyType, - @NonNull Handler handler) { + int timeoutMs, int legacyType, @NonNull Handler handler, + @NonNull NetworkCallback networkCallback) { + if (legacyType == TYPE_NONE) { + throw new IllegalArgumentException("TYPE_NONE is meaningless legacy type"); + } CallbackHandler cbHandler = new CallbackHandler(handler); NetworkCapabilities nc = request.networkCapabilities; sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, legacyType, cbHandler); @@ -3894,9 +3814,9 @@ public class ConnectivityManager { */ public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, @NonNull Handler handler) { - int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); CallbackHandler cbHandler = new CallbackHandler(handler); - requestNetwork(request, networkCallback, 0, legacyType, cbHandler); + NetworkCapabilities nc = request.networkCapabilities; + sendRequestForNetwork(nc, networkCallback, 0, REQUEST, TYPE_NONE, cbHandler); } /** @@ -3929,8 +3849,9 @@ public class ConnectivityManager { public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, int timeoutMs) { checkTimeout(timeoutMs); - int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); - requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler()); + NetworkCapabilities nc = request.networkCapabilities; + sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, TYPE_NONE, + getDefaultHandler()); } /** @@ -3955,9 +3876,9 @@ public class ConnectivityManager { public void requestNetwork(@NonNull NetworkRequest request, @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) { checkTimeout(timeoutMs); - int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities); CallbackHandler cbHandler = new CallbackHandler(handler); - requestNetwork(request, networkCallback, timeoutMs, legacyType, cbHandler); + NetworkCapabilities nc = request.networkCapabilities; + sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, TYPE_NONE, cbHandler); } /** diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java index 83b5f63576f2..d975017f9c8e 100644 --- a/core/java/android/net/EthernetManager.java +++ b/core/java/android/net/EthernetManager.java @@ -200,6 +200,21 @@ public class EthernetManager { } /** + * Whether to treat interfaces created by {@link TestNetworkManager#createTapInterface} + * as Ethernet interfaces. The effects of this method apply to any test interfaces that are + * already present on the system. + * @hide + */ + @TestApi + public void setIncludeTestInterfaces(boolean include) { + try { + mService.setIncludeTestInterfaces(include); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * A request for a tethered interface. */ public static class TetheredInterfaceRequest { diff --git a/core/java/android/net/IConnectivityDiagnosticsCallback.aidl b/core/java/android/net/IConnectivityDiagnosticsCallback.aidl index 3a161bfabfd2..82b64a928000 100644 --- a/core/java/android/net/IConnectivityDiagnosticsCallback.aidl +++ b/core/java/android/net/IConnectivityDiagnosticsCallback.aidl @@ -22,7 +22,7 @@ import android.net.Network; /** @hide */ oneway interface IConnectivityDiagnosticsCallback { - void onConnectivityReport(in ConnectivityDiagnosticsManager.ConnectivityReport report); + void onConnectivityReportAvailable(in ConnectivityDiagnosticsManager.ConnectivityReport report); void onDataStallSuspected(in ConnectivityDiagnosticsManager.DataStallReport report); void onNetworkConnectivityReported(in Network n, boolean hasConnectivity); }
\ No newline at end of file diff --git a/core/java/android/net/IEthernetManager.aidl b/core/java/android/net/IEthernetManager.aidl index ccc6e352098f..e058e5a70c71 100644 --- a/core/java/android/net/IEthernetManager.aidl +++ b/core/java/android/net/IEthernetManager.aidl @@ -33,6 +33,7 @@ interface IEthernetManager boolean isAvailable(String iface); void addListener(in IEthernetServiceListener listener); void removeListener(in IEthernetServiceListener listener); + void setIncludeTestInterfaces(boolean include); void requestTetheredInterface(in ITetheredInterfaceCallback callback); void releaseTetheredInterface(in ITetheredInterfaceCallback callback); } diff --git a/core/java/android/net/ITestNetworkManager.aidl b/core/java/android/net/ITestNetworkManager.aidl index d586038ebb89..2a863adde581 100644 --- a/core/java/android/net/ITestNetworkManager.aidl +++ b/core/java/android/net/ITestNetworkManager.aidl @@ -33,7 +33,7 @@ interface ITestNetworkManager TestNetworkInterface createTapInterface(); void setupTestNetwork(in String iface, in LinkProperties lp, in boolean isMetered, - in IBinder binder); + in int[] administratorUids, in IBinder binder); void teardownTestNetwork(int netId); } 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 2b8b7e69dec9..e21cb44f72d8 100644 --- a/core/java/android/net/KeepalivePacketData.java +++ b/core/java/android/net/KeepalivePacketData.java @@ -19,10 +19,10 @@ 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; -import android.os.Parcel; import android.util.Log; import java.net.InetAddress; @@ -30,7 +30,6 @@ import java.net.InetAddress; /** * Represents the actual packets that are sent by the * {@link android.net.SocketKeepalive} API. - * * @hide */ @SystemApi @@ -39,33 +38,37 @@ 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; + // Note: If you add new fields, please modify the parcelling code in the child classes. + + // This should only be constructed via static factory methods, such as // nattKeepalivePacket. /** * 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. @@ -82,26 +85,34 @@ public class KeepalivePacketData { } } + /** Get source IP address. */ @NonNull - public byte[] getPacket() { - return mPacket.clone(); + public InetAddress getSrcAddress() { + return mSrcAddress; + } + + /** Get destination IP address. */ + @NonNull + public InetAddress getDstAddress() { + return mDstAddress; } - /** @hide */ - public void writeToParcel(Parcel out, int flags) { - out.writeString(srcAddress.getHostAddress()); - out.writeString(dstAddress.getHostAddress()); - out.writeInt(srcPort); - out.writeInt(dstPort); - out.writeByteArray(mPacket); + /** Get source port number. */ + public int getSrcPort() { + return mSrcPort; } - /** @hide */ - protected KeepalivePacketData(Parcel in) { - srcAddress = NetworkUtils.numericToInetAddress(in.readString()); - dstAddress = NetworkUtils.numericToInetAddress(in.readString()); - srcPort = in.readInt(); - dstPort = in.readInt(); - mPacket = in.createByteArray(); + /** 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 732ceb560cab..7ff954bdc1d2 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -167,7 +167,19 @@ public final class LinkProperties implements Parcelable { this(source, false /* parcelSensitiveFields */); } - private LinkProperties(@Nullable LinkProperties source, boolean parcelSensitiveFields) { + /** + * Create a copy of a {@link LinkProperties} that may preserve fields that were set + * based on the permissions of the process that originally received it. + * + * <p>By default {@link LinkProperties} does not preserve such fields during parceling, as + * they should not be shared outside of the process that receives them without appropriate + * checks. + * @param parcelSensitiveFields Whether the sensitive fields should be kept when parceling + * @hide + */ + @SystemApi + @TestApi + public LinkProperties(@Nullable LinkProperties source, boolean parcelSensitiveFields) { mParcelSensitiveFields = parcelSensitiveFields; if (source == null) return; mIfaceName = source.mIfaceName; @@ -674,17 +686,29 @@ public final class LinkProperties implements Parcelable { route.getDestination(), route.getGateway(), mIfaceName, - route.getType()); + route.getType(), + route.getMtu()); + } + + private int findRouteIndexByRouteKey(RouteInfo route) { + for (int i = 0; i < mRoutes.size(); i++) { + if (mRoutes.get(i).getRouteKey().equals(route.getRouteKey())) { + return i; + } + } + return -1; } /** - * Adds a {@link RouteInfo} to this {@code LinkProperties}, if not present. 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}. + * Adds a {@link RouteInfo} to this {@code LinkProperties}, if a {@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 false} if the route was already present, {@code true} if it was added. + * @return {@code true} was added or updated, false otherwise. */ public boolean addRoute(@NonNull RouteInfo route) { String routeIface = route.getInterface(); @@ -694,11 +718,20 @@ public final class LinkProperties implements Parcelable { + " vs. " + mIfaceName); } route = routeWithInterface(route); - if (!mRoutes.contains(route)) { + + int i = findRouteIndexByRouteKey(route); + if (i == -1) { + // Route was not present. Add it. mRoutes.add(route); return true; + } else if (mRoutes.get(i).equals(route)) { + // Route was present and has same properties. Do nothing. + return false; + } else { + // Route was present and has different properties. Update it. + mRoutes.set(i, route); + return true; } - return false; } /** @@ -706,6 +739,7 @@ public final class LinkProperties implements Parcelable { * specify an interface and the interface must match the interface of this * {@code LinkProperties}, or it will not be removed. * + * @param route A {@link RouteInfo} specifying the route to remove. * @return {@code true} if the route was removed, {@code false} if it was not present. * * @hide @@ -1561,22 +1595,6 @@ public final class LinkProperties implements Parcelable { } /** - * Create a copy of this {@link LinkProperties} that will preserve fields that were set - * based on the permissions of the process that received this {@link LinkProperties}. - * - * <p>By default {@link LinkProperties} does not preserve such fields during parceling, as - * they should not be shared outside of the process that receives them without appropriate - * checks. - * @hide - */ - @SystemApi - @TestApi - @NonNull - public LinkProperties makeSensitiveFieldsParcelingCopy() { - return new LinkProperties(this, true /* parcelSensitiveFields */); - } - - /** * Compares this {@code LinkProperties} instance against the target * LinkProperties in {@code obj}. Two LinkPropertieses are equal if * all their fields are equal in values. 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 8d1ab332ce12..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; @@ -61,17 +62,18 @@ import javax.net.SocketFactory; 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 @@ -169,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 @@ -283,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; } /** @@ -353,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/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index fef353f604dc..5c754a1b9733 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -78,6 +78,7 @@ public abstract class NetworkAgent { /** * The ID of the {@link NetworkProvider} that created this object, or * {@link NetworkProvider#ID_NONE} if unknown. + * @hide */ public final int providerId; @@ -584,6 +585,7 @@ public abstract class NetworkAgent { * * @deprecated this is for backward compatibility only. * @param legacySubtype the legacy subtype. + * @hide */ @Deprecated public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) { @@ -608,6 +610,7 @@ public abstract class NetworkAgent { * * @deprecated this is for backward compatibility only. * @param extraInfo the ExtraInfo. + * @hide */ @Deprecated public void setLegacyExtraInfo(@Nullable final String extraInfo) { @@ -711,6 +714,7 @@ public abstract class NetworkAgent { /** * Called when ConnectivityService request a bandwidth update. The parent factory * shall try to overwrite this method and produce a bandwidth update if capable. + * @hide */ public void onBandwidthUpdateRequested() { pollLceData(); diff --git a/core/java/android/net/NetworkAgentConfig.java b/core/java/android/net/NetworkAgentConfig.java index 7e2db4a4fa95..ca9328a713f0 100644 --- a/core/java/android/net/NetworkAgentConfig.java +++ b/core/java/android/net/NetworkAgentConfig.java @@ -108,6 +108,7 @@ public final class NetworkAgentConfig implements Parcelable { /** * * @return whether the sign in to network notification is enabled by this configuration. + * @hide */ public boolean isProvisioningNotificationEnabled() { return !provisioningNotificationDisabled; @@ -122,6 +123,7 @@ public final class NetworkAgentConfig implements Parcelable { /** * @return the subscriber ID, or null if none. + * @hide */ @Nullable public String getSubscriberId() { @@ -138,6 +140,7 @@ public final class NetworkAgentConfig implements Parcelable { /** * @return whether NAT64 prefix detection is enabled. + * @hide */ public boolean isNat64DetectionEnabled() { return !skip464xlat; @@ -247,6 +250,7 @@ public final class NetworkAgentConfig implements Parcelable { * Sets the subscriber ID for this network. * * @return this builder, to facilitate chaining. + * @hide */ @NonNull public Builder setSubscriberId(@Nullable String subscriberId) { @@ -259,6 +263,7 @@ public final class NetworkAgentConfig implements Parcelable { * and reduce idle traffic on networks that are known to be IPv6-only without a NAT64. * * @return this builder, to facilitate chaining. + * @hide */ @NonNull public Builder disableNat64Detection() { @@ -271,6 +276,7 @@ public final class NetworkAgentConfig implements Parcelable { * perform its own carrier-specific provisioning procedure. * * @return this builder, to facilitate chaining. + * @hide */ @NonNull public Builder disableProvisioningNotification() { diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 873d6e914629..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,14 +33,13 @@ 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; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.Arrays; import java.util.Objects; import java.util.Set; import java.util.StringJoiner; @@ -88,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; @@ -96,7 +97,7 @@ public final class NetworkCapabilities implements Parcelable { mTransportInfo = null; mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; mUids = null; - mAdministratorUids.clear(); + mAdministratorUids = new int[0]; mOwnerUid = Process.INVALID_UID; mSSID = null; mPrivateDnsBroken = false; @@ -414,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 @@ -434,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 @@ -456,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), @@ -470,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) { @@ -613,7 +630,6 @@ public final class NetworkCapabilities implements Parcelable { * @return {@code true} if the network should be restricted. * @hide */ - @SystemApi public boolean deduceRestrictedCapability() { // Check if we have any capability that forces the network to be restricted. final boolean forceRestrictedCapability = @@ -644,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 @@ -731,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 @@ -740,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); @@ -852,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; @@ -869,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; @@ -885,10 +920,10 @@ public final class NetworkCapabilities implements Parcelable { * empty unless the destination is 1) the System Server, or 2) Telephony. In either case, the * receiving entity must have the ACCESS_FINE_LOCATION permission and target R+. */ - private final List<Integer> mAdministratorUids = new ArrayList<>(); + private int[] mAdministratorUids = new int[0]; /** - * Sets the list of UIDs that are administrators of this network. + * Sets the int[] 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: @@ -907,24 +942,22 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @NonNull - @SystemApi - public NetworkCapabilities setAdministratorUids( - @NonNull final List<Integer> administratorUids) { - mAdministratorUids.clear(); - mAdministratorUids.addAll(administratorUids); + public NetworkCapabilities setAdministratorUids(@NonNull final int[] administratorUids) { + mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length); return this; } /** - * Retrieves the list of UIDs that are administrators of this Network. + * Retrieves the UIDs that are administrators of this Network. * - * @return the List of UIDs that are administrators of this Network + * @return the int[] of UIDs that are administrators of this Network * @hide */ @NonNull @SystemApi - public List<Integer> getAdministratorUids() { - return Collections.unmodifiableList(mAdministratorUids); + @TestApi + public int[] getAdministratorUids() { + return Arrays.copyOf(mAdministratorUids, mAdministratorUids.length); } /** @@ -945,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; @@ -974,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; @@ -1041,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) { @@ -1062,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; @@ -1072,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; @@ -1142,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; @@ -1368,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; @@ -1379,7 +1402,8 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @SystemApi - public @Nullable String getSSID() { + @TestApi + public @Nullable String getSsid() { return mSSID; } @@ -1585,7 +1609,7 @@ public final class NetworkCapabilities implements Parcelable { dest.writeArraySet(mUids); dest.writeString(mSSID); dest.writeBoolean(mPrivateDnsBroken); - dest.writeList(mAdministratorUids); + dest.writeIntArray(mAdministratorUids); dest.writeInt(mOwnerUid); dest.writeInt(mRequestorUid); dest.writeString(mRequestorPackageName); @@ -1609,7 +1633,7 @@ public final class NetworkCapabilities implements Parcelable { null /* ClassLoader, null for default */); netCap.mSSID = in.readString(); netCap.mPrivateDnsBroken = in.readBoolean(); - netCap.setAdministratorUids(in.readArrayList(null)); + netCap.setAdministratorUids(in.createIntArray()); netCap.mOwnerUid = in.readInt(); netCap.mRequestorUid = in.readInt(); netCap.mRequestorPackageName = in.readString(); @@ -1666,8 +1690,8 @@ public final class NetworkCapabilities implements Parcelable { sb.append(" OwnerUid: ").append(mOwnerUid); } - if (!mAdministratorUids.isEmpty()) { - sb.append(" AdministratorUids: ").append(mAdministratorUids); + if (mAdministratorUids.length == 0) { + sb.append(" AdministratorUids: ").append(Arrays.toString(mAdministratorUids)); } if (null != mSSID) { @@ -1859,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() { @@ -1887,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 @@ -1912,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. @@ -1973,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/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index febc730480e4..4edbcd0ac8b8 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -25,6 +25,7 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Build; import android.service.NetworkIdentityProto; +import android.telephony.Annotation.NetworkType; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -39,16 +40,6 @@ import java.util.Objects; public class NetworkIdentity implements Comparable<NetworkIdentity> { private static final String TAG = "NetworkIdentity"; - /** - * When enabled, combine all {@link #mSubType} together under - * {@link #SUBTYPE_COMBINED}. - * - * @deprecated we no longer offer to collect statistics on a per-subtype - * basis; this is always disabled. - */ - @Deprecated - public static final boolean COMBINE_SUBTYPE_ENABLED = true; - public static final int SUBTYPE_COMBINED = -1; final int mType; @@ -63,7 +54,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { int type, int subType, String subscriberId, String networkId, boolean roaming, boolean metered, boolean defaultNetwork) { mType = type; - mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType; + mSubType = subType; mSubscriberId = subscriberId; mNetworkId = networkId; mRoaming = roaming; @@ -95,7 +86,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { final StringBuilder builder = new StringBuilder("{"); builder.append("type=").append(getNetworkTypeName(mType)); builder.append(", subType="); - if (COMBINE_SUBTYPE_ENABLED) { + if (mSubType == SUBTYPE_COMBINED) { builder.append("COMBINED"); } else { builder.append(mSubType); @@ -187,13 +178,14 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { } /** - * Build a {@link NetworkIdentity} from the given {@link NetworkState}, - * assuming that any mobile networks are using the current IMSI. + * Build a {@link NetworkIdentity} from the given {@link NetworkState} and {@code subType}, + * assuming that any mobile networks are using the current IMSI. The subType if applicable, + * should be set as one of the TelephonyManager.NETWORK_TYPE_* constants, or + * {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not. */ public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state, - boolean defaultNetwork) { + boolean defaultNetwork, @NetworkType int subType) { final int type = state.networkInfo.getType(); - final int subType = state.networkInfo.getSubtype(); String subscriberId = null; String networkId = null; diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java index 08fe159b276e..d752901e2eb0 100644 --- a/core/java/android/net/NetworkInfo.java +++ b/core/java/android/net/NetworkInfo.java @@ -22,6 +22,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.NetworkType; +import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; @@ -538,7 +539,7 @@ public class NetworkInfo implements Parcelable { @Override public String toString() { synchronized (this) { - StringBuilder builder = new StringBuilder("["); + final StringBuilder builder = new StringBuilder("["); builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()). append("], state: ").append(mState).append("/").append(mDetailedState). append(", reason: ").append(mReason == null ? "(unspecified)" : mReason). @@ -551,6 +552,32 @@ public class NetworkInfo implements Parcelable { } } + /** + * Returns a brief summary string suitable for debugging. + * @hide + */ + public String toShortString() { + synchronized (this) { + final StringBuilder builder = new StringBuilder(); + builder.append(getTypeName()); + + final String subtype = getSubtypeName(); + if (!TextUtils.isEmpty(subtype)) { + builder.append("[").append(subtype).append("]"); + } + + builder.append(" "); + builder.append(mDetailedState); + if (mIsRoaming) { + builder.append(" ROAMING"); + } + if (mExtraInfo != null) { + builder.append(" extra: ").append(mExtraInfo); + } + return builder.toString(); + } + } + @Override public int describeContents() { return 0; diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 14442a2088cd..1922b6df2e7f 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -21,7 +21,6 @@ import static android.content.pm.PackageManager.GET_SIGNATURES; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; -import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.ActivityManager; import android.compat.annotation.UnsupportedAppUsage; @@ -56,7 +55,6 @@ import java.util.concurrent.ConcurrentHashMap; * @hide */ @SystemService(Context.NETWORK_POLICY_SERVICE) -@SystemApi public class NetworkPolicyManager { /* POLICY_* are masks and can be ORed, although currently they are not.*/ @@ -162,11 +160,13 @@ public class NetworkPolicyManager { /** * Mask used to check if an override value is marked as unmetered. + * @hide */ public static final int SUBSCRIPTION_OVERRIDE_UNMETERED = 1 << 0; /** * Mask used to check if an override value is marked as congested. + * @hide */ public static final int SUBSCRIPTION_OVERRIDE_CONGESTED = 1 << 1; @@ -294,7 +294,6 @@ public class NetworkPolicyManager { /** @hide */ @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) - @SystemApi public void registerSubscriptionCallback(@NonNull SubscriptionCallback callback) { if (callback == null) { throw new NullPointerException("Callback cannot be null."); @@ -309,7 +308,6 @@ public class NetworkPolicyManager { /** @hide */ @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) - @SystemApi public void unregisterSubscriptionCallback(@NonNull SubscriptionCallback callback) { if (callback == null) { throw new NullPointerException("Callback cannot be null."); @@ -373,6 +371,7 @@ public class NetworkPolicyManager { * requested state until explicitly cleared, or the next reboot, * whichever happens first * @param callingPackage the name of the package making the call. + * @hide */ public void setSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask, @SubscriptionOverrideMask int overrideValue, long timeoutMillis, @@ -391,6 +390,7 @@ public class NetworkPolicyManager { * @param subId the subscriber this relationship applies to. * @param plans the list of plans. * @param callingPackage the name of the package making the call + * @hide */ public void setSubscriptionPlans(int subId, @NonNull SubscriptionPlan[] plans, @NonNull String callingPackage) { @@ -406,6 +406,7 @@ public class NetworkPolicyManager { * * @param subId the subscriber to get the subscription plans for. * @param callingPackage the name of the package making the call. + * @hide */ @NonNull public SubscriptionPlan[] getSubscriptionPlans(int subId, @NonNull String callingPackage) { @@ -549,7 +550,6 @@ public class NetworkPolicyManager { } /** @hide */ - @SystemApi public static class SubscriptionCallback { /** * Notify clients of a new override about a given subscription. diff --git a/core/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java index 2c0e4aa700b1..418d6915d4b3 100644 --- a/core/java/android/net/NetworkProvider.java +++ b/core/java/android/net/NetworkProvider.java @@ -106,10 +106,12 @@ public class NetworkProvider { } // TODO: consider adding a register() method so ConnectivityManager does not need to call this. + /** @hide */ public @Nullable Messenger getMessenger() { return mMessenger; } + /** @hide */ public @NonNull String getName() { return mName; } diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java index a46c410bd55e..86f3dfd412f6 100644 --- a/core/java/android/net/NetworkStack.java +++ b/core/java/android/net/NetworkStack.java @@ -19,15 +19,17 @@ import static android.Manifest.permission.NETWORK_STACK; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.content.Context; +import android.os.IBinder; +import android.os.ServiceManager; import java.util.ArrayList; import java.util.Arrays; /** - * - * Constants for client code communicating with the network stack service. + * Constants and utilities for client code communicating with the network stack service. * @hide */ @SystemApi @@ -43,6 +45,34 @@ public class NetworkStack { public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK"; + @Nullable + private static volatile IBinder sMockService; + + /** + * Get an {@link IBinder} representing the NetworkStack stable AIDL Interface, if registered. + * @hide + */ + @Nullable + @SystemApi + @TestApi + public static IBinder getService() { + final IBinder mockService = sMockService; + if (mockService != null) return mockService; + return ServiceManager.getService(Context.NETWORK_STACK_SERVICE); + } + + /** + * Set a mock service for testing, to be returned by future calls to {@link #getService()}. + * + * <p>Passing a {@code null} {@code mockService} resets {@link #getService()} to normal + * behavior. + * @hide + */ + @TestApi + public static void setServiceForTest(@Nullable IBinder mockService) { + sMockService = mockService; + } + private NetworkStack() {} /** diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index 2f536ffd8ca6..9c1fb41ecc96 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -21,7 +21,6 @@ import static android.os.Process.CLAT_UID; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; @@ -58,9 +57,12 @@ import java.util.function.Predicate; public final class NetworkStats implements Parcelable { private static final String TAG = "NetworkStats"; - /** {@link #iface} value when interface details unavailable. */ - @SuppressLint("CompileTimeConstant") + /** + * {@link #iface} value when interface details unavailable. + * @hide + */ @Nullable public static final String IFACE_ALL = null; + /** * Virtual network interface for video telephony. This is for VT data usage counting * purpose. @@ -248,7 +250,13 @@ public final class NetworkStats implements Parcelable { @UnsupportedAppUsage private long[] operations; - /** @hide */ + /** + * Basic element of network statistics. Contains the number of packets and number of bytes + * transferred on both directions in a given set of conditions. See + * {@link Entry#Entry(String, int, int, int, int, int, int, long, long, long, long, long)}. + * + * @hide + */ @SystemApi public static class Entry { /** @hide */ @@ -319,6 +327,35 @@ public final class NetworkStats implements Parcelable { rxBytes, rxPackets, txBytes, txPackets, operations); } + /** + * Construct a {@link Entry} object by giving statistics of packet and byte transferred on + * both direction, and associated with a set of given conditions. + * + * @param iface interface name of this {@link Entry}. Or null if not specified. + * @param uid uid of this {@link Entry}. {@link #UID_TETHERING} if this {@link Entry} is + * for tethering. Or {@link #UID_ALL} if this {@link NetworkStats} is only + * counting iface stats. + * @param set usage state of this {@link Entry}. Should be one of the following + * values: {@link #SET_DEFAULT}, {@link #SET_FOREGROUND}. + * @param tag tag of this {@link Entry}. + * @param metered metered state of this {@link Entry}. Should be one of the following + * values: {link #METERED_YES}, {link #METERED_NO}. + * @param roaming roaming state of this {@link Entry}. Should be one of the following + * values: {link #ROAMING_YES}, {link #ROAMING_NO}. + * @param defaultNetwork default network status of this {@link Entry}. Should be one + * of the following values: {link #DEFAULT_NETWORK_YES}, + * {link #DEFAULT_NETWORK_NO}. + * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should + * represent the contents of IP packets, including IP headers. + * @param rxPackets Number of packets received for this {@link Entry}. Statistics should + * represent the contents of IP packets, including IP headers. + * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should + * represent the contents of IP packets, including IP headers. + * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should + * represent the contents of IP packets, including IP headers. + * @param operations count of network operations performed for this {@link Entry}. This can + * be used to derive bytes-per-operation. + */ public Entry(@Nullable String iface, int uid, @State int set, int tag, @Meteredness int metered, @Roaming int roaming, @DefaultNetwork int defaultNetwork, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { @@ -466,7 +503,7 @@ public final class NetworkStats implements Parcelable { NetworkStats.Entry entry = null; for (int i = 0; i < size; i++) { entry = getValues(i, entry); - clone.addEntry(entry); + clone.insertEntry(entry); } return clone; } @@ -493,26 +530,26 @@ public final class NetworkStats implements Parcelable { /** @hide */ @VisibleForTesting - public NetworkStats addIfaceValues( + public NetworkStats insertEntry( String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { - return addEntry( + return insertEntry( iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L); } /** @hide */ @VisibleForTesting - public NetworkStats addEntry(String iface, int uid, int set, int tag, long rxBytes, + public NetworkStats insertEntry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { - return addEntry(new Entry( + return insertEntry(new Entry( iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); } /** @hide */ @VisibleForTesting - public NetworkStats addEntry(String iface, int uid, int set, int tag, int metered, int roaming, - int defaultNetwork, long rxBytes, long rxPackets, long txBytes, long txPackets, - long operations) { - return addEntry(new Entry( + public NetworkStats insertEntry(String iface, int uid, int set, int tag, int metered, + int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes, + long txPackets, long operations) { + return insertEntry(new Entry( iface, uid, set, tag, metered, roaming, defaultNetwork, rxBytes, rxPackets, txBytes, txPackets, operations)); } @@ -522,7 +559,7 @@ public final class NetworkStats implements Parcelable { * object can be recycled across multiple calls. * @hide */ - public NetworkStats addEntry(Entry entry) { + public NetworkStats insertEntry(Entry entry) { if (size >= capacity) { final int newLength = Math.max(size, 10) * 3 / 2; iface = Arrays.copyOf(iface, newLength); @@ -665,7 +702,7 @@ public final class NetworkStats implements Parcelable { entry.roaming, entry.defaultNetwork); if (i == -1) { // only create new entry when positive contribution - addEntry(entry); + insertEntry(entry); } else { rxBytes[i] += entry.rxBytes; rxPackets[i] += entry.rxPackets; @@ -684,7 +721,7 @@ public final class NetworkStats implements Parcelable { * @param entry the {@link Entry} to add. * @return a new constructed {@link NetworkStats} object that contains the result. */ - public @NonNull NetworkStats addValues(@NonNull Entry entry) { + public @NonNull NetworkStats addEntry(@NonNull Entry entry) { return this.clone().combineValues(entry); } @@ -1003,7 +1040,7 @@ public final class NetworkStats implements Parcelable { entry.operations = Math.max(entry.operations, 0); } - result.addEntry(entry); + result.insertEntry(entry); } return result; diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 5498f74ba2cc..cb9463a59d34 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -34,9 +34,13 @@ import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_YES; import static android.net.wifi.WifiInfo.sanitizeSsid; +import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.NetworkType; +import android.telephony.TelephonyManager; +import android.text.TextUtils; import android.util.BackupUtils; import android.util.Log; @@ -73,6 +77,14 @@ public class NetworkTemplate implements Parcelable { public static final int MATCH_BLUETOOTH = 8; public static final int MATCH_PROXY = 9; + /** + * Include all network types when filtering. This is meant to merge in with the + * {@code TelephonyManager.NETWORK_TYPE_*} constants, and thus needs to stay in sync. + * + * @hide + */ + public static final int NETWORK_TYPE_ALL = -1; + private static boolean isKnownMatchRule(final int rule) { switch (rule) { case MATCH_MOBILE: @@ -117,7 +129,22 @@ public class NetworkTemplate implements Parcelable { } /** - * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks, + * Template to match cellular networks with the given IMSI and {@code ratType}. + * Use {@link #NETWORK_TYPE_ALL} to include all network types when filtering. + * See {@code TelephonyManager.NETWORK_TYPE_*}. + */ + public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId, + @NetworkType int ratType) { + if (TextUtils.isEmpty(subscriberId)) { + return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null, null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType); + } + return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[]{subscriberId}, null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType); + } + + /** + * Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks, * regardless of IMSI. */ @UnsupportedAppUsage @@ -126,7 +153,7 @@ public class NetworkTemplate implements Parcelable { } /** - * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks, + * Template to match all metered {@link ConnectivityManager#TYPE_WIFI} networks, * regardless of SSID. */ @UnsupportedAppUsage @@ -192,6 +219,7 @@ public class NetworkTemplate implements Parcelable { private final int mMetered; private final int mRoaming; private final int mDefaultNetwork; + private final int mSubType; @UnsupportedAppUsage public NetworkTemplate(int matchRule, String subscriberId, String networkId) { @@ -201,11 +229,11 @@ public class NetworkTemplate implements Parcelable { public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds, String networkId) { this(matchRule, subscriberId, matchSubscriberIds, networkId, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL); + DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL); } public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds, - String networkId, int metered, int roaming, int defaultNetwork) { + String networkId, int metered, int roaming, int defaultNetwork, int subType) { mMatchRule = matchRule; mSubscriberId = subscriberId; mMatchSubscriberIds = matchSubscriberIds; @@ -213,6 +241,7 @@ public class NetworkTemplate implements Parcelable { mMetered = metered; mRoaming = roaming; mDefaultNetwork = defaultNetwork; + mSubType = subType; if (!isKnownMatchRule(matchRule)) { Log.e(TAG, "Unknown network template rule " + matchRule @@ -228,6 +257,7 @@ public class NetworkTemplate implements Parcelable { mMetered = in.readInt(); mRoaming = in.readInt(); mDefaultNetwork = in.readInt(); + mSubType = in.readInt(); } @Override @@ -239,6 +269,7 @@ public class NetworkTemplate implements Parcelable { dest.writeInt(mMetered); dest.writeInt(mRoaming); dest.writeInt(mDefaultNetwork); + dest.writeInt(mSubType); } @Override @@ -271,13 +302,16 @@ public class NetworkTemplate implements Parcelable { builder.append(", defaultNetwork=").append(NetworkStats.defaultNetworkToString( mDefaultNetwork)); } + if (mSubType != NETWORK_TYPE_ALL) { + builder.append(", subType=").append(mSubType); + } return builder.toString(); } @Override public int hashCode() { return Objects.hash(mMatchRule, mSubscriberId, mNetworkId, mMetered, mRoaming, - mDefaultNetwork); + mDefaultNetwork, mSubType); } @Override @@ -289,7 +323,8 @@ public class NetworkTemplate implements Parcelable { && Objects.equals(mNetworkId, other.mNetworkId) && mMetered == other.mMetered && mRoaming == other.mRoaming - && mDefaultNetwork == other.mDefaultNetwork; + && mDefaultNetwork == other.mDefaultNetwork + && mSubType == other.mSubType; } return false; } @@ -376,6 +411,11 @@ public class NetworkTemplate implements Parcelable { || (mDefaultNetwork == DEFAULT_NETWORK_NO && !ident.mDefaultNetwork); } + private boolean matchesCollapsedRatType(NetworkIdentity ident) { + return mSubType == NETWORK_TYPE_ALL + || getCollapsedRatType(mSubType) == getCollapsedRatType(ident.mSubType); + } + public boolean matchesSubscriberId(String subscriberId) { return ArrayUtils.contains(mMatchSubscriberIds, subscriberId); } @@ -388,9 +428,52 @@ public class NetworkTemplate implements Parcelable { // TODO: consider matching against WiMAX subscriber identity return true; } else { + // Only metered mobile network would be matched regardless of metered filter. + // This is used to exclude non-metered APNs, e.g. IMS. See ag/908650. + // TODO: Respect metered filter and remove mMetered condition. return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered)) && !ArrayUtils.isEmpty(mMatchSubscriberIds) - && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId); + && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId) + && matchesCollapsedRatType(ident); + } + } + + /** + * Get a Radio Access Technology(RAT) type that is representative of a group of RAT types. + * The mapping is corresponding to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*}. + * + * @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}. + */ + // TODO: 1. Consider move this to TelephonyManager if used by other modules. + // 2. Consider make this configurable. + // 3. Use TelephonyManager APIs when available. + public static int getCollapsedRatType(int ratType) { + switch (ratType) { + case TelephonyManager.NETWORK_TYPE_GPRS: + case TelephonyManager.NETWORK_TYPE_GSM: + case TelephonyManager.NETWORK_TYPE_EDGE: + case TelephonyManager.NETWORK_TYPE_IDEN: + case TelephonyManager.NETWORK_TYPE_CDMA: + case TelephonyManager.NETWORK_TYPE_1xRTT: + return TelephonyManager.NETWORK_TYPE_GSM; + case TelephonyManager.NETWORK_TYPE_EVDO_0: + case TelephonyManager.NETWORK_TYPE_EVDO_A: + case TelephonyManager.NETWORK_TYPE_EVDO_B: + case TelephonyManager.NETWORK_TYPE_EHRPD: + case TelephonyManager.NETWORK_TYPE_UMTS: + case TelephonyManager.NETWORK_TYPE_HSDPA: + case TelephonyManager.NETWORK_TYPE_HSUPA: + case TelephonyManager.NETWORK_TYPE_HSPA: + case TelephonyManager.NETWORK_TYPE_HSPAP: + case TelephonyManager.NETWORK_TYPE_TD_SCDMA: + return TelephonyManager.NETWORK_TYPE_UMTS; + case TelephonyManager.NETWORK_TYPE_LTE: + case TelephonyManager.NETWORK_TYPE_IWLAN: + return TelephonyManager.NETWORK_TYPE_LTE; + case TelephonyManager.NETWORK_TYPE_NR: + return TelephonyManager.NETWORK_TYPE_NR; + default: + return TelephonyManager.NETWORK_TYPE_UNKNOWN; } } @@ -421,7 +504,8 @@ public class NetworkTemplate implements Parcelable { if (ident.mType == TYPE_WIMAX) { return true; } else { - return sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered); + return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered)) + && matchesCollapsedRatType(ident); } } 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 2b9e9fe81b1b..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,6 +528,30 @@ public final class RouteInfo implements Parcelable { } /** + * 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 static class RouteKey extends Pair<IpPrefix, InetAddress> { + RouteKey(@NonNull IpPrefix destination, @Nullable InetAddress gateway) { + super(destination, gateway); + } + } + + /** + * Get {@code RouteKey} of this {@code RouteInfo}. + * @return a {@code RouteKey} object. + * + * @hide + */ + @NonNull + public RouteKey getRouteKey() { + return new RouteKey(mDestination, mGateway); + } + + /** * Returns a hashcode for this <code>RouteInfo</code> object. */ public int hashCode() { diff --git a/core/java/android/net/TestNetworkManager.java b/core/java/android/net/TestNetworkManager.java index 4ac4a69e4b1b..a0a563b37025 100644 --- a/core/java/android/net/TestNetworkManager.java +++ b/core/java/android/net/TestNetworkManager.java @@ -16,6 +16,7 @@ package android.net; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.TestApi; import android.os.IBinder; import android.os.RemoteException; @@ -29,6 +30,18 @@ import com.android.internal.util.Preconditions; */ @TestApi public class TestNetworkManager { + /** + * Prefix for tun interfaces created by this class. + * @hide + */ + public static final String TEST_TUN_PREFIX = "testtun"; + + /** + * Prefix for tap interfaces created by this class. + * @hide + */ + public static final String TEST_TAP_PREFIX = "testtap"; + @NonNull private static final String TAG = TestNetworkManager.class.getSimpleName(); @NonNull private final ITestNetworkManager mService; @@ -53,6 +66,19 @@ public class TestNetworkManager { } } + private void setupTestNetwork( + @NonNull String iface, + @Nullable LinkProperties lp, + boolean isMetered, + @NonNull int[] administratorUids, + @NonNull IBinder binder) { + try { + mService.setupTestNetwork(iface, lp, isMetered, administratorUids, binder); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Sets up a capability-limited, testing-only network for a given interface * @@ -66,11 +92,7 @@ public class TestNetworkManager { public void setupTestNetwork( @NonNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder) { Preconditions.checkNotNull(lp, "Invalid LinkProperties"); - try { - mService.setupTestNetwork(lp.getInterfaceName(), lp, isMetered, binder); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + setupTestNetwork(lp.getInterfaceName(), lp, isMetered, new int[0], binder); } /** @@ -82,11 +104,21 @@ public class TestNetworkManager { */ @TestApi public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) { - try { - mService.setupTestNetwork(iface, null, true, binder); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + setupTestNetwork(iface, null, true, new int[0], binder); + } + + /** + * Sets up a capability-limited, testing-only network for a given interface with the given + * administrator UIDs. + * + * @param iface the name of the interface to be used for the Network LinkProperties. + * @param administratorUids The administrator UIDs to be used for the test-only network + * @param binder A binder object guarding the lifecycle of this test network. + * @hide + */ + public void setupTestNetwork( + @NonNull String iface, @NonNull int[] administratorUids, @NonNull IBinder binder) { + setupTestNetwork(iface, null, true, administratorUids, binder); } /** 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/net/netstats/provider/AbstractNetworkStatsProvider.java b/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java deleted file mode 100644 index 740aa92ad484..000000000000 --- a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.netstats.provider; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.net.NetworkStats; - -/** - * A base class that allows external modules to implement a custom network statistics provider. - * @hide - */ -@SystemApi -public abstract class AbstractNetworkStatsProvider { - /** - * A value used by {@link #setLimit} and {@link #setAlert} indicates there is no limit. - */ - public static final int QUOTA_UNLIMITED = -1; - - /** - * Called by {@code NetworkStatsService} when global polling is needed. Custom - * implementation of providers MUST respond to it by calling - * {@link NetworkStatsProviderCallback#onStatsUpdated} within one minute. Responding - * later than this may cause the stats to be dropped. - * - * @param token a positive number identifying the new state of the system under which - * {@link NetworkStats} have to be gathered from now on. When this is called, - * custom implementations of providers MUST report the latest stats with the - * previous token, under which stats were being gathered so far. - */ - public abstract void requestStatsUpdate(int token); - - /** - * Called by {@code NetworkStatsService} when setting the interface quota for the specified - * upstream interface. When this is called, the custom implementation should block all egress - * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have - * been reached, and MUST respond to it by calling - * {@link NetworkStatsProviderCallback#onLimitReached()}. - * - * @param iface the interface requiring the operation. - * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting - * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. - */ - public abstract void setLimit(@NonNull String iface, long quotaBytes); - - /** - * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations - * MUST call {@link NetworkStatsProviderCallback#onAlertReached()} when {@code quotaBytes} bytes - * have been reached. Unlike {@link #setLimit(String, long)}, the custom implementation should - * not block all egress packets. - * - * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting - * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert. - */ - public abstract void setAlert(long quotaBytes); -} diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl index 55b3d4edb157..4078b249218c 100644 --- a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl +++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl @@ -22,7 +22,7 @@ package android.net.netstats.provider; * @hide */ oneway interface INetworkStatsProvider { - void requestStatsUpdate(int token); - void setLimit(String iface, long quotaBytes); - void setAlert(long quotaBytes); + void onRequestStatsUpdate(int token); + void onSetLimit(String iface, long quotaBytes); + void onSetAlert(long quotaBytes); } diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl index 3ea9318f10d4..bd336dd348fe 100644 --- a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl +++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl @@ -24,8 +24,8 @@ import android.net.NetworkStats; * @hide */ oneway interface INetworkStatsProviderCallback { - void onStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats); - void onAlertReached(); - void onLimitReached(); + void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats); + void notifyAlertReached(); + void notifyLimitReached(); void unregister(); } diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java new file mode 100644 index 000000000000..7639d2244cfe --- /dev/null +++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java @@ -0,0 +1,195 @@ +/* + * 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.netstats.provider; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.net.NetworkStats; +import android.os.RemoteException; + +/** + * A base class that allows external modules to implement a custom network statistics provider. + * @hide + */ +@SystemApi +public abstract class NetworkStatsProvider { + /** + * A value used by {@link #onSetLimit} and {@link #onSetAlert} indicates there is no limit. + */ + public static final int QUOTA_UNLIMITED = -1; + + @NonNull private final INetworkStatsProvider mProviderBinder = + new INetworkStatsProvider.Stub() { + + @Override + public void onRequestStatsUpdate(int token) { + NetworkStatsProvider.this.onRequestStatsUpdate(token); + } + + @Override + public void onSetLimit(String iface, long quotaBytes) { + NetworkStatsProvider.this.onSetLimit(iface, quotaBytes); + } + + @Override + public void onSetAlert(long quotaBytes) { + NetworkStatsProvider.this.onSetAlert(quotaBytes); + } + }; + + // The binder given by the service when successfully registering. Only null before registering, + // never null once non-null. + @Nullable + private INetworkStatsProviderCallback mProviderCbBinder; + + /** + * Return the binder invoked by the service and redirect function calls to the overridden + * methods. + * @hide + */ + @NonNull + public INetworkStatsProvider getProviderBinder() { + return mProviderBinder; + } + + /** + * Store the binder that was returned by the service when successfully registering. Note that + * the provider cannot be re-registered. Hence this method can only be called once per provider. + * + * @hide + */ + public void setProviderCallbackBinder(@NonNull INetworkStatsProviderCallback binder) { + if (mProviderCbBinder != null) { + throw new IllegalArgumentException("provider is already registered"); + } + mProviderCbBinder = binder; + } + + /** + * Get the binder that was returned by the service when successfully registering. Or null if the + * provider was never registered. + * + * @hide + */ + @Nullable + public INetworkStatsProviderCallback getProviderCallbackBinder() { + return mProviderCbBinder; + } + + /** + * Get the binder that was returned by the service when successfully registering. Throw an + * {@link IllegalStateException} if the provider is not registered. + * + * @hide + */ + @NonNull + public INetworkStatsProviderCallback getProviderCallbackBinderOrThrow() { + if (mProviderCbBinder == null) { + throw new IllegalStateException("the provider is not registered"); + } + return mProviderCbBinder; + } + + /** + * Notify the system of new network statistics. + * + * Send the network statistics recorded since the last call to {@link #notifyStatsUpdated}. Must + * be called as soon as possible after {@link NetworkStatsProvider#onRequestStatsUpdate(int)} + * being called. Responding later increases the probability stats will be dropped. The + * provider can also call this whenever it wants to reports new stats for any reason. + * Note that the system will not necessarily immediately propagate the statistics to + * reflect the update. + * + * @param token the token under which these stats were gathered. Providers can call this method + * with the current token as often as they want, until the token changes. + * {@see NetworkStatsProvider#onRequestStatsUpdate()} + * @param ifaceStats the {@link NetworkStats} per interface to be reported. + * The provider should not include any traffic that is already counted by + * kernel interface counters. + * @param uidStats the same stats as above, but counts {@link NetworkStats} + * per uid. + */ + public void notifyStatsUpdated(int token, @NonNull NetworkStats ifaceStats, + @NonNull NetworkStats uidStats) { + try { + getProviderCallbackBinderOrThrow().notifyStatsUpdated(token, ifaceStats, uidStats); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@code onSetAlert} has been reached. + */ + public void notifyAlertReached() { + try { + getProviderCallbackBinderOrThrow().notifyAlertReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@code onSetLimit} has been reached. + */ + public void notifyLimitReached() { + try { + getProviderCallbackBinderOrThrow().notifyLimitReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Called by {@code NetworkStatsService} when it requires to know updated stats. + * The provider MUST respond by calling {@link #notifyStatsUpdated} as soon as possible. + * Responding later increases the probability stats will be dropped. Memory allowing, the + * system will try to take stats into account up to one minute after calling + * {@link #onRequestStatsUpdate}. + * + * @param token a positive number identifying the new state of the system under which + * {@link NetworkStats} have to be gathered from now on. When this is called, + * custom implementations of providers MUST tally and report the latest stats with + * the previous token, under which stats were being gathered so far. + */ + public abstract void onRequestStatsUpdate(int token); + + /** + * Called by {@code NetworkStatsService} when setting the interface quota for the specified + * upstream interface. When this is called, the custom implementation should block all egress + * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have + * been reached, and MUST respond to it by calling + * {@link NetworkStatsProvider#notifyLimitReached()}. + * + * @param iface the interface requiring the operation. + * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. + */ + public abstract void onSetLimit(@NonNull String iface, long quotaBytes); + + /** + * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations + * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes + * have been reached. Unlike {@link #onSetLimit(String, long)}, the custom implementation should + * not block all egress packets. + * + * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert. + */ + public abstract void onSetAlert(long quotaBytes); +} diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java b/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java deleted file mode 100644 index e17a8eee7ff0..000000000000 --- a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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.netstats.provider; - -import android.annotation.NonNull; -import android.annotation.SuppressLint; -import android.annotation.SystemApi; -import android.net.NetworkStats; -import android.os.RemoteException; - -/** - * A callback class that allows callers to report events to the system. - * @hide - */ -@SystemApi -@SuppressLint("CallbackMethodName") -public class NetworkStatsProviderCallback { - @NonNull private final INetworkStatsProviderCallback mBinder; - - /** @hide */ - public NetworkStatsProviderCallback(@NonNull INetworkStatsProviderCallback binder) { - mBinder = binder; - } - - /** - * Notify the system of new network statistics. - * - * Send the network statistics recorded since the last call to {@link #onStatsUpdated}. Must be - * called within one minute of {@link AbstractNetworkStatsProvider#requestStatsUpdate(int)} - * being called. The provider can also call this whenever it wants to reports new stats for any - * reason. Note that the system will not necessarily immediately propagate the statistics to - * reflect the update. - * - * @param token the token under which these stats were gathered. Providers can call this method - * with the current token as often as they want, until the token changes. - * {@see AbstractNetworkStatsProvider#requestStatsUpdate()} - * @param ifaceStats the {@link NetworkStats} per interface to be reported. - * The provider should not include any traffic that is already counted by - * kernel interface counters. - * @param uidStats the same stats as above, but counts {@link NetworkStats} - * per uid. - */ - public void onStatsUpdated(int token, @NonNull NetworkStats ifaceStats, - @NonNull NetworkStats uidStats) { - try { - mBinder.onStatsUpdated(token, ifaceStats, uidStats); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } - } - - /** - * Notify system that the quota set by {@code setAlert} has been reached. - */ - public void onAlertReached() { - try { - mBinder.onAlertReached(); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } - } - - /** - * Notify system that the quota set by {@code setLimit} has been reached. - */ - public void onLimitReached() { - try { - mBinder.onLimitReached(); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } - } - - /** - * Unregister the provider and the referencing callback. - */ - public void unregister() { - try { - mBinder.unregister(); - } catch (RemoteException e) { - // Ignore error. - } - } -} diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java b/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java deleted file mode 100644 index 4bf7c9bc086e..000000000000 --- a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.netstats.provider; - -import android.annotation.NonNull; - -/** - * A wrapper class of {@link INetworkStatsProvider} that hides the binder interface from exposing - * to outer world. - * - * @hide - */ -public class NetworkStatsProviderWrapper extends INetworkStatsProvider.Stub { - @NonNull final AbstractNetworkStatsProvider mProvider; - - public NetworkStatsProviderWrapper(AbstractNetworkStatsProvider provider) { - mProvider = provider; - } - - @Override - public void requestStatsUpdate(int token) { - mProvider.requestStatsUpdate(token); - } - - @Override - public void setLimit(@NonNull String iface, long quotaBytes) { - mProvider.setLimit(iface, quotaBytes); - } - - @Override - public void setAlert(long quotaBytes) { - mProvider.setAlert(quotaBytes); - } -} diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java index e9ea99f84f90..696708408c22 100644 --- a/core/java/android/net/util/SocketUtils.java +++ b/core/java/android/net/util/SocketUtils.java @@ -66,6 +66,10 @@ public final class SocketUtils { /** * Make socket address that packet sockets can bind to. + * + * @param protocol the layer 2 protocol of the packets to receive. One of the {@code ETH_P_*} + * constants in {@link android.system.OsConstants}. + * @param ifIndex the interface index on which packets will be received. */ @NonNull public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex) { @@ -78,6 +82,9 @@ public final class SocketUtils { /** * Make a socket address that packet socket can send packets to. * @deprecated Use {@link #makePacketSocketAddress(int, int, byte[])} instead. + * + * @param ifIndex the interface index on which packets will be sent. + * @param hwAddr the hardware address to which packets will be sent. */ @Deprecated @NonNull @@ -89,7 +96,12 @@ public final class SocketUtils { } /** - * Make a socket address that packet socket can send packets to. + * Make a socket address that a packet socket can send packets to. + * + * @param protocol the layer 2 protocol of the packets to send. One of the {@code ETH_P_*} + * constants in {@link android.system.OsConstants}. + * @param ifIndex the interface index on which packets will be sent. + * @param hwAddr the hardware address to which packets will be sent. */ @NonNull public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex, diff --git a/core/java/android/os/ConfigUpdate.java b/core/java/android/os/ConfigUpdate.java index 9c999b202797..a28f5fbaba0b 100644 --- a/core/java/android/os/ConfigUpdate.java +++ b/core/java/android/os/ConfigUpdate.java @@ -16,6 +16,9 @@ package android.os; +import android.annotation.RequiresPermission; +import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; /** @@ -114,20 +117,37 @@ public final class ConfigUpdate { = "android.os.action.UPDATE_CARRIER_ID_DB"; /** - * Broadcast intent action indicating that the updated emergency number database is available. - * <p>Extra: "VERSION" the numeric version of the new data. Devices should only install if the - * update version is newer than the current one. - * <p>Extra: "REQUIRED_HASH" the hash of the current update data. - * <p>Input: {@link android.content.Intent#getData} is URI of downloaded emergency number file. - * Devices should pick up the downloaded file and persist to the database - * {@code com.android.internal.telephony.emergency.EmergencyNumberTracker}. + * Update the emergency number database into the devices. + * <p>Extra: {@link #EXTRA_VERSION} the numeric version of the database. + * <p>Extra: {@link #EXTRA_REQUIRED_HASH} the hash of the database. + * <p>Input: {@link android.content.Intent#getData} the URI to download emergency number + * database. * * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.UPDATE_CONFIG) + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB = "android.os.action.UPDATE_EMERGENCY_NUMBER_DB"; + /** + * An integer to indicate the numeric version of the new data. Devices should only install + * if the update version is newer than the current one. + * + * @hide + */ + @SystemApi + public static final String EXTRA_VERSION = "android.os.extra.VERSION"; + + /** + * A string to indicate the hash of the data. + * + * @hide + */ + @SystemApi + public static final String EXTRA_REQUIRED_HASH = "android.os.extra.REQUIRED_HASH"; + private ConfigUpdate() { } } diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index fa7404c5b139..51df971c6e50 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -792,6 +792,17 @@ public class Handler { } /** + * Remove any pending posts of messages with code 'what' and whose obj is + * 'object' that are in the message queue. If <var>object</var> is null, + * all messages will be removed. + * + *@hide + */ + public final void removeEqualMessages(int what, @Nullable Object object) { + mQueue.removeEqualMessages(this, what, object); + } + + /** * Remove any pending posts of callbacks and sent messages whose * <var>obj</var> is <var>token</var>. If <var>token</var> is null, * all callbacks and messages will be removed. @@ -801,6 +812,16 @@ public class Handler { } /** + * Remove any pending posts of callbacks and sent messages whose + * <var>obj</var> is <var>token</var>. If <var>token</var> is null, + * all callbacks and messages will be removed. + * + *@hide + */ + public final void removeCallbacksAndEqualMessages(@Nullable Object token) { + mQueue.removeCallbacksAndEqualMessages(this, token); + } + /** * Check if there are any pending posts of messages with code 'what' in * the message queue. */ @@ -825,6 +846,16 @@ public class Handler { } /** + * Check if there are any pending posts of messages with code 'what' and + * whose obj is 'object' in the message queue. + * + *@hide + */ + public final boolean hasEqualMessages(int what, @Nullable Object object) { + return mQueue.hasEqualMessages(this, what, object); + } + + /** * Check if there are any pending posts of messages with callback r in * the message queue. */ diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index 4e910577dd49..529350461cd8 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -617,6 +617,23 @@ public final class MessageQueue { } } + boolean hasEqualMessages(Handler h, int what, Object object) { + if (h == null) { + return false; + } + + synchronized (this) { + Message p = mMessages; + while (p != null) { + if (p.target == h && p.what == what && (object == null || object.equals(p.obj))) { + return true; + } + p = p.next; + } + return false; + } + } + @UnsupportedAppUsage boolean hasMessages(Handler h, Runnable r, Object object) { if (h == null) { @@ -686,6 +703,40 @@ public final class MessageQueue { } } + void removeEqualMessages(Handler h, int what, Object object) { + if (h == null) { + return; + } + + synchronized (this) { + Message p = mMessages; + + // Remove all messages at front. + while (p != null && p.target == h && p.what == what + && (object == null || object.equals(p.obj))) { + Message n = p.next; + mMessages = n; + p.recycleUnchecked(); + p = n; + } + + // Remove all messages after front. + while (p != null) { + Message n = p.next; + if (n != null) { + if (n.target == h && n.what == what + && (object == null || object.equals(n.obj))) { + Message nn = n.next; + n.recycleUnchecked(); + p.next = nn; + continue; + } + } + p = n; + } + } + } + void removeMessages(Handler h, Runnable r, Object object) { if (h == null || r == null) { return; @@ -720,6 +771,41 @@ public final class MessageQueue { } } + void removeEqualMessages(Handler h, Runnable r, Object object) { + if (h == null || r == null) { + return; + } + + synchronized (this) { + Message p = mMessages; + + // Remove all messages at front. + while (p != null && p.target == h && p.callback == r + && (object == null || object.equals(p.obj))) { + Message n = p.next; + mMessages = n; + p.recycleUnchecked(); + p = n; + } + + // Remove all messages after front. + while (p != null) { + Message n = p.next; + if (n != null) { + if (n.target == h && n.callback == r + && (object == null || object.equals(n.obj))) { + Message nn = n.next; + n.recycleUnchecked(); + p.next = nn; + continue; + } + } + p = n; + } + } + } + + void removeCallbacksAndMessages(Handler h, Object object) { if (h == null) { return; @@ -753,6 +839,39 @@ public final class MessageQueue { } } + void removeCallbacksAndEqualMessages(Handler h, Object object) { + if (h == null) { + return; + } + + synchronized (this) { + Message p = mMessages; + + // Remove all messages at front. + while (p != null && p.target == h + && (object == null || object.equals(p.obj))) { + Message n = p.next; + mMessages = n; + p.recycleUnchecked(); + p = n; + } + + // Remove all messages after front. + while (p != null) { + Message n = p.next; + if (n != null) { + if (n.target == h && (object == null || object.equals(n.obj))) { + Message nn = n.next; + n.recycleUnchecked(); + p.next = nn; + continue; + } + } + p = n; + } + } + } + private void removeAllMessagesLocked() { Message p = mMessages; while (p != null) { 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/provider/BlockedNumberContract.java b/core/java/android/provider/BlockedNumberContract.java index 1eb76648f7b2..dd2ea81d747b 100644 --- a/core/java/android/provider/BlockedNumberContract.java +++ b/core/java/android/provider/BlockedNumberContract.java @@ -16,7 +16,6 @@ package android.provider; import android.annotation.IntDef; -import android.annotation.SystemApi; import android.annotation.WorkerThread; import android.content.Context; import android.net.Uri; @@ -240,7 +239,6 @@ public class BlockedNumberContract { * blocked. * @hide */ - @SystemApi public static final int STATUS_NOT_BLOCKED = 0; /** @@ -248,7 +246,6 @@ public class BlockedNumberContract { * because it is in the list of blocked numbers maintained by the provider. * @hide */ - @SystemApi public static final int STATUS_BLOCKED_IN_LIST = 1; /** @@ -256,7 +253,6 @@ public class BlockedNumberContract { * because it is from a restricted number. * @hide */ - @SystemApi public static final int STATUS_BLOCKED_RESTRICTED = 2; /** @@ -264,7 +260,6 @@ public class BlockedNumberContract { * because it is from an unknown number. * @hide */ - @SystemApi public static final int STATUS_BLOCKED_UNKNOWN_NUMBER = 3; /** @@ -272,7 +267,6 @@ public class BlockedNumberContract { * because it is from a pay phone. * @hide */ - @SystemApi public static final int STATUS_BLOCKED_PAYPHONE = 4; /** @@ -280,14 +274,12 @@ public class BlockedNumberContract { * because it is from a number not in the users contacts. * @hide */ - @SystemApi public static final int STATUS_BLOCKED_NOT_IN_CONTACTS = 5; /** * Integer reason indicating whether a call was blocked, and if so why. * @hide */ - @SystemApi public static final String RES_BLOCK_STATUS = "block_status"; /** @hide */ @@ -298,31 +290,6 @@ public class BlockedNumberContract { "can_current_user_block_numbers"; /** @hide */ - @SystemApi - public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact"; - - /** @hide */ - public static final String METHOD_END_BLOCK_SUPPRESSION = "end_block_suppression"; - - /** @hide */ - @SystemApi - public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number"; - - /** @hide */ - public static final String METHOD_GET_BLOCK_SUPPRESSION_STATUS = - "get_block_suppression_status"; - - /** @hide */ - public static final String METHOD_SHOULD_SHOW_EMERGENCY_CALL_NOTIFICATION = - "should_show_emergency_call_notification"; - - /** @hide */ - public static final String METHOD_GET_ENHANCED_BLOCK_SETTING = "get_enhanced_block_setting"; - - /** @hide */ - public static final String METHOD_SET_ENHANCED_BLOCK_SETTING = "set_enhanced_block_setting"; - - /** @hide */ public static final String RES_CAN_BLOCK_NUMBERS = "can_block"; /** @hide */ @@ -439,11 +406,26 @@ public class BlockedNumberContract { public static final String ACTION_BLOCK_SUPPRESSION_STATE_CHANGED = "android.provider.action.BLOCK_SUPPRESSION_STATE_CHANGED"; + public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact"; + + public static final String METHOD_END_BLOCK_SUPPRESSION = "end_block_suppression"; + + public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number"; + + public static final String METHOD_GET_BLOCK_SUPPRESSION_STATUS = + "get_block_suppression_status"; + + public static final String METHOD_SHOULD_SHOW_EMERGENCY_CALL_NOTIFICATION = + "should_show_emergency_call_notification"; + public static final String RES_IS_BLOCKING_SUPPRESSED = "blocking_suppressed"; public static final String RES_BLOCKING_SUPPRESSED_UNTIL_TIMESTAMP = "blocking_suppressed_until_timestamp"; + public static final String METHOD_GET_ENHANCED_BLOCK_SETTING = "get_enhanced_block_setting"; + public static final String METHOD_SET_ENHANCED_BLOCK_SETTING = "set_enhanced_block_setting"; + /* Preference key of block numbers not in contacts setting. */ public static final String ENHANCED_SETTING_KEY_BLOCK_UNREGISTERED = "block_numbers_not_in_contacts_setting"; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index d6869c549dcf..de30bced50fc 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -10197,6 +10197,8 @@ public final class Settings { public static final String NETSTATS_SAMPLE_ENABLED = "netstats_sample_enabled"; /** {@hide} */ public static final String NETSTATS_AUGMENT_ENABLED = "netstats_augment_enabled"; + /** {@hide} */ + public static final String NETSTATS_COMBINE_SUBTYPE_ENABLED = "netstats_combine_subtype_enabled"; /** {@hide} */ public static final String NETSTATS_DEV_BUCKET_DURATION = "netstats_dev_bucket_duration"; @@ -13407,12 +13409,12 @@ public final class Settings { * <p> * Type: int (0 for false, 1 for true) * @hide - * @deprecated Use {@link android.provider.Telephony.SimInfo#ENHANCED_4G_MODE_ENABLED} - * instead. + * @deprecated Use + * {@link android.provider.Telephony.SimInfo#COLUMN_ENHANCED_4G_MODE_ENABLED} instead. */ @Deprecated public static final String ENHANCED_4G_MODE_ENABLED = - Telephony.SimInfo.ENHANCED_4G_MODE_ENABLED; + Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED; /** * Whether VT (Video Telephony over IMS) is enabled @@ -13420,10 +13422,10 @@ public final class Settings { * Type: int (0 for false, 1 for true) * * @hide - * @deprecated Use {@link android.provider.Telephony.SimInfo#VT_IMS_ENABLED} instead. + * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_VT_IMS_ENABLED} instead. */ @Deprecated - public static final String VT_IMS_ENABLED = Telephony.SimInfo.VT_IMS_ENABLED; + public static final String VT_IMS_ENABLED = Telephony.SimInfo.COLUMN_VT_IMS_ENABLED; /** * Whether WFC is enabled @@ -13431,10 +13433,11 @@ public final class Settings { * Type: int (0 for false, 1 for true) * * @hide - * @deprecated Use {@link android.provider.Telephony.SimInfo#WFC_IMS_ENABLED} instead. + * @deprecated Use + * {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_ENABLED} instead. */ @Deprecated - public static final String WFC_IMS_ENABLED = Telephony.SimInfo.WFC_IMS_ENABLED; + public static final String WFC_IMS_ENABLED = Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED; /** * WFC mode on home/non-roaming network. @@ -13442,10 +13445,10 @@ public final class Settings { * Type: int - 2=Wi-Fi preferred, 1=Cellular preferred, 0=Wi-Fi only * * @hide - * @deprecated Use {@link android.provider.Telephony.SimInfo#WFC_IMS_MODE} instead. + * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_MODE} instead. */ @Deprecated - public static final String WFC_IMS_MODE = Telephony.SimInfo.WFC_IMS_MODE; + public static final String WFC_IMS_MODE = Telephony.SimInfo.COLUMN_WFC_IMS_MODE; /** * WFC mode on roaming network. @@ -13453,11 +13456,12 @@ public final class Settings { * Type: int - see {@link #WFC_IMS_MODE} for values * * @hide - * @deprecated Use {@link android.provider.Telephony.SimInfo#WFC_IMS_ROAMING_MODE} + * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_ROAMING_MODE} * instead. */ @Deprecated - public static final String WFC_IMS_ROAMING_MODE = Telephony.SimInfo.WFC_IMS_ROAMING_MODE; + public static final String WFC_IMS_ROAMING_MODE = + Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE; /** * Whether WFC roaming is enabled @@ -13465,12 +13469,12 @@ public final class Settings { * Type: int (0 for false, 1 for true) * * @hide - * @deprecated Use {@link android.provider.Telephony.SimInfo#WFC_IMS_ROAMING_ENABLED} + * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_ROAMING_ENABLED} * instead */ @Deprecated public static final String WFC_IMS_ROAMING_ENABLED = - Telephony.SimInfo.WFC_IMS_ROAMING_ENABLED; + Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED; /** * Whether user can enable/disable LTE as a preferred network. A carrier might control diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index a897a8e4994a..db17d73a1cb9 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -1365,7 +1365,6 @@ public final class Telephony { * Base column for the table that contain Carrier Public key. * @hide */ - @SystemApi public interface CarrierColumns extends BaseColumns { /** @@ -4358,6 +4357,7 @@ public final class Telephony { * Indicates that whether the message has been broadcasted to the application. * <P>Type: BOOLEAN</P> */ + // TODO: deprecate this in S. public static final String MESSAGE_BROADCASTED = "message_broadcasted"; /** @@ -4864,7 +4864,6 @@ public final class Telephony { * Contains mappings between matching rules with carrier id for all carriers. * @hide */ - @SystemApi public static final class All implements BaseColumns { /** @@ -4940,7 +4939,6 @@ public final class Telephony { * Contains SIM Information * @hide */ - @SystemApi public static final class SimInfo { /** * Not instantiable. @@ -4950,6 +4948,7 @@ public final class Telephony { /** * The {@code content://} style URI for this provider. + * @hide */ @NonNull public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo"); @@ -4957,25 +4956,32 @@ public final class Telephony { /** * TelephonyProvider unique key column name is the subscription id. * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String UNIQUE_KEY_SUBSCRIPTION_ID = "_id"; + public static final String COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID = "_id"; /** * TelephonyProvider column name for a unique identifier for the subscription within the * specific subscription type. For example, it contains SIM ICC Identifier subscriptions * on Local SIMs. and Mac-address for Remote-SIM Subscriptions for Bluetooth devices. * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String ICC_ID = "icc_id"; + public static final String COLUMN_ICC_ID = "icc_id"; /** * TelephonyProvider column name for user SIM_SlOT_INDEX * <P>Type: INTEGER (int)</P> + * + * @hide */ - public static final String SIM_SLOT_INDEX = "sim_id"; + public static final String COLUMN_SIM_SLOT_INDEX = "sim_id"; /** * SIM is not inserted + * @hide */ public static final int SIM_NOT_INSERTED = -1; @@ -4984,14 +4990,18 @@ public final class Telephony { * <P>Type: INTEGER (int)</P> {@link #SUBSCRIPTION_TYPE_LOCAL_SIM} for Local-SIM * Subscriptions, {@link #SUBSCRIPTION_TYPE_REMOTE_SIM} for Remote-SIM Subscriptions. * Default value is 0. + * + * @hide */ - public static final String SUBSCRIPTION_TYPE = "subscription_type"; + public static final String COLUMN_SUBSCRIPTION_TYPE = "subscription_type"; /** * This constant is to designate a subscription as a Local-SIM Subscription. * <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on * the device. * </p> + * + * @hide */ public static final int SUBSCRIPTION_TYPE_LOCAL_SIM = 0; @@ -5018,6 +5028,8 @@ public final class Telephony { * phone; i.e., new Remote-SIM subscription treats the reconnected phone as a Remote-SIM * that was never seen before. * </p> + * + * @hide */ public static final int SUBSCRIPTION_TYPE_REMOTE_SIM = 1; @@ -5030,71 +5042,89 @@ public final class Telephony { * subscription and while is in voice call. * * Default value is empty string. + * + * @hide */ - public static final String DATA_ENABLED_OVERRIDE_RULES = "data_enabled_override_rules"; + public static final String COLUMN_DATA_ENABLED_OVERRIDE_RULES = + "data_enabled_override_rules"; /** * TelephonyProvider column name for user displayed name. * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String DISPLAY_NAME = "display_name"; + public static final String COLUMN_DISPLAY_NAME = "display_name"; /** * TelephonyProvider column name for the service provider name for the SIM. * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String CARRIER_NAME = "carrier_name"; + public static final String COLUMN_CARRIER_NAME = "carrier_name"; /** * TelephonyProvider column name for source of the user displayed name. * <P>Type: INT (int)</P> with one of the NAME_SOURCE_XXXX values below + * + * @hide */ - public static final String NAME_SOURCE = "name_source"; + public static final String COLUMN_NAME_SOURCE = "name_source"; - /** The name_source is the default, which is from the carrier id. */ - public static final int NAME_SOURCE_DEFAULT = 0; + /** The name_source is from the carrier id. {@hide} */ + public static final int NAME_SOURCE_CARRIER_ID = 0; /** * The name_source is from SIM EF_SPN. + * @hide */ public static final int NAME_SOURCE_SIM_SPN = 1; /** * The name_source is from user input + * @hide */ public static final int NAME_SOURCE_USER_INPUT = 2; /** * The name_source is carrier (carrier app, carrier config, etc.) + * @hide */ public static final int NAME_SOURCE_CARRIER = 3; /** * The name_source is from SIM EF_PNN. + * @hide */ public static final int NAME_SOURCE_SIM_PNN = 4; /** * TelephonyProvider column name for the color of a SIM. * <P>Type: INTEGER (int)</P> + * + * @hide */ - public static final String COLOR = "color"; + public static final String COLUMN_COLOR = "color"; - /** TelephonyProvider column name for the default color of a SIM {@hide} */ + /** The default color of a SIM {@hide} */ public static final int COLOR_DEFAULT = 0; /** * TelephonyProvider column name for the phone number of a SIM. * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String NUMBER = "number"; + public static final String COLUMN_NUMBER = "number"; /** * TelephonyProvider column name for the number display format of a SIM. * <P>Type: INTEGER (int)</P> + * * @hide */ - public static final String DISPLAY_NUMBER_FORMAT = "display_number_format"; + public static final String COLUMN_DISPLAY_NUMBER_FORMAT = "display_number_format"; /** * TelephonyProvider column name for the default display format of a SIM @@ -5105,73 +5135,89 @@ public final class Telephony { /** * TelephonyProvider column name for whether data roaming is enabled. * <P>Type: INTEGER (int)</P> + * + * @hide */ - public static final String DATA_ROAMING = "data_roaming"; + public static final String COLUMN_DATA_ROAMING = "data_roaming"; - /** Indicates that data roaming is enabled for a subscription */ + /** Indicates that data roaming is enabled for a subscription {@hide} */ public static final int DATA_ROAMING_ENABLE = 1; - /** Indicates that data roaming is disabled for a subscription */ + /** Indicates that data roaming is disabled for a subscription {@hide} */ public static final int DATA_ROAMING_DISABLE = 0; - /** TelephonyProvider column name for default data roaming setting: disable */ - public static final int DATA_ROAMING_DEFAULT = DATA_ROAMING_DISABLE; - /** * TelephonyProvider column name for subscription carrier id. * @see TelephonyManager#getSimCarrierId() * <p>Type: INTEGER (int) </p> + * + * @hide */ - public static final String CARRIER_ID = "carrier_id"; + public static final String COLUMN_CARRIER_ID = "carrier_id"; /** * A comma-separated list of EHPLMNs associated with the subscription * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String EHPLMNS = "ehplmns"; + public static final String COLUMN_EHPLMNS = "ehplmns"; /** * A comma-separated list of HPLMNs associated with the subscription * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String HPLMNS = "hplmns"; + public static final String COLUMN_HPLMNS = "hplmns"; /** * TelephonyProvider column name for the MCC associated with a SIM, stored as a string. * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String MCC_STRING = "mcc_string"; + public static final String COLUMN_MCC_STRING = "mcc_string"; /** * TelephonyProvider column name for the MNC associated with a SIM, stored as a string. * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String MNC_STRING = "mnc_string"; + public static final String COLUMN_MNC_STRING = "mnc_string"; /** * TelephonyProvider column name for the MCC associated with a SIM. * <P>Type: INTEGER (int)</P> + * + * @hide */ - public static final String MCC = "mcc"; + public static final String COLUMN_MCC = "mcc"; /** * TelephonyProvider column name for the MNC associated with a SIM. * <P>Type: INTEGER (int)</P> + * + * @hide */ - public static final String MNC = "mnc"; + public static final String COLUMN_MNC = "mnc"; /** * TelephonyProvider column name for the iso country code associated with a SIM. * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String ISO_COUNTRY_CODE = "iso_country_code"; + public static final String COLUMN_ISO_COUNTRY_CODE = "iso_country_code"; /** * TelephonyProvider column name for the sim provisioning status associated with a SIM. * <P>Type: INTEGER (int)</P> + * * @hide */ - public static final String SIM_PROVISIONING_STATUS = "sim_provisioning_status"; + public static final String COLUMN_SIM_PROVISIONING_STATUS = "sim_provisioning_status"; /** The sim is provisioned {@hide} */ public static final int SIM_PROVISIONED = 0; @@ -5180,147 +5226,174 @@ public final class Telephony { * TelephonyProvider column name for whether a subscription is embedded (that is, present on * an eSIM). * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded. + * + * @hide */ - public static final String IS_EMBEDDED = "is_embedded"; + public static final String COLUMN_IS_EMBEDDED = "is_embedded"; /** * TelephonyProvider column name for SIM card identifier. For UICC card it is the ICCID of * the current enabled profile on the card, while for eUICC card it is the EID of the card. * <P>Type: TEXT (String)</P> + * + * @hide */ - public static final String CARD_ID = "card_id"; + public static final String COLUMN_CARD_ID = "card_id"; /** * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from - * {@link UiccAccessRule#encodeRules}. Only present if {@link #IS_EMBEDDED} is 1. + * {@link UiccAccessRule#encodeRules}. Only present if {@link #COLUMN_IS_EMBEDDED} is 1. * <p>TYPE: BLOB + * + * @hide */ - public static final String ACCESS_RULES = "access_rules"; + public static final String COLUMN_ACCESS_RULES = "access_rules"; /** * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from * {@link UiccAccessRule#encodeRules} but for the rules that come from CarrierConfigs. * Only present if there are access rules in CarrierConfigs * <p>TYPE: BLOB + * + * @hide */ - public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS = + public static final String COLUMN_ACCESS_RULES_FROM_CARRIER_CONFIGS = "access_rules_from_carrier_configs"; /** * TelephonyProvider column name identifying whether an embedded subscription is on a * removable card. Such subscriptions are marked inaccessible as soon as the current card * is removed. Otherwise, they will remain accessible unless explicitly deleted. Only - * present if {@link #IS_EMBEDDED} is 1. + * present if {@link #COLUMN_IS_EMBEDDED} is 1. * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable. + * + * @hide */ - public static final String IS_REMOVABLE = "is_removable"; + public static final String COLUMN_IS_REMOVABLE = "is_removable"; - /** TelephonyProvider column name for extreme threat in CB settings */ - public static final String CB_EXTREME_THREAT_ALERT = "enable_cmas_extreme_threat_alerts"; + /** TelephonyProvider column name for extreme threat in CB settings {@hide} */ + public static final String COLUMN_CB_EXTREME_THREAT_ALERT = + "enable_cmas_extreme_threat_alerts"; - /** TelephonyProvider column name for severe threat in CB settings */ - public static final String CB_SEVERE_THREAT_ALERT = "enable_cmas_severe_threat_alerts"; + /** TelephonyProvider column name for severe threat in CB settings {@hide} */ + public static final String COLUMN_CB_SEVERE_THREAT_ALERT = + "enable_cmas_severe_threat_alerts"; - /** TelephonyProvider column name for amber alert in CB settings */ - public static final String CB_AMBER_ALERT = "enable_cmas_amber_alerts"; + /** TelephonyProvider column name for amber alert in CB settings {@hide} */ + public static final String COLUMN_CB_AMBER_ALERT = "enable_cmas_amber_alerts"; - /** TelephonyProvider column name for emergency alert in CB settings */ - public static final String CB_EMERGENCY_ALERT = "enable_emergency_alerts"; + /** TelephonyProvider column name for emergency alert in CB settings {@hide} */ + public static final String COLUMN_CB_EMERGENCY_ALERT = "enable_emergency_alerts"; - /** TelephonyProvider column name for alert sound duration in CB settings */ - public static final String CB_ALERT_SOUND_DURATION = "alert_sound_duration"; + /** TelephonyProvider column name for alert sound duration in CB settings {@hide} */ + public static final String COLUMN_CB_ALERT_SOUND_DURATION = "alert_sound_duration"; - /** TelephonyProvider column name for alert reminder interval in CB settings */ - public static final String CB_ALERT_REMINDER_INTERVAL = "alert_reminder_interval"; + /** TelephonyProvider column name for alert reminder interval in CB settings {@hide} */ + public static final String COLUMN_CB_ALERT_REMINDER_INTERVAL = "alert_reminder_interval"; - /** TelephonyProvider column name for enabling vibrate in CB settings */ - public static final String CB_ALERT_VIBRATE = "enable_alert_vibrate"; + /** TelephonyProvider column name for enabling vibrate in CB settings {@hide} */ + public static final String COLUMN_CB_ALERT_VIBRATE = "enable_alert_vibrate"; - /** TelephonyProvider column name for enabling alert speech in CB settings */ - public static final String CB_ALERT_SPEECH = "enable_alert_speech"; + /** TelephonyProvider column name for enabling alert speech in CB settings {@hide} */ + public static final String COLUMN_CB_ALERT_SPEECH = "enable_alert_speech"; - /** TelephonyProvider column name for ETWS test alert in CB settings */ - public static final String CB_ETWS_TEST_ALERT = "enable_etws_test_alerts"; + /** TelephonyProvider column name for ETWS test alert in CB settings {@hide} */ + public static final String COLUMN_CB_ETWS_TEST_ALERT = "enable_etws_test_alerts"; - /** TelephonyProvider column name for enable channel50 alert in CB settings */ - public static final String CB_CHANNEL_50_ALERT = "enable_channel_50_alerts"; + /** TelephonyProvider column name for enable channel50 alert in CB settings {@hide} */ + public static final String COLUMN_CB_CHANNEL_50_ALERT = "enable_channel_50_alerts"; - /** TelephonyProvider column name for CMAS test alert in CB settings */ - public static final String CB_CMAS_TEST_ALERT = "enable_cmas_test_alerts"; + /** TelephonyProvider column name for CMAS test alert in CB settings {@hide} */ + public static final String COLUMN_CB_CMAS_TEST_ALERT = "enable_cmas_test_alerts"; - /** TelephonyProvider column name for Opt out dialog in CB settings */ - public static final String CB_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog"; + /** TelephonyProvider column name for Opt out dialog in CB settings {@hide} */ + public static final String COLUMN_CB_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog"; /** * TelephonyProvider column name for enable Volte. * * If this setting is not initialized (set to -1) then we use the Carrier Config value * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}. + * + * @hide */ - public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled"; + public static final String COLUMN_ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled"; - /** TelephonyProvider column name for enable VT (Video Telephony over IMS) */ - public static final String VT_IMS_ENABLED = "vt_ims_enabled"; + /** TelephonyProvider column name for enable VT (Video Telephony over IMS) {@hide} */ + public static final String COLUMN_VT_IMS_ENABLED = "vt_ims_enabled"; - /** TelephonyProvider column name for enable Wifi calling */ - public static final String WFC_IMS_ENABLED = "wfc_ims_enabled"; + /** TelephonyProvider column name for enable Wifi calling {@hide} */ + public static final String COLUMN_WFC_IMS_ENABLED = "wfc_ims_enabled"; - /** TelephonyProvider column name for Wifi calling mode */ - public static final String WFC_IMS_MODE = "wfc_ims_mode"; + /** TelephonyProvider column name for Wifi calling mode {@hide} */ + public static final String COLUMN_WFC_IMS_MODE = "wfc_ims_mode"; - /** TelephonyProvider column name for Wifi calling mode in roaming */ - public static final String WFC_IMS_ROAMING_MODE = "wfc_ims_roaming_mode"; + /** TelephonyProvider column name for Wifi calling mode in roaming {@hide} */ + public static final String COLUMN_WFC_IMS_ROAMING_MODE = "wfc_ims_roaming_mode"; - /** TelephonyProvider column name for enable Wifi calling in roaming */ - public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled"; + /** TelephonyProvider column name for enable Wifi calling in roaming {@hide} */ + public static final String COLUMN_WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled"; /** - * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this - * subscription. + * TelephonyProvider column name for determining if the user has enabled IMS RCS User + * Capability Exchange (UCE) for this subscription. + * + * @hide */ - public static final String IMS_RCS_UCE_ENABLED = "ims_rcs_uce_enabled"; + public static final String COLUMN_IMS_RCS_UCE_ENABLED = "ims_rcs_uce_enabled"; /** * TelephonyProvider column name for whether a subscription is opportunistic, that is, * whether the network it connects to is limited in functionality or coverage. * For example, CBRS. * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic. + * + * @hide */ - public static final String IS_OPPORTUNISTIC = "is_opportunistic"; + public static final String COLUMN_IS_OPPORTUNISTIC = "is_opportunistic"; /** * TelephonyProvider column name for group ID. Subscriptions with same group ID * are considered bundled together, and should behave as a single subscription at * certain scenarios. + * + * @hide */ - public static final String GROUP_UUID = "group_uuid"; + public static final String COLUMN_GROUP_UUID = "group_uuid"; /** * TelephonyProvider column name for group owner. It's the package name who created * the subscription group. + * + * @hide */ - public static final String GROUP_OWNER = "group_owner"; + public static final String COLUMN_GROUP_OWNER = "group_owner"; /** * TelephonyProvider column name for whether a subscription is metered or not, that is, * whether the network it connects to charges for subscription or not. For example, paid * CBRS or unpaid. + * * @hide */ - public static final String IS_METERED = "is_metered"; + public static final String COLUMN_IS_METERED = "is_metered"; /** * TelephonyProvider column name for the profile class of a subscription - * Only present if {@link #IS_EMBEDDED} is 1. + * Only present if {@link #COLUMN_IS_EMBEDDED} is 1. * <P>Type: INTEGER (int)</P> + * + * @hide */ - public static final String PROFILE_CLASS = "profile_class"; + public static final String COLUMN_PROFILE_CLASS = "profile_class"; /** * A testing profile can be pre-loaded or downloaded onto * the eUICC and provides connectivity to test equipment * for the purpose of testing the device and the eUICC. It * is not intended to store any operator credentials. + * + * @hide */ public static final int PROFILE_CLASS_TESTING = 0; @@ -5328,6 +5401,8 @@ public final class Telephony { * A provisioning profile is pre-loaded onto the eUICC and * provides connectivity to a mobile network solely for the * purpose of provisioning profiles. + * + * @hide */ public static final int PROFILE_CLASS_PROVISIONING = 1; @@ -5335,6 +5410,8 @@ public final class Telephony { * An operational profile can be pre-loaded or downloaded * onto the eUICC and provides services provided by the * operator. + * + * @hide */ public static final int PROFILE_CLASS_OPERATIONAL = 2; @@ -5342,25 +5419,32 @@ public final class Telephony { * The profile class is unset. This occurs when profile class * info is not available. The subscription either has no profile * metadata or the profile metadata did not encode profile class. + * + * @hide */ public static final int PROFILE_CLASS_UNSET = -1; - /** Default profile class */ - public static final int PROFILE_CLASS_DEFAULT = PROFILE_CLASS_UNSET; - /** * IMSI (International Mobile Subscriber Identity). * <P>Type: TEXT </P> + * + * @hide */ - public static final String IMSI = "imsi"; + public static final String COLUMN_IMSI = "imsi"; - /** Whether uicc applications is set to be enabled or disabled. By default it's enabled. */ - public static final String UICC_APPLICATIONS_ENABLED = "uicc_applications_enabled"; + /** + * Whether uicc applications is set to be enabled or disabled. By default it's enabled. + * @hide + */ + public static final String COLUMN_UICC_APPLICATIONS_ENABLED = "uicc_applications_enabled"; /** * TelephonyProvider column name for allowed network types. Indicate which network types * are allowed. Default is -1. + * <P>Type: BIGINT (long) </P> + * + * @hide */ - public static final String ALLOWED_NETWORK_TYPES = "allowed_network_types"; + public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types"; } } diff --git a/core/java/android/se/omapi/Reader.java b/core/java/android/se/omapi/Reader.java index 7f68d9188650..90c934d189fa 100644 --- a/core/java/android/se/omapi/Reader.java +++ b/core/java/android/se/omapi/Reader.java @@ -160,7 +160,7 @@ public final class Reader { * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED) + @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION) public boolean reset() { if (!mService.isConnected()) { Log.e(TAG, "service is not connected"); diff --git a/core/java/android/telephony/CellBroadcastIntents.java b/core/java/android/telephony/CellBroadcastIntents.java index 32d330e1a47f..e07f69a98a85 100644 --- a/core/java/android/telephony/CellBroadcastIntents.java +++ b/core/java/android/telephony/CellBroadcastIntents.java @@ -46,7 +46,11 @@ public class CellBroadcastIntents { /** * Broadcast intent action for notifying area information has been updated. The information - * can be retrieved by {@link CellBroadcastService#getCellBroadcastAreaInfo(int)} + * can be retrieved by {@link CellBroadcastService#getCellBroadcastAreaInfo(int)}. The + * associated SIM slot index of updated area information can be retrieved through the extra + * {@link SubscriptionManager#EXTRA_SLOT_INDEX}. + * + * @see SubscriptionManager#EXTRA_SLOT_INDEX */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_AREA_INFO_UPDATED = @@ -81,7 +85,6 @@ public class CellBroadcastIntents { int initialCode, int slotIndex) { Intent backgroundIntent = new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION); backgroundIntent.putExtra(EXTRA_MESSAGE, smsCbMessage); - backgroundIntent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); putPhoneIdAndSubIdExtra(context, backgroundIntent, slotIndex); String receiverPermission = Manifest.permission.RECEIVE_SMS; diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 1dca7fd0e444..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; /** @@ -427,6 +426,17 @@ public class PhoneStateListener { @RequiresPermission(Manifest.permission.READ_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 0x40000000; + /** + * Listen for Barring Information for the current registered / camped cell. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling + * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see #onBarringInfoChanged() + */ + @RequiresPermission(Manifest.permission.READ_PHONE_STATE) + public static final int LISTEN_BARRING_INFO = 0x80000000; + /* * Subscription used to listen to the phone state changes * @hide @@ -1036,6 +1046,20 @@ public class PhoneStateListener { } /** + * Report updated barring information for the current camped/registered cell. + * + * <p>Barring info is provided for all services applicable to the current camped/registered + * cell, for the registered PLMN and current access class/access category. + * + * @param barringInfo for all services on the current cell. + * + * @see android.telephony.BarringInfo + */ + public void onBarringInfoChanged(@NonNull BarringInfo barringInfo) { + // default implementation empty + } + + /** * The callback methods need to be called on the handler thread where * this object was created. If the binder did that for us it'd be nice. * @@ -1328,6 +1352,14 @@ public class PhoneStateListener { cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode))); // default implementation empty } + + public void onBarringInfoChanged(BarringInfo barringInfo) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onBarringInfoChanged(barringInfo))); + } } diff --git a/core/java/android/telephony/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 c4b4c43056b1..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 { @@ -729,4 +674,21 @@ public class TelephonyRegistryManager { } catch (RemoteException ex) { } } + + /** + * Notify {@link BarringInfo} has changed for a specific subscription. + * + * @param slotIndex for the phone object that got updated barring info. + * @param subId for which the BarringInfo changed. + * @param barringInfo updated BarringInfo. + */ + public void notifyBarringInfoChanged( + int slotIndex, int subId, @NonNull BarringInfo barringInfo) { + try { + sRegistry.notifyBarringInfoChanged(slotIndex, subId, barringInfo); + } catch (RemoteException ex) { + // system server crash + } + } + } diff --git a/core/java/android/view/inputmethod/OWNERS b/core/java/android/view/inputmethod/OWNERS new file mode 100644 index 000000000000..244cc30e089e --- /dev/null +++ b/core/java/android/view/inputmethod/OWNERS @@ -0,0 +1,3 @@ +set noparent + +include ../../../../../services/core/java/com/android/server/inputmethod/OWNERS diff --git a/core/java/android/webkit/DateSorter.java b/core/java/android/webkit/DateSorter.java index fede244f2720..90d44db3eff4 100644 --- a/core/java/android/webkit/DateSorter.java +++ b/core/java/android/webkit/DateSorter.java @@ -19,11 +19,11 @@ package android.webkit; import android.content.Context; import android.content.res.Resources; +import com.android.icu.text.DateSorterBridge; + import java.util.Calendar; import java.util.Locale; -import libcore.icu.LocaleData; - /** * Sorts dates into the following groups: * Today @@ -69,9 +69,9 @@ public class DateSorter { if (locale == null) { locale = Locale.getDefault(); } - LocaleData localeData = LocaleData.get(locale); - mLabels[0] = localeData.today; - mLabels[1] = localeData.yesterday; + DateSorterBridge dateSorterBridge = DateSorterBridge.createInstance(locale); + mLabels[0] = dateSorterBridge.getToday(); + mLabels[1] = dateSorterBridge.getYesterday(); int resId = com.android.internal.R.plurals.last_num_days; String format = resources.getQuantityString(resId, NUM_DAYS_AGO); diff --git a/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java b/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java index 9aee879f21da..ef8d0184c6ed 100644 --- a/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java +++ b/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java @@ -50,6 +50,16 @@ public class ImsUceManager { public static final String ACTION_UCE_SERVICE_DOWN = "com.android.ims.internal.uce.UCE_SERVICE_DOWN"; + /** + * Uce Service status received in IUceListener.setStatus() callback + */ + public static final int UCE_SERVICE_STATUS_FAILURE = 0; + /** indicate UI to call Presence/Options API. */ + public static final int UCE_SERVICE_STATUS_ON = 1; + /** Indicate UI destroy Presence/Options */ + public static final int UCE_SERVICE_STATUS_CLOSED = 2; + /** Service up and trying to register for network events */ + public static final int UCE_SERVICE_STATUS_READY = 3; /** * Gets the instance of UCE Manager diff --git a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java index ab890d277f43..9ba025988126 100644 --- a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java +++ b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java @@ -93,6 +93,43 @@ public class CompatibilityChangeInfo implements Parcelable { dest.writeString(mDescription); } + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CompatibilityChangeInfo(") + .append(getId()); + if (getName() != null) { + sb.append("; name=").append(getName()); + } + if (getEnableAfterTargetSdk() != -1) { + sb.append("; enableAfterTargetSdk=").append(getEnableAfterTargetSdk()); + } + if (getDisabled()) { + sb.append("; disabled"); + } + if (getLoggingOnly()) { + sb.append("; loggingOnly"); + } + return sb.append(")").toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || !(o instanceof CompatibilityChangeInfo)) { + return false; + } + CompatibilityChangeInfo that = (CompatibilityChangeInfo) o; + return this.mChangeId == that.mChangeId + && this.mName.equals(that.mName) + && this.mEnableAfterTargetSdk == that.mEnableAfterTargetSdk + && this.mDisabled == that.mDisabled + && this.mLoggingOnly == that.mLoggingOnly + && this.mDescription.equals(that.mDescription); + + } + public static final Parcelable.Creator<CompatibilityChangeInfo> CREATOR = new Parcelable.Creator<CompatibilityChangeInfo>() { diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl index 523ed6fa9a4f..6408def7eeac 100644 --- a/core/java/com/android/internal/compat/IPlatformCompat.aidl +++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl @@ -222,6 +222,14 @@ interface IPlatformCompat CompatibilityChangeInfo[] listAllChanges(); /** + * List the compatibility changes that should be present in the UI. + * Filters out certain changes like e.g. logging only. + * + * @return An array of {@link CompatChangeInfo}. + */ + CompatibilityChangeInfo[] listUIChanges(); + + /** * Get an instance that can determine whether a changeid can be overridden for a package name. */ IOverrideValidator getOverrideValidator(); diff --git a/core/java/com/android/internal/inputmethod/OWNERS b/core/java/com/android/internal/inputmethod/OWNERS new file mode 100644 index 000000000000..fc0e5d4dea2b --- /dev/null +++ b/core/java/com/android/internal/inputmethod/OWNERS @@ -0,0 +1,3 @@ +set noparent + +include ../../../../../../services/core/java/com/android/server/inputmethod/OWNERS diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 5d50582517a3..401933aa4b1f 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -5421,7 +5421,7 @@ public class BatteryStatsImpl extends BatteryStats { if (mVideoOnNesting > 0) { final long elapsedRealtime = mClocks.elapsedRealtime(); final long uptime = mClocks.uptimeMillis(); - mAudioOnNesting = 0; + mVideoOnNesting = 0; mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " + Integer.toHexString(mHistoryCur.states)); diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 300f71af5dd5..021f48746889 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -122,12 +122,6 @@ public class ZygoteInit { private static boolean sPreloadComplete; - /** - * Cached classloader to use for the system server. Will only be populated in the system - * server process. - */ - private static ClassLoader sCachedSystemServerClassLoader = null; - static void preload(TimingsTraceLog bootTimingsTraceLog) { Log.d(TAG, "begin preload"); bootTimingsTraceLog.traceBegin("BeginPreload"); @@ -499,13 +493,7 @@ public class ZygoteInit { final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { - if (performSystemServerDexOpt(systemServerClasspath)) { - // Throw away the cached classloader. If we compiled here, the classloader would - // not have had AoT-ed artifacts. - // Note: This only works in a very special environment where selinux enforcement is - // disabled, e.g., Mac builds. - sCachedSystemServerClassLoader = null; - } + performSystemServerDexOpt(systemServerClasspath); // Capturing profiles is only supported for debug or eng builds since selinux normally // prevents it. if (shouldProfileSystemServer() && (Build.IS_USERDEBUG || Build.IS_ENG)) { @@ -537,9 +525,10 @@ public class ZygoteInit { throw new IllegalStateException("Unexpected return from WrapperInit.execApplication"); } else { - createSystemServerClassLoader(); - ClassLoader cl = sCachedSystemServerClassLoader; - if (cl != null) { + ClassLoader cl = null; + if (systemServerClasspath != null) { + cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion); + Thread.currentThread().setContextClassLoader(cl); } @@ -555,24 +544,6 @@ public class ZygoteInit { } /** - * Create the classloader for the system server and store it in - * {@link sCachedSystemServerClassLoader}. This function may be called through JNI in - * system server startup, when the runtime is in a critically low state. Do not do - * extended computation etc here. - */ - private static void createSystemServerClassLoader() { - if (sCachedSystemServerClassLoader != null) { - return; - } - final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); - // TODO: Should we run optimization here? - if (systemServerClasspath != null) { - sCachedSystemServerClassLoader = createPathClassLoader(systemServerClasspath, - VMRuntime.SDK_VERSION_CUR_DEVELOPMENT); - } - } - - /** * Note that preparing the profiles for system server does not require special selinux * permissions. From the installer perspective the system server is a regular package which can * capture profile information. @@ -636,16 +607,15 @@ public class ZygoteInit { /** * Performs dex-opt on the elements of {@code classPath}, if needed. We choose the instruction - * set of the current runtime. If something was compiled, return true. + * set of the current runtime. */ - private static boolean performSystemServerDexOpt(String classPath) { + private static void performSystemServerDexOpt(String classPath) { final String[] classPathElements = classPath.split(":"); final IInstalld installd = IInstalld.Stub .asInterface(ServiceManager.getService("installd")); final String instructionSet = VMRuntime.getRuntime().vmInstructionSet(); String classPathForElement = ""; - boolean compiledSomething = false; for (String classPathElement : classPathElements) { // We default to the verify filter because the compilation will happen on /data and // system server cannot load executable code outside /system. @@ -686,7 +656,6 @@ public class ZygoteInit { uuid, classLoaderContext, seInfo, false /* downgrade */, targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null, "server-dexopt"); - compiledSomething = true; } catch (RemoteException | ServiceSpecificException e) { // Ignore (but log), we need this on the classpath for fallback mode. Log.w(TAG, "Failed compiling classpath element for system server: " @@ -697,8 +666,6 @@ public class ZygoteInit { classPathForElement = encodeSystemServerClassPath( classPathForElement, classPathElement); } - - return compiledSomething; } /** diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index d15f48054e9d..3d5dfbbb871a 100644 --- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -16,6 +16,7 @@ package com.android.internal.telephony; +import android.telephony.BarringInfo; import android.telephony.CallAttributes; import android.telephony.CellIdentity; import android.telephony.CellInfo; @@ -66,4 +67,5 @@ oneway interface IPhoneStateListener { void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo); void onRegistrationFailed(in CellIdentity cellIdentity, String chosenPlmn, int domain, int causeCode, int additionalCauseCode); + void onBarringInfoChanged(in BarringInfo barringInfo); } diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 3176f96ef9ce..866715551a41 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -19,6 +19,7 @@ package com.android.internal.telephony; import android.content.Intent; import android.net.LinkProperties; import android.net.NetworkCapabilities; +import android.telephony.BarringInfo; import android.telephony.CallQuality; import android.telephony.CellIdentity; import android.telephony.CellInfo; @@ -102,4 +103,5 @@ interface ITelephonyRegistry { void notifyImsDisconnectCause(int subId, in ImsReasonInfo imsReasonInfo); void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity, String chosenPlmn, int domain, int causeCode, int additionalCauseCode); + void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo); } diff --git a/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_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp index bd4862dfb08d..d4369d40a45e 100644 --- a/core/jni/android_content_res_ApkAssets.cpp +++ b/core/jni/android_content_res_ApkAssets.cpp @@ -78,12 +78,13 @@ static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, jobject file_descri return 0; } + auto dup_fd_id = dup_fd.get(); std::unique_ptr<const ApkAssets> apk_assets = ApkAssets::LoadFromFd(std::move(dup_fd), friendly_name_utf8.c_str(), system, force_shared_lib); if (apk_assets == nullptr) { std::string error_msg = base::StringPrintf("Failed to load asset path %s from fd %d", - friendly_name_utf8.c_str(), dup_fd.get()); + friendly_name_utf8.c_str(), dup_fd_id); jniThrowException(env, "java/io/IOException", error_msg.c_str()); return 0; } 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/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 0ce61de270f8..22f0478ce841 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -113,15 +113,11 @@ typedef const std::function<void(std::string)>& fail_fn_t; static pid_t gSystemServerPid = 0; -static constexpr const char* kZygoteClassName = "com/android/internal/os/Zygote"; +static const char kZygoteClassName[] = "com/android/internal/os/Zygote"; static jclass gZygoteClass; static jmethodID gCallPostForkSystemServerHooks; static jmethodID gCallPostForkChildHooks; -static constexpr const char* kZygoteInitClassName = "com/android/internal/os/ZygoteInit"; -static jclass gZygoteInitClass; -static jmethodID gCreateSystemServerClassLoader; - static bool gIsSecurityEnforced = true; /** @@ -1221,15 +1217,6 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, fail_fn("Error calling post fork system server hooks."); } - // Prefetch the classloader for the system server. This is done early to - // allow a tie-down of the proper system server selinux domain. - env->CallStaticVoidMethod(gZygoteInitClass, gCreateSystemServerClassLoader); - if (env->ExceptionCheck()) { - // Be robust here. The Java code will attempt to create the classloader - // at a later point (but may not have rights to use AoT artifacts). - env->ExceptionClear(); - } - // TODO(oth): Remove hardcoded label here (b/117874058). static const char* kSystemServerLabel = "u:r:system_server:s0"; if (selinux_android_setcon(kSystemServerLabel) != 0) { @@ -1908,13 +1895,6 @@ int register_com_android_internal_os_Zygote(JNIEnv* env) { gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks", "(IZZLjava/lang/String;)V"); - gZygoteInitClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteInitClassName)); - gCreateSystemServerClassLoader = GetStaticMethodIDOrDie(env, gZygoteInitClass, - "createSystemServerClassLoader", - "()V"); - - RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods)); - - return JNI_OK; + return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods)); } } // namespace android 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/AndroidManifest.xml b/core/res/AndroidManifest.xml index 9817cebf1c83..e6dc15f911de 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1645,6 +1645,10 @@ <permission android:name="android.permission.NETWORK_FACTORY" android:protectionLevel="signature" /> + <!-- @SystemApi @hide Allows applications to access network stats provider --> + <permission android:name="android.permission.NETWORK_STATS_PROVIDER" + android:protectionLevel="signature" /> + <!-- Allows Settings and SystemUI to call methods in Networking services <p>Not for use by third-party or privileged applications. @SystemApi @TestApi @@ -1794,7 +1798,7 @@ and bypass OMAPI AccessControlEnforcer. <p>Not for use by third-party applications. @hide --> - <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED" + <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION" android:protectionLevel="signature|privileged" /> <!-- @deprecated This permission used to allow too broad access to sensitive methods and all its diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index d48c56c42b09..4c6e1e350466 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3049,6 +3049,10 @@ <!-- Whether to use voip audio mode for ims call --> <bool name="config_use_voip_mode_for_ims">false</bool> + <!-- Boolean indicating USSD over IMS is allowed. + If it is not supported due to modem limitations, USSD send over the CS pipe instead.--> + <bool name="config_allow_ussd_over_ims">false</bool> + <!-- String array containing numbers that shouldn't be logged. Country-specific. --> <string-array name="unloggable_phone_numbers" /> 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 8810ac459f63..7f463807e1e9 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3450,8 +3450,6 @@ <!-- A notification is shown when connected network without internet due to private dns validation failed. This is the notification's message. [CHAR LIMIT=NONE] --> <string name="private_dns_broken_detailed">Private DNS server cannot be accessed</string> - <!-- A notification is shown after the user logs in to a captive portal network, to indicate that the network should now have internet connectivity. This is the message of notification. [CHAR LIMIT=50] --> - <string name="captive_portal_logged_in_detailed">Connected</string> <!-- A notification is shown when the user connects to a network that doesn't have access to some services (e.g. Push notifications may not work). This is the notification's title. [CHAR LIMIT=50] --> <string name="network_partial_connectivity"><xliff:g id="network_ssid" example="GoogleGuest">%1$s</xliff:g> has limited connectivity</string> @@ -5423,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/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 076885637f76..7102f6c97247 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -735,7 +735,6 @@ <java-symbol type="string" name="capability_title_canControlMagnification" /> <java-symbol type="string" name="capability_desc_canPerformGestures" /> <java-symbol type="string" name="capability_title_canPerformGestures" /> - <java-symbol type="string" name="captive_portal_logged_in_detailed" /> <java-symbol type="string" name="cfTemplateForwarded" /> <java-symbol type="string" name="cfTemplateForwardedTime" /> <java-symbol type="string" name="cfTemplateNotForwarded" /> @@ -2635,6 +2634,7 @@ <java-symbol type="bool" name="config_device_wfc_ims_available" /> <java-symbol type="bool" name="config_carrier_wfc_ims_available" /> <java-symbol type="bool" name="config_use_voip_mode_for_ims" /> + <java-symbol type="bool" name="config_allow_ussd_over_ims" /> <java-symbol type="attr" name="touchscreenBlocksFocus" /> <java-symbol type="layout" name="resolver_list_with_default" /> <java-symbol type="string" name="activity_resolver_set_always" /> diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java index 5d42915fc82b..4b42f4ae9888 100644 --- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java +++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java @@ -268,7 +268,7 @@ public class BandwidthTest extends InstrumentationTestCase { File snd_stat = new File (root_filepath + "tcp_snd"); int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat); NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); - stats.addEntry(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT, + stats.insertEntry(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT, NetworkStats.TAG_NONE, rx, 0, tx, 0, 0); return stats; } diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java index 239f971664e9..3ebe1039d975 100644 --- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java +++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java @@ -54,7 +54,7 @@ public class NetworkStatsBenchmark { recycle.txBytes = 150000; recycle.txPackets = 1500; recycle.operations = 0; - mNetworkStats.addEntry(recycle); + mNetworkStats.insertEntry(recycle); if (recycle.set == 1) { uid++; } @@ -70,7 +70,7 @@ public class NetworkStatsBenchmark { recycle.txBytes = 180000 * mSize; recycle.txPackets = 1200 * mSize; recycle.operations = 0; - mNetworkStats.addEntry(recycle); + mNetworkStats.insertEntry(recycle); } } diff --git a/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java b/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java index c4ff9beec0c5..28009d4168ad 100644 --- a/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java +++ b/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java @@ -129,7 +129,7 @@ public class TelephonyTimeZoneSuggestionTest { } @Test(expected = RuntimeException.class) - public void testBuilderValidates_emptyZone_badMatchType() { + public void testBuilderValidates_nullZone_badMatchType() { TelephonyTimeZoneSuggestion.Builder builder = new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX); // No zone ID, so match type should be left unset. diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 7d752cdcd2d8..802b106a107c 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -346,6 +346,7 @@ public class SettingsBackupTest { Settings.Global.NETSTATS_POLL_INTERVAL, Settings.Global.NETSTATS_SAMPLE_ENABLED, Settings.Global.NETSTATS_AUGMENT_ENABLED, + Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED, Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE, Settings.Global.NETSTATS_UID_BUCKET_DURATION, Settings.Global.NETSTATS_UID_DELETE_AGE, diff --git a/data/etc/framework-sysconfig.xml b/data/etc/framework-sysconfig.xml index b0d2de17527d..ad001da899ec 100644 --- a/data/etc/framework-sysconfig.xml +++ b/data/etc/framework-sysconfig.xml @@ -19,11 +19,29 @@ <!-- Broadcast actions that are currently exempted from O+ background delivery restrictions. --> - <allow-implicit-broadcast action="android.intent.action.SIM_STATE_CHANGED" /> - <allow-implicit-broadcast action="android.intent.action.PACKAGE_CHANGED" /> + <allow-implicit-broadcast action="android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED" /> + <allow-implicit-broadcast action="android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED" /> + <allow-implicit-broadcast action="android.intent.action.DATA_SMS_RECEIVED" /> <allow-implicit-broadcast action="android.intent.action.MEDIA_SCANNER_SCAN_FILE" /> - <allow-implicit-broadcast action="android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION" /> + <allow-implicit-broadcast action="android.intent.action.PACKAGE_CHANGED" /> + <allow-implicit-broadcast action="android.intent.action.SIM_STATE_CHANGED" /> <allow-implicit-broadcast action="android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION" /> + <allow-implicit-broadcast action="android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION" /> + <allow-implicit-broadcast action="android.provider.Telephony.SECRET_CODE" /> + <allow-implicit-broadcast action="android.provider.Telephony.SMS_CB_RECEIVED" /> + <allow-implicit-broadcast action="android.provider.Telephony.SMS_DELIVER" /> + <allow-implicit-broadcast action="android.provider.Telephony.SMS_RECEIVED" /> + <allow-implicit-broadcast action="android.provider.Telephony.SMS_REJECTED" /> + <allow-implicit-broadcast action="android.provider.Telephony.WAP_PUSH_DELIVER" /> + <allow-implicit-broadcast action="android.provider.Telephony.WAP_PUSH_RECEIVED" /> + <allow-implicit-broadcast action="android.telephony.action.CARRIER_CONFIG_CHANGED" /> + <allow-implicit-broadcast action="android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED" /> + <allow-implicit-broadcast action="android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED" /> + <allow-implicit-broadcast action="android.telephony.action.SECRET_CODE" /> + <allow-implicit-broadcast action="android.telephony.action.SIM_APPLICATION_STATE_CHANGED" /> + <allow-implicit-broadcast action="android.telephony.action.SIM_CARD_STATE_CHANGED" /> + <allow-implicit-broadcast action="android.telephony.action.SIM_SLOT_STATUS_CHANGED" /> + <!-- Whitelist of what components are permitted as backup data transports. The 'service' attribute here is a flattened ComponentName string. --> 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/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index e00702384713..a1c8e1366803 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -39,11 +39,6 @@ applications that come with the platform <permission name="android.permission.CRYPT_KEEPER"/> </privapp-permissions> - <privapp-permissions package="com.android.captiveportallogin"> - <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/> - <permission name="android.permission.NETWORK_BYPASS_PRIVATE_DNS"/> - </privapp-permissions> - <privapp-permissions package="com.android.cellbroadcastreceiver"> <permission name="android.permission.INTERACT_ACROSS_USERS"/> <permission name="android.permission.MANAGE_USERS"/> @@ -238,6 +233,7 @@ applications that come with the platform </privapp-permissions> <privapp-permissions package="com.android.networkstack.tethering"> + <permission name="android.permission.BLUETOOTH_PRIVILEGED" /> <permission name="android.permission.MANAGE_USB"/> <permission name="android.permission.MODIFY_PHONE_STATE"/> <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/> @@ -332,6 +328,7 @@ applications that come with the platform <permission name="android.permission.SUSPEND_APPS" /> <permission name="android.permission.UPDATE_APP_OPS_STATS"/> <permission name="android.permission.USE_RESERVED_DISK"/> + <permission name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE"/> <permission name="android.permission.WRITE_MEDIA_STORAGE"/> <permission name="android.permission.WRITE_SECURE_SETTINGS"/> <permission name="android.permission.STATUS_BAR_SERVICE"/> @@ -358,6 +355,8 @@ applications that come with the platform <!-- Permission required to test lights control APIs. --> <permission name="android.permission.CONTROL_DEVICE_LIGHTS" /> <permission name="android.permission.REBOOT"/> + <!-- Permission required for testing system audio effect APIs. --> + <permission name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"/> </privapp-permissions> <privapp-permissions package="com.android.statementservice"> diff --git a/keystore/tests/OWNERS b/keystore/tests/OWNERS index 9e65f88b3366..86c31f403da0 100644 --- a/keystore/tests/OWNERS +++ b/keystore/tests/OWNERS @@ -1,5 +1,4 @@ # Android Enterprise security team eranm@google.com -irinaid@google.com pgrafov@google.com rubinxu@google.com diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index 237c1e970b17..09705e1aae67 100644 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -70,8 +70,11 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap LOG(ERROR) << "failed to load IDMAP " << idmap_path; return {}; } - return LoadImpl({} /*fd*/, loaded_idmap->OverlayApkPath(), std::move(idmap_asset), - std::move(loaded_idmap), system, false /*load_as_shared_library*/); + auto apkPath = loaded_idmap->OverlayApkPath(); + return LoadImpl({} /*fd*/, apkPath, + std::move(idmap_asset), + std::move(loaded_idmap), + system, false /*load_as_shared_library*/); } std::unique_ptr<const ApkAssets> ApkAssets::LoadFromFd(unique_fd fd, diff --git a/libs/androidfw/LocaleDataTables.cpp b/libs/androidfw/LocaleDataTables.cpp index e748bd886ebc..6c6c5c9f4e22 100644 --- a/libs/androidfw/LocaleDataTables.cpp +++ b/libs/androidfw/LocaleDataTables.cpp @@ -15,1474 +15,1478 @@ const char SCRIPT_CODES[][4] = { /* 11 */ {'C', 'a', 'r', 'i'}, /* 12 */ {'C', 'h', 'a', 'm'}, /* 13 */ {'C', 'h', 'e', 'r'}, - /* 14 */ {'C', 'o', 'p', 't'}, - /* 15 */ {'C', 'p', 'r', 't'}, - /* 16 */ {'C', 'y', 'r', 'l'}, - /* 17 */ {'D', 'e', 'v', 'a'}, - /* 18 */ {'E', 'g', 'y', 'p'}, - /* 19 */ {'E', 't', 'h', 'i'}, - /* 20 */ {'G', 'e', 'o', 'r'}, - /* 21 */ {'G', 'o', 'n', 'g'}, - /* 22 */ {'G', 'o', 'n', 'm'}, - /* 23 */ {'G', 'o', 't', 'h'}, - /* 24 */ {'G', 'r', 'e', 'k'}, - /* 25 */ {'G', 'u', 'j', 'r'}, - /* 26 */ {'G', 'u', 'r', 'u'}, - /* 27 */ {'H', 'a', 'n', 's'}, - /* 28 */ {'H', 'a', 'n', 't'}, - /* 29 */ {'H', 'a', 't', 'r'}, - /* 30 */ {'H', 'e', 'b', 'r'}, - /* 31 */ {'H', 'l', 'u', 'w'}, - /* 32 */ {'H', 'm', 'n', 'g'}, - /* 33 */ {'H', 'm', 'n', 'p'}, - /* 34 */ {'I', 't', 'a', 'l'}, - /* 35 */ {'J', 'p', 'a', 'n'}, - /* 36 */ {'K', 'a', 'l', 'i'}, - /* 37 */ {'K', 'a', 'n', 'a'}, - /* 38 */ {'K', 'h', 'a', 'r'}, - /* 39 */ {'K', 'h', 'm', 'r'}, - /* 40 */ {'K', 'n', 'd', 'a'}, - /* 41 */ {'K', 'o', 'r', 'e'}, - /* 42 */ {'L', 'a', 'n', 'a'}, - /* 43 */ {'L', 'a', 'o', 'o'}, - /* 44 */ {'L', 'a', 't', 'n'}, - /* 45 */ {'L', 'e', 'p', 'c'}, - /* 46 */ {'L', 'i', 'n', 'a'}, - /* 47 */ {'L', 'i', 's', 'u'}, - /* 48 */ {'L', 'y', 'c', 'i'}, - /* 49 */ {'L', 'y', 'd', 'i'}, - /* 50 */ {'M', 'a', 'n', 'd'}, - /* 51 */ {'M', 'a', 'n', 'i'}, - /* 52 */ {'M', 'e', 'r', 'c'}, - /* 53 */ {'M', 'l', 'y', 'm'}, - /* 54 */ {'M', 'o', 'n', 'g'}, - /* 55 */ {'M', 'r', 'o', 'o'}, - /* 56 */ {'M', 'y', 'm', 'r'}, - /* 57 */ {'N', 'a', 'r', 'b'}, - /* 58 */ {'N', 'k', 'o', 'o'}, - /* 59 */ {'N', 's', 'h', 'u'}, - /* 60 */ {'O', 'g', 'a', 'm'}, - /* 61 */ {'O', 'r', 'k', 'h'}, - /* 62 */ {'O', 'r', 'y', 'a'}, - /* 63 */ {'O', 's', 'g', 'e'}, - /* 64 */ {'P', 'a', 'u', 'c'}, - /* 65 */ {'P', 'h', 'l', 'i'}, - /* 66 */ {'P', 'h', 'n', 'x'}, - /* 67 */ {'P', 'l', 'r', 'd'}, - /* 68 */ {'P', 'r', 't', 'i'}, - /* 69 */ {'R', 'u', 'n', 'r'}, - /* 70 */ {'S', 'a', 'm', 'r'}, - /* 71 */ {'S', 'a', 'r', 'b'}, - /* 72 */ {'S', 'a', 'u', 'r'}, - /* 73 */ {'S', 'g', 'n', 'w'}, - /* 74 */ {'S', 'i', 'n', 'h'}, - /* 75 */ {'S', 'o', 'g', 'd'}, - /* 76 */ {'S', 'o', 'r', 'a'}, - /* 77 */ {'S', 'o', 'y', 'o'}, - /* 78 */ {'S', 'y', 'r', 'c'}, - /* 79 */ {'T', 'a', 'l', 'e'}, - /* 80 */ {'T', 'a', 'l', 'u'}, - /* 81 */ {'T', 'a', 'm', 'l'}, - /* 82 */ {'T', 'a', 'n', 'g'}, - /* 83 */ {'T', 'a', 'v', 't'}, - /* 84 */ {'T', 'e', 'l', 'u'}, - /* 85 */ {'T', 'f', 'n', 'g'}, - /* 86 */ {'T', 'h', 'a', 'a'}, - /* 87 */ {'T', 'h', 'a', 'i'}, - /* 88 */ {'T', 'i', 'b', 't'}, - /* 89 */ {'U', 'g', 'a', 'r'}, - /* 90 */ {'V', 'a', 'i', 'i'}, - /* 91 */ {'W', 'c', 'h', 'o'}, - /* 92 */ {'X', 'p', 'e', 'o'}, - /* 93 */ {'X', 's', 'u', 'x'}, - /* 94 */ {'Y', 'i', 'i', 'i'}, - /* 95 */ {'~', '~', '~', 'A'}, - /* 96 */ {'~', '~', '~', 'B'}, + /* 14 */ {'C', 'h', 'r', 's'}, + /* 15 */ {'C', 'o', 'p', 't'}, + /* 16 */ {'C', 'p', 'r', 't'}, + /* 17 */ {'C', 'y', 'r', 'l'}, + /* 18 */ {'D', 'e', 'v', 'a'}, + /* 19 */ {'E', 'g', 'y', 'p'}, + /* 20 */ {'E', 't', 'h', 'i'}, + /* 21 */ {'G', 'e', 'o', 'r'}, + /* 22 */ {'G', 'o', 'n', 'g'}, + /* 23 */ {'G', 'o', 'n', 'm'}, + /* 24 */ {'G', 'o', 't', 'h'}, + /* 25 */ {'G', 'r', 'e', 'k'}, + /* 26 */ {'G', 'u', 'j', 'r'}, + /* 27 */ {'G', 'u', 'r', 'u'}, + /* 28 */ {'H', 'a', 'n', 's'}, + /* 29 */ {'H', 'a', 'n', 't'}, + /* 30 */ {'H', 'a', 't', 'r'}, + /* 31 */ {'H', 'e', 'b', 'r'}, + /* 32 */ {'H', 'l', 'u', 'w'}, + /* 33 */ {'H', 'm', 'n', 'g'}, + /* 34 */ {'H', 'm', 'n', 'p'}, + /* 35 */ {'I', 't', 'a', 'l'}, + /* 36 */ {'J', 'p', 'a', 'n'}, + /* 37 */ {'K', 'a', 'l', 'i'}, + /* 38 */ {'K', 'a', 'n', 'a'}, + /* 39 */ {'K', 'h', 'a', 'r'}, + /* 40 */ {'K', 'h', 'm', 'r'}, + /* 41 */ {'K', 'i', 't', 's'}, + /* 42 */ {'K', 'n', 'd', 'a'}, + /* 43 */ {'K', 'o', 'r', 'e'}, + /* 44 */ {'L', 'a', 'n', 'a'}, + /* 45 */ {'L', 'a', 'o', 'o'}, + /* 46 */ {'L', 'a', 't', 'n'}, + /* 47 */ {'L', 'e', 'p', 'c'}, + /* 48 */ {'L', 'i', 'n', 'a'}, + /* 49 */ {'L', 'i', 's', 'u'}, + /* 50 */ {'L', 'y', 'c', 'i'}, + /* 51 */ {'L', 'y', 'd', 'i'}, + /* 52 */ {'M', 'a', 'n', 'd'}, + /* 53 */ {'M', 'a', 'n', 'i'}, + /* 54 */ {'M', 'e', 'r', 'c'}, + /* 55 */ {'M', 'l', 'y', 'm'}, + /* 56 */ {'M', 'o', 'n', 'g'}, + /* 57 */ {'M', 'r', 'o', 'o'}, + /* 58 */ {'M', 'y', 'm', 'r'}, + /* 59 */ {'N', 'a', 'r', 'b'}, + /* 60 */ {'N', 'k', 'o', 'o'}, + /* 61 */ {'N', 's', 'h', 'u'}, + /* 62 */ {'O', 'g', 'a', 'm'}, + /* 63 */ {'O', 'r', 'k', 'h'}, + /* 64 */ {'O', 'r', 'y', 'a'}, + /* 65 */ {'O', 's', 'g', 'e'}, + /* 66 */ {'P', 'a', 'u', 'c'}, + /* 67 */ {'P', 'h', 'l', 'i'}, + /* 68 */ {'P', 'h', 'n', 'x'}, + /* 69 */ {'P', 'l', 'r', 'd'}, + /* 70 */ {'P', 'r', 't', 'i'}, + /* 71 */ {'R', 'u', 'n', 'r'}, + /* 72 */ {'S', 'a', 'm', 'r'}, + /* 73 */ {'S', 'a', 'r', 'b'}, + /* 74 */ {'S', 'a', 'u', 'r'}, + /* 75 */ {'S', 'g', 'n', 'w'}, + /* 76 */ {'S', 'i', 'n', 'h'}, + /* 77 */ {'S', 'o', 'g', 'd'}, + /* 78 */ {'S', 'o', 'r', 'a'}, + /* 79 */ {'S', 'o', 'y', 'o'}, + /* 80 */ {'S', 'y', 'r', 'c'}, + /* 81 */ {'T', 'a', 'l', 'e'}, + /* 82 */ {'T', 'a', 'l', 'u'}, + /* 83 */ {'T', 'a', 'm', 'l'}, + /* 84 */ {'T', 'a', 'n', 'g'}, + /* 85 */ {'T', 'a', 'v', 't'}, + /* 86 */ {'T', 'e', 'l', 'u'}, + /* 87 */ {'T', 'f', 'n', 'g'}, + /* 88 */ {'T', 'h', 'a', 'a'}, + /* 89 */ {'T', 'h', 'a', 'i'}, + /* 90 */ {'T', 'i', 'b', 't'}, + /* 91 */ {'U', 'g', 'a', 'r'}, + /* 92 */ {'V', 'a', 'i', 'i'}, + /* 93 */ {'W', 'c', 'h', 'o'}, + /* 94 */ {'X', 'p', 'e', 'o'}, + /* 95 */ {'X', 's', 'u', 'x'}, + /* 96 */ {'Y', 'i', 'i', 'i'}, + /* 97 */ {'~', '~', '~', 'A'}, + /* 98 */ {'~', '~', '~', 'B'}, }; const std::unordered_map<uint32_t, uint8_t> LIKELY_SCRIPTS({ - {0x61610000u, 44u}, // aa -> Latn - {0xA0000000u, 44u}, // aai -> Latn - {0xA8000000u, 44u}, // aak -> Latn - {0xD0000000u, 44u}, // aau -> Latn - {0x61620000u, 16u}, // ab -> Cyrl - {0xA0200000u, 44u}, // abi -> Latn - {0xC0200000u, 16u}, // abq -> Cyrl - {0xC4200000u, 44u}, // abr -> Latn - {0xCC200000u, 44u}, // abt -> Latn - {0xE0200000u, 44u}, // aby -> Latn - {0x8C400000u, 44u}, // acd -> Latn - {0x90400000u, 44u}, // ace -> Latn - {0x9C400000u, 44u}, // ach -> Latn - {0x80600000u, 44u}, // ada -> Latn - {0x90600000u, 44u}, // ade -> Latn - {0xA4600000u, 44u}, // adj -> Latn - {0xBC600000u, 88u}, // adp -> Tibt - {0xE0600000u, 16u}, // ady -> Cyrl - {0xE4600000u, 44u}, // adz -> Latn + {0x61610000u, 46u}, // aa -> Latn + {0xA0000000u, 46u}, // aai -> Latn + {0xA8000000u, 46u}, // aak -> Latn + {0xD0000000u, 46u}, // aau -> Latn + {0x61620000u, 17u}, // ab -> Cyrl + {0xA0200000u, 46u}, // abi -> Latn + {0xC0200000u, 17u}, // abq -> Cyrl + {0xC4200000u, 46u}, // abr -> Latn + {0xCC200000u, 46u}, // abt -> Latn + {0xE0200000u, 46u}, // aby -> Latn + {0x8C400000u, 46u}, // acd -> Latn + {0x90400000u, 46u}, // ace -> Latn + {0x9C400000u, 46u}, // ach -> Latn + {0x80600000u, 46u}, // ada -> Latn + {0x90600000u, 46u}, // ade -> Latn + {0xA4600000u, 46u}, // adj -> Latn + {0xBC600000u, 90u}, // adp -> Tibt + {0xE0600000u, 17u}, // ady -> Cyrl + {0xE4600000u, 46u}, // adz -> Latn {0x61650000u, 4u}, // ae -> Avst {0x84800000u, 1u}, // aeb -> Arab - {0xE0800000u, 44u}, // aey -> Latn - {0x61660000u, 44u}, // af -> Latn - {0x88C00000u, 44u}, // agc -> Latn - {0x8CC00000u, 44u}, // agd -> Latn - {0x98C00000u, 44u}, // agg -> Latn - {0xB0C00000u, 44u}, // agm -> Latn - {0xB8C00000u, 44u}, // ago -> Latn - {0xC0C00000u, 44u}, // agq -> Latn - {0x80E00000u, 44u}, // aha -> Latn - {0xACE00000u, 44u}, // ahl -> Latn + {0xE0800000u, 46u}, // aey -> Latn + {0x61660000u, 46u}, // af -> Latn + {0x88C00000u, 46u}, // agc -> Latn + {0x8CC00000u, 46u}, // agd -> Latn + {0x98C00000u, 46u}, // agg -> Latn + {0xB0C00000u, 46u}, // agm -> Latn + {0xB8C00000u, 46u}, // ago -> Latn + {0xC0C00000u, 46u}, // agq -> Latn + {0x80E00000u, 46u}, // aha -> Latn + {0xACE00000u, 46u}, // ahl -> Latn {0xB8E00000u, 0u}, // aho -> Ahom - {0x99200000u, 44u}, // ajg -> Latn - {0x616B0000u, 44u}, // ak -> Latn - {0xA9400000u, 93u}, // akk -> Xsux - {0x81600000u, 44u}, // ala -> Latn - {0xA1600000u, 44u}, // ali -> Latn - {0xB5600000u, 44u}, // aln -> Latn - {0xCD600000u, 16u}, // alt -> Cyrl - {0x616D0000u, 19u}, // am -> Ethi - {0xB1800000u, 44u}, // amm -> Latn - {0xB5800000u, 44u}, // amn -> Latn - {0xB9800000u, 44u}, // amo -> Latn - {0xBD800000u, 44u}, // amp -> Latn - {0x616E0000u, 44u}, // an -> Latn - {0x89A00000u, 44u}, // anc -> Latn - {0xA9A00000u, 44u}, // ank -> Latn - {0xB5A00000u, 44u}, // ann -> Latn - {0xE1A00000u, 44u}, // any -> Latn - {0xA5C00000u, 44u}, // aoj -> Latn - {0xB1C00000u, 44u}, // aom -> Latn - {0xE5C00000u, 44u}, // aoz -> Latn + {0x99200000u, 46u}, // ajg -> Latn + {0x616B0000u, 46u}, // ak -> Latn + {0xA9400000u, 95u}, // akk -> Xsux + {0x81600000u, 46u}, // ala -> Latn + {0xA1600000u, 46u}, // ali -> Latn + {0xB5600000u, 46u}, // aln -> Latn + {0xCD600000u, 17u}, // alt -> Cyrl + {0x616D0000u, 20u}, // am -> Ethi + {0xB1800000u, 46u}, // amm -> Latn + {0xB5800000u, 46u}, // amn -> Latn + {0xB9800000u, 46u}, // amo -> Latn + {0xBD800000u, 46u}, // amp -> Latn + {0x616E0000u, 46u}, // an -> Latn + {0x89A00000u, 46u}, // anc -> Latn + {0xA9A00000u, 46u}, // ank -> Latn + {0xB5A00000u, 46u}, // ann -> Latn + {0xE1A00000u, 46u}, // any -> Latn + {0xA5C00000u, 46u}, // aoj -> Latn + {0xB1C00000u, 46u}, // aom -> Latn + {0xE5C00000u, 46u}, // aoz -> Latn {0x89E00000u, 1u}, // apc -> Arab {0x8DE00000u, 1u}, // apd -> Arab - {0x91E00000u, 44u}, // ape -> Latn - {0xC5E00000u, 44u}, // apr -> Latn - {0xC9E00000u, 44u}, // aps -> Latn - {0xE5E00000u, 44u}, // apz -> Latn + {0x91E00000u, 46u}, // ape -> Latn + {0xC5E00000u, 46u}, // apr -> Latn + {0xC9E00000u, 46u}, // aps -> Latn + {0xE5E00000u, 46u}, // apz -> Latn {0x61720000u, 1u}, // ar -> Arab - {0x61725842u, 96u}, // ar-XB -> ~~~B + {0x61725842u, 98u}, // ar-XB -> ~~~B {0x8A200000u, 2u}, // arc -> Armi - {0x9E200000u, 44u}, // arh -> Latn - {0xB6200000u, 44u}, // arn -> Latn - {0xBA200000u, 44u}, // aro -> Latn + {0x9E200000u, 46u}, // arh -> Latn + {0xB6200000u, 46u}, // arn -> Latn + {0xBA200000u, 46u}, // aro -> Latn {0xC2200000u, 1u}, // arq -> Arab {0xCA200000u, 1u}, // ars -> Arab {0xE2200000u, 1u}, // ary -> Arab {0xE6200000u, 1u}, // arz -> Arab {0x61730000u, 7u}, // as -> Beng - {0x82400000u, 44u}, // asa -> Latn - {0x92400000u, 73u}, // ase -> Sgnw - {0x9A400000u, 44u}, // asg -> Latn - {0xBA400000u, 44u}, // aso -> Latn - {0xCE400000u, 44u}, // ast -> Latn - {0x82600000u, 44u}, // ata -> Latn - {0x9A600000u, 44u}, // atg -> Latn - {0xA6600000u, 44u}, // atj -> Latn - {0xE2800000u, 44u}, // auy -> Latn - {0x61760000u, 16u}, // av -> Cyrl + {0x82400000u, 46u}, // asa -> Latn + {0x92400000u, 75u}, // ase -> Sgnw + {0x9A400000u, 46u}, // asg -> Latn + {0xBA400000u, 46u}, // aso -> Latn + {0xCE400000u, 46u}, // ast -> Latn + {0x82600000u, 46u}, // ata -> Latn + {0x9A600000u, 46u}, // atg -> Latn + {0xA6600000u, 46u}, // atj -> Latn + {0xE2800000u, 46u}, // auy -> Latn + {0x61760000u, 17u}, // av -> Cyrl {0xAEA00000u, 1u}, // avl -> Arab - {0xB6A00000u, 44u}, // avn -> Latn - {0xCEA00000u, 44u}, // avt -> Latn - {0xD2A00000u, 44u}, // avu -> Latn - {0x82C00000u, 17u}, // awa -> Deva - {0x86C00000u, 44u}, // awb -> Latn - {0xBAC00000u, 44u}, // awo -> Latn - {0xDEC00000u, 44u}, // awx -> Latn - {0x61790000u, 44u}, // ay -> Latn - {0x87000000u, 44u}, // ayb -> Latn - {0x617A0000u, 44u}, // az -> Latn + {0xB6A00000u, 46u}, // avn -> Latn + {0xCEA00000u, 46u}, // avt -> Latn + {0xD2A00000u, 46u}, // avu -> Latn + {0x82C00000u, 18u}, // awa -> Deva + {0x86C00000u, 46u}, // awb -> Latn + {0xBAC00000u, 46u}, // awo -> Latn + {0xDEC00000u, 46u}, // awx -> Latn + {0x61790000u, 46u}, // ay -> Latn + {0x87000000u, 46u}, // ayb -> Latn + {0x617A0000u, 46u}, // az -> Latn {0x617A4951u, 1u}, // az-IQ -> Arab {0x617A4952u, 1u}, // az-IR -> Arab - {0x617A5255u, 16u}, // az-RU -> Cyrl - {0x62610000u, 16u}, // ba -> Cyrl + {0x617A5255u, 17u}, // az-RU -> Cyrl + {0x62610000u, 17u}, // ba -> Cyrl {0xAC010000u, 1u}, // bal -> Arab - {0xB4010000u, 44u}, // ban -> Latn - {0xBC010000u, 17u}, // bap -> Deva - {0xC4010000u, 44u}, // bar -> Latn - {0xC8010000u, 44u}, // bas -> Latn - {0xD4010000u, 44u}, // bav -> Latn + {0xB4010000u, 46u}, // ban -> Latn + {0xBC010000u, 18u}, // bap -> Deva + {0xC4010000u, 46u}, // bar -> Latn + {0xC8010000u, 46u}, // bas -> Latn + {0xD4010000u, 46u}, // bav -> Latn {0xDC010000u, 5u}, // bax -> Bamu - {0x80210000u, 44u}, // bba -> Latn - {0x84210000u, 44u}, // bbb -> Latn - {0x88210000u, 44u}, // bbc -> Latn - {0x8C210000u, 44u}, // bbd -> Latn - {0xA4210000u, 44u}, // bbj -> Latn - {0xBC210000u, 44u}, // bbp -> Latn - {0xC4210000u, 44u}, // bbr -> Latn - {0x94410000u, 44u}, // bcf -> Latn - {0x9C410000u, 44u}, // bch -> Latn - {0xA0410000u, 44u}, // bci -> Latn - {0xB0410000u, 44u}, // bcm -> Latn - {0xB4410000u, 44u}, // bcn -> Latn - {0xB8410000u, 44u}, // bco -> Latn - {0xC0410000u, 19u}, // bcq -> Ethi - {0xD0410000u, 44u}, // bcu -> Latn - {0x8C610000u, 44u}, // bdd -> Latn - {0x62650000u, 16u}, // be -> Cyrl - {0x94810000u, 44u}, // bef -> Latn - {0x9C810000u, 44u}, // beh -> Latn + {0x80210000u, 46u}, // bba -> Latn + {0x84210000u, 46u}, // bbb -> Latn + {0x88210000u, 46u}, // bbc -> Latn + {0x8C210000u, 46u}, // bbd -> Latn + {0xA4210000u, 46u}, // bbj -> Latn + {0xBC210000u, 46u}, // bbp -> Latn + {0xC4210000u, 46u}, // bbr -> Latn + {0x94410000u, 46u}, // bcf -> Latn + {0x9C410000u, 46u}, // bch -> Latn + {0xA0410000u, 46u}, // bci -> Latn + {0xB0410000u, 46u}, // bcm -> Latn + {0xB4410000u, 46u}, // bcn -> Latn + {0xB8410000u, 46u}, // bco -> Latn + {0xC0410000u, 20u}, // bcq -> Ethi + {0xD0410000u, 46u}, // bcu -> Latn + {0x8C610000u, 46u}, // bdd -> Latn + {0x62650000u, 17u}, // be -> Cyrl + {0x94810000u, 46u}, // bef -> Latn + {0x9C810000u, 46u}, // beh -> Latn {0xA4810000u, 1u}, // bej -> Arab - {0xB0810000u, 44u}, // bem -> Latn - {0xCC810000u, 44u}, // bet -> Latn - {0xD8810000u, 44u}, // bew -> Latn - {0xDC810000u, 44u}, // bex -> Latn - {0xE4810000u, 44u}, // bez -> Latn - {0x8CA10000u, 44u}, // bfd -> Latn - {0xC0A10000u, 81u}, // bfq -> Taml + {0xB0810000u, 46u}, // bem -> Latn + {0xCC810000u, 46u}, // bet -> Latn + {0xD8810000u, 46u}, // bew -> Latn + {0xDC810000u, 46u}, // bex -> Latn + {0xE4810000u, 46u}, // bez -> Latn + {0x8CA10000u, 46u}, // bfd -> Latn + {0xC0A10000u, 83u}, // bfq -> Taml {0xCCA10000u, 1u}, // bft -> Arab - {0xE0A10000u, 17u}, // bfy -> Deva - {0x62670000u, 16u}, // bg -> Cyrl - {0x88C10000u, 17u}, // bgc -> Deva + {0xE0A10000u, 18u}, // bfy -> Deva + {0x62670000u, 17u}, // bg -> Cyrl + {0x88C10000u, 18u}, // bgc -> Deva {0xB4C10000u, 1u}, // bgn -> Arab - {0xDCC10000u, 24u}, // bgx -> Grek - {0x84E10000u, 17u}, // bhb -> Deva - {0x98E10000u, 44u}, // bhg -> Latn - {0xA0E10000u, 17u}, // bhi -> Deva - {0xACE10000u, 44u}, // bhl -> Latn - {0xB8E10000u, 17u}, // bho -> Deva - {0xE0E10000u, 44u}, // bhy -> Latn - {0x62690000u, 44u}, // bi -> Latn - {0x85010000u, 44u}, // bib -> Latn - {0x99010000u, 44u}, // big -> Latn - {0xA9010000u, 44u}, // bik -> Latn - {0xB1010000u, 44u}, // bim -> Latn - {0xB5010000u, 44u}, // bin -> Latn - {0xB9010000u, 44u}, // bio -> Latn - {0xC1010000u, 44u}, // biq -> Latn - {0x9D210000u, 44u}, // bjh -> Latn - {0xA1210000u, 19u}, // bji -> Ethi - {0xA5210000u, 17u}, // bjj -> Deva - {0xB5210000u, 44u}, // bjn -> Latn - {0xB9210000u, 44u}, // bjo -> Latn - {0xC5210000u, 44u}, // bjr -> Latn - {0xCD210000u, 44u}, // bjt -> Latn - {0xE5210000u, 44u}, // bjz -> Latn - {0x89410000u, 44u}, // bkc -> Latn - {0xB1410000u, 44u}, // bkm -> Latn - {0xC1410000u, 44u}, // bkq -> Latn - {0xD1410000u, 44u}, // bku -> Latn - {0xD5410000u, 44u}, // bkv -> Latn - {0xCD610000u, 83u}, // blt -> Tavt - {0x626D0000u, 44u}, // bm -> Latn - {0x9D810000u, 44u}, // bmh -> Latn - {0xA9810000u, 44u}, // bmk -> Latn - {0xC1810000u, 44u}, // bmq -> Latn - {0xD1810000u, 44u}, // bmu -> Latn + {0xDCC10000u, 25u}, // bgx -> Grek + {0x84E10000u, 18u}, // bhb -> Deva + {0x98E10000u, 46u}, // bhg -> Latn + {0xA0E10000u, 18u}, // bhi -> Deva + {0xACE10000u, 46u}, // bhl -> Latn + {0xB8E10000u, 18u}, // bho -> Deva + {0xE0E10000u, 46u}, // bhy -> Latn + {0x62690000u, 46u}, // bi -> Latn + {0x85010000u, 46u}, // bib -> Latn + {0x99010000u, 46u}, // big -> Latn + {0xA9010000u, 46u}, // bik -> Latn + {0xB1010000u, 46u}, // bim -> Latn + {0xB5010000u, 46u}, // bin -> Latn + {0xB9010000u, 46u}, // bio -> Latn + {0xC1010000u, 46u}, // biq -> Latn + {0x9D210000u, 46u}, // bjh -> Latn + {0xA1210000u, 20u}, // bji -> Ethi + {0xA5210000u, 18u}, // bjj -> Deva + {0xB5210000u, 46u}, // bjn -> Latn + {0xB9210000u, 46u}, // bjo -> Latn + {0xC5210000u, 46u}, // bjr -> Latn + {0xCD210000u, 46u}, // bjt -> Latn + {0xE5210000u, 46u}, // bjz -> Latn + {0x89410000u, 46u}, // bkc -> Latn + {0xB1410000u, 46u}, // bkm -> Latn + {0xC1410000u, 46u}, // bkq -> Latn + {0xD1410000u, 46u}, // bku -> Latn + {0xD5410000u, 46u}, // bkv -> Latn + {0xCD610000u, 85u}, // blt -> Tavt + {0x626D0000u, 46u}, // bm -> Latn + {0x9D810000u, 46u}, // bmh -> Latn + {0xA9810000u, 46u}, // bmk -> Latn + {0xC1810000u, 46u}, // bmq -> Latn + {0xD1810000u, 46u}, // bmu -> Latn {0x626E0000u, 7u}, // bn -> Beng - {0x99A10000u, 44u}, // bng -> Latn - {0xB1A10000u, 44u}, // bnm -> Latn - {0xBDA10000u, 44u}, // bnp -> Latn - {0x626F0000u, 88u}, // bo -> Tibt - {0xA5C10000u, 44u}, // boj -> Latn - {0xB1C10000u, 44u}, // bom -> Latn - {0xB5C10000u, 44u}, // bon -> Latn + {0x99A10000u, 46u}, // bng -> Latn + {0xB1A10000u, 46u}, // bnm -> Latn + {0xBDA10000u, 46u}, // bnp -> Latn + {0x626F0000u, 90u}, // bo -> Tibt + {0xA5C10000u, 46u}, // boj -> Latn + {0xB1C10000u, 46u}, // bom -> Latn + {0xB5C10000u, 46u}, // bon -> Latn {0xE1E10000u, 7u}, // bpy -> Beng - {0x8A010000u, 44u}, // bqc -> Latn + {0x8A010000u, 46u}, // bqc -> Latn {0xA2010000u, 1u}, // bqi -> Arab - {0xBE010000u, 44u}, // bqp -> Latn - {0xD6010000u, 44u}, // bqv -> Latn - {0x62720000u, 44u}, // br -> Latn - {0x82210000u, 17u}, // bra -> Deva + {0xBE010000u, 46u}, // bqp -> Latn + {0xD6010000u, 46u}, // bqv -> Latn + {0x62720000u, 46u}, // br -> Latn + {0x82210000u, 18u}, // bra -> Deva {0x9E210000u, 1u}, // brh -> Arab - {0xDE210000u, 17u}, // brx -> Deva - {0xE6210000u, 44u}, // brz -> Latn - {0x62730000u, 44u}, // bs -> Latn - {0xA6410000u, 44u}, // bsj -> Latn + {0xDE210000u, 18u}, // brx -> Deva + {0xE6210000u, 46u}, // brz -> Latn + {0x62730000u, 46u}, // bs -> Latn + {0xA6410000u, 46u}, // bsj -> Latn {0xC2410000u, 6u}, // bsq -> Bass - {0xCA410000u, 44u}, // bss -> Latn - {0xCE410000u, 19u}, // bst -> Ethi - {0xBA610000u, 44u}, // bto -> Latn - {0xCE610000u, 44u}, // btt -> Latn - {0xD6610000u, 17u}, // btv -> Deva - {0x82810000u, 16u}, // bua -> Cyrl - {0x8A810000u, 44u}, // buc -> Latn - {0x8E810000u, 44u}, // bud -> Latn - {0x9A810000u, 44u}, // bug -> Latn - {0xAA810000u, 44u}, // buk -> Latn - {0xB2810000u, 44u}, // bum -> Latn - {0xBA810000u, 44u}, // buo -> Latn - {0xCA810000u, 44u}, // bus -> Latn - {0xD2810000u, 44u}, // buu -> Latn - {0x86A10000u, 44u}, // bvb -> Latn - {0x8EC10000u, 44u}, // bwd -> Latn - {0xC6C10000u, 44u}, // bwr -> Latn - {0x9EE10000u, 44u}, // bxh -> Latn - {0x93010000u, 44u}, // bye -> Latn - {0xB7010000u, 19u}, // byn -> Ethi - {0xC7010000u, 44u}, // byr -> Latn - {0xCB010000u, 44u}, // bys -> Latn - {0xD7010000u, 44u}, // byv -> Latn - {0xDF010000u, 44u}, // byx -> Latn - {0x83210000u, 44u}, // bza -> Latn - {0x93210000u, 44u}, // bze -> Latn - {0x97210000u, 44u}, // bzf -> Latn - {0x9F210000u, 44u}, // bzh -> Latn - {0xDB210000u, 44u}, // bzw -> Latn - {0x63610000u, 44u}, // ca -> Latn - {0xB4020000u, 44u}, // can -> Latn - {0xA4220000u, 44u}, // cbj -> Latn - {0x9C420000u, 44u}, // cch -> Latn + {0xCA410000u, 46u}, // bss -> Latn + {0xCE410000u, 20u}, // bst -> Ethi + {0xBA610000u, 46u}, // bto -> Latn + {0xCE610000u, 46u}, // btt -> Latn + {0xD6610000u, 18u}, // btv -> Deva + {0x82810000u, 17u}, // bua -> Cyrl + {0x8A810000u, 46u}, // buc -> Latn + {0x8E810000u, 46u}, // bud -> Latn + {0x9A810000u, 46u}, // bug -> Latn + {0xAA810000u, 46u}, // buk -> Latn + {0xB2810000u, 46u}, // bum -> Latn + {0xBA810000u, 46u}, // buo -> Latn + {0xCA810000u, 46u}, // bus -> Latn + {0xD2810000u, 46u}, // buu -> Latn + {0x86A10000u, 46u}, // bvb -> Latn + {0x8EC10000u, 46u}, // bwd -> Latn + {0xC6C10000u, 46u}, // bwr -> Latn + {0x9EE10000u, 46u}, // bxh -> Latn + {0x93010000u, 46u}, // bye -> Latn + {0xB7010000u, 20u}, // byn -> Ethi + {0xC7010000u, 46u}, // byr -> Latn + {0xCB010000u, 46u}, // bys -> Latn + {0xD7010000u, 46u}, // byv -> Latn + {0xDF010000u, 46u}, // byx -> Latn + {0x83210000u, 46u}, // bza -> Latn + {0x93210000u, 46u}, // bze -> Latn + {0x97210000u, 46u}, // bzf -> Latn + {0x9F210000u, 46u}, // bzh -> Latn + {0xDB210000u, 46u}, // bzw -> Latn + {0x63610000u, 46u}, // ca -> Latn + {0xB4020000u, 46u}, // can -> Latn + {0xA4220000u, 46u}, // cbj -> Latn + {0x9C420000u, 46u}, // cch -> Latn {0xBC420000u, 9u}, // ccp -> Cakm - {0x63650000u, 16u}, // ce -> Cyrl - {0x84820000u, 44u}, // ceb -> Latn - {0x80A20000u, 44u}, // cfa -> Latn - {0x98C20000u, 44u}, // cgg -> Latn - {0x63680000u, 44u}, // ch -> Latn - {0xA8E20000u, 44u}, // chk -> Latn - {0xB0E20000u, 16u}, // chm -> Cyrl - {0xB8E20000u, 44u}, // cho -> Latn - {0xBCE20000u, 44u}, // chp -> Latn + {0x63650000u, 17u}, // ce -> Cyrl + {0x84820000u, 46u}, // ceb -> Latn + {0x80A20000u, 46u}, // cfa -> Latn + {0x98C20000u, 46u}, // cgg -> Latn + {0x63680000u, 46u}, // ch -> Latn + {0xA8E20000u, 46u}, // chk -> Latn + {0xB0E20000u, 17u}, // chm -> Cyrl + {0xB8E20000u, 46u}, // cho -> Latn + {0xBCE20000u, 46u}, // chp -> Latn {0xC4E20000u, 13u}, // chr -> Cher - {0x89020000u, 44u}, // cic -> Latn + {0x89020000u, 46u}, // cic -> Latn {0x81220000u, 1u}, // cja -> Arab {0xB1220000u, 12u}, // cjm -> Cham - {0xD5220000u, 44u}, // cjv -> Latn + {0xD5220000u, 46u}, // cjv -> Latn {0x85420000u, 1u}, // ckb -> Arab - {0xAD420000u, 44u}, // ckl -> Latn - {0xB9420000u, 44u}, // cko -> Latn - {0xE1420000u, 44u}, // cky -> Latn - {0x81620000u, 44u}, // cla -> Latn - {0x91820000u, 44u}, // cme -> Latn - {0x99820000u, 77u}, // cmg -> Soyo - {0x636F0000u, 44u}, // co -> Latn - {0xBDC20000u, 14u}, // cop -> Copt - {0xC9E20000u, 44u}, // cps -> Latn + {0xAD420000u, 46u}, // ckl -> Latn + {0xB9420000u, 46u}, // cko -> Latn + {0xE1420000u, 46u}, // cky -> Latn + {0x81620000u, 46u}, // cla -> Latn + {0x91820000u, 46u}, // cme -> Latn + {0x99820000u, 79u}, // cmg -> Soyo + {0x636F0000u, 46u}, // co -> Latn + {0xBDC20000u, 15u}, // cop -> Copt + {0xC9E20000u, 46u}, // cps -> Latn {0x63720000u, 10u}, // cr -> Cans - {0x9E220000u, 16u}, // crh -> Cyrl + {0x9E220000u, 17u}, // crh -> Cyrl {0xA6220000u, 10u}, // crj -> Cans {0xAA220000u, 10u}, // crk -> Cans {0xAE220000u, 10u}, // crl -> Cans {0xB2220000u, 10u}, // crm -> Cans - {0xCA220000u, 44u}, // crs -> Latn - {0x63730000u, 44u}, // cs -> Latn - {0x86420000u, 44u}, // csb -> Latn + {0xCA220000u, 46u}, // crs -> Latn + {0x63730000u, 46u}, // cs -> Latn + {0x86420000u, 46u}, // csb -> Latn {0xDA420000u, 10u}, // csw -> Cans - {0x8E620000u, 64u}, // ctd -> Pauc - {0x63750000u, 16u}, // cu -> Cyrl - {0x63760000u, 16u}, // cv -> Cyrl - {0x63790000u, 44u}, // cy -> Latn - {0x64610000u, 44u}, // da -> Latn - {0x8C030000u, 44u}, // dad -> Latn - {0x94030000u, 44u}, // daf -> Latn - {0x98030000u, 44u}, // dag -> Latn - {0x9C030000u, 44u}, // dah -> Latn - {0xA8030000u, 44u}, // dak -> Latn - {0xC4030000u, 16u}, // dar -> Cyrl - {0xD4030000u, 44u}, // dav -> Latn - {0x8C230000u, 44u}, // dbd -> Latn - {0xC0230000u, 44u}, // dbq -> Latn + {0x8E620000u, 66u}, // ctd -> Pauc + {0x63750000u, 17u}, // cu -> Cyrl + {0x63760000u, 17u}, // cv -> Cyrl + {0x63790000u, 46u}, // cy -> Latn + {0x64610000u, 46u}, // da -> Latn + {0x8C030000u, 46u}, // dad -> Latn + {0x94030000u, 46u}, // daf -> Latn + {0x98030000u, 46u}, // dag -> Latn + {0x9C030000u, 46u}, // dah -> Latn + {0xA8030000u, 46u}, // dak -> Latn + {0xC4030000u, 17u}, // dar -> Cyrl + {0xD4030000u, 46u}, // dav -> Latn + {0x8C230000u, 46u}, // dbd -> Latn + {0xC0230000u, 46u}, // dbq -> Latn {0x88430000u, 1u}, // dcc -> Arab - {0xB4630000u, 44u}, // ddn -> Latn - {0x64650000u, 44u}, // de -> Latn - {0x8C830000u, 44u}, // ded -> Latn - {0xB4830000u, 44u}, // den -> Latn - {0x80C30000u, 44u}, // dga -> Latn - {0x9CC30000u, 44u}, // dgh -> Latn - {0xA0C30000u, 44u}, // dgi -> Latn + {0xB4630000u, 46u}, // ddn -> Latn + {0x64650000u, 46u}, // de -> Latn + {0x8C830000u, 46u}, // ded -> Latn + {0xB4830000u, 46u}, // den -> Latn + {0x80C30000u, 46u}, // dga -> Latn + {0x9CC30000u, 46u}, // dgh -> Latn + {0xA0C30000u, 46u}, // dgi -> Latn {0xACC30000u, 1u}, // dgl -> Arab - {0xC4C30000u, 44u}, // dgr -> Latn - {0xE4C30000u, 44u}, // dgz -> Latn - {0x81030000u, 44u}, // dia -> Latn - {0x91230000u, 44u}, // dje -> Latn - {0xA5A30000u, 44u}, // dnj -> Latn - {0x85C30000u, 44u}, // dob -> Latn + {0xC4C30000u, 46u}, // dgr -> Latn + {0xE4C30000u, 46u}, // dgz -> Latn + {0x81030000u, 46u}, // dia -> Latn + {0x91230000u, 46u}, // dje -> Latn + {0xA5A30000u, 46u}, // dnj -> Latn + {0x85C30000u, 46u}, // dob -> Latn {0xA1C30000u, 1u}, // doi -> Arab - {0xBDC30000u, 44u}, // dop -> Latn - {0xD9C30000u, 44u}, // dow -> Latn - {0x9E230000u, 54u}, // drh -> Mong - {0xA2230000u, 44u}, // dri -> Latn - {0xCA230000u, 19u}, // drs -> Ethi - {0x86430000u, 44u}, // dsb -> Latn - {0xB2630000u, 44u}, // dtm -> Latn - {0xBE630000u, 44u}, // dtp -> Latn - {0xCA630000u, 44u}, // dts -> Latn - {0xE2630000u, 17u}, // dty -> Deva - {0x82830000u, 44u}, // dua -> Latn - {0x8A830000u, 44u}, // duc -> Latn - {0x8E830000u, 44u}, // dud -> Latn - {0x9A830000u, 44u}, // dug -> Latn - {0x64760000u, 86u}, // dv -> Thaa - {0x82A30000u, 44u}, // dva -> Latn - {0xDAC30000u, 44u}, // dww -> Latn - {0xBB030000u, 44u}, // dyo -> Latn - {0xD3030000u, 44u}, // dyu -> Latn - {0x647A0000u, 88u}, // dz -> Tibt - {0x9B230000u, 44u}, // dzg -> Latn - {0xD0240000u, 44u}, // ebu -> Latn - {0x65650000u, 44u}, // ee -> Latn - {0xA0A40000u, 44u}, // efi -> Latn - {0xACC40000u, 44u}, // egl -> Latn - {0xE0C40000u, 18u}, // egy -> Egyp - {0x81440000u, 44u}, // eka -> Latn - {0xE1440000u, 36u}, // eky -> Kali - {0x656C0000u, 24u}, // el -> Grek - {0x81840000u, 44u}, // ema -> Latn - {0xA1840000u, 44u}, // emi -> Latn - {0x656E0000u, 44u}, // en -> Latn - {0x656E5841u, 95u}, // en-XA -> ~~~A - {0xB5A40000u, 44u}, // enn -> Latn - {0xC1A40000u, 44u}, // enq -> Latn - {0x656F0000u, 44u}, // eo -> Latn - {0xA2240000u, 44u}, // eri -> Latn - {0x65730000u, 44u}, // es -> Latn - {0x9A440000u, 22u}, // esg -> Gonm - {0xD2440000u, 44u}, // esu -> Latn - {0x65740000u, 44u}, // et -> Latn - {0xC6640000u, 44u}, // etr -> Latn - {0xCE640000u, 34u}, // ett -> Ital - {0xD2640000u, 44u}, // etu -> Latn - {0xDE640000u, 44u}, // etx -> Latn - {0x65750000u, 44u}, // eu -> Latn - {0xBAC40000u, 44u}, // ewo -> Latn - {0xCEE40000u, 44u}, // ext -> Latn + {0xBDC30000u, 46u}, // dop -> Latn + {0xD9C30000u, 46u}, // dow -> Latn + {0x9E230000u, 56u}, // drh -> Mong + {0xA2230000u, 46u}, // dri -> Latn + {0xCA230000u, 20u}, // drs -> Ethi + {0x86430000u, 46u}, // dsb -> Latn + {0xB2630000u, 46u}, // dtm -> Latn + {0xBE630000u, 46u}, // dtp -> Latn + {0xCA630000u, 46u}, // dts -> Latn + {0xE2630000u, 18u}, // dty -> Deva + {0x82830000u, 46u}, // dua -> Latn + {0x8A830000u, 46u}, // duc -> Latn + {0x8E830000u, 46u}, // dud -> Latn + {0x9A830000u, 46u}, // dug -> Latn + {0x64760000u, 88u}, // dv -> Thaa + {0x82A30000u, 46u}, // dva -> Latn + {0xDAC30000u, 46u}, // dww -> Latn + {0xBB030000u, 46u}, // dyo -> Latn + {0xD3030000u, 46u}, // dyu -> Latn + {0x647A0000u, 90u}, // dz -> Tibt + {0x9B230000u, 46u}, // dzg -> Latn + {0xD0240000u, 46u}, // ebu -> Latn + {0x65650000u, 46u}, // ee -> Latn + {0xA0A40000u, 46u}, // efi -> Latn + {0xACC40000u, 46u}, // egl -> Latn + {0xE0C40000u, 19u}, // egy -> Egyp + {0x81440000u, 46u}, // eka -> Latn + {0xE1440000u, 37u}, // eky -> Kali + {0x656C0000u, 25u}, // el -> Grek + {0x81840000u, 46u}, // ema -> Latn + {0xA1840000u, 46u}, // emi -> Latn + {0x656E0000u, 46u}, // en -> Latn + {0x656E5841u, 97u}, // en-XA -> ~~~A + {0xB5A40000u, 46u}, // enn -> Latn + {0xC1A40000u, 46u}, // enq -> Latn + {0x656F0000u, 46u}, // eo -> Latn + {0xA2240000u, 46u}, // eri -> Latn + {0x65730000u, 46u}, // es -> Latn + {0x9A440000u, 23u}, // esg -> Gonm + {0xD2440000u, 46u}, // esu -> Latn + {0x65740000u, 46u}, // et -> Latn + {0xC6640000u, 46u}, // etr -> Latn + {0xCE640000u, 35u}, // ett -> Ital + {0xD2640000u, 46u}, // etu -> Latn + {0xDE640000u, 46u}, // etx -> Latn + {0x65750000u, 46u}, // eu -> Latn + {0xBAC40000u, 46u}, // ewo -> Latn + {0xCEE40000u, 46u}, // ext -> Latn {0x66610000u, 1u}, // fa -> Arab - {0x80050000u, 44u}, // faa -> Latn - {0x84050000u, 44u}, // fab -> Latn - {0x98050000u, 44u}, // fag -> Latn - {0xA0050000u, 44u}, // fai -> Latn - {0xB4050000u, 44u}, // fan -> Latn - {0x66660000u, 44u}, // ff -> Latn - {0xA0A50000u, 44u}, // ffi -> Latn - {0xB0A50000u, 44u}, // ffm -> Latn - {0x66690000u, 44u}, // fi -> Latn + {0x80050000u, 46u}, // faa -> Latn + {0x84050000u, 46u}, // fab -> Latn + {0x98050000u, 46u}, // fag -> Latn + {0xA0050000u, 46u}, // fai -> Latn + {0xB4050000u, 46u}, // fan -> Latn + {0x66660000u, 46u}, // ff -> Latn + {0xA0A50000u, 46u}, // ffi -> Latn + {0xB0A50000u, 46u}, // ffm -> Latn + {0x66690000u, 46u}, // fi -> Latn {0x81050000u, 1u}, // fia -> Arab - {0xAD050000u, 44u}, // fil -> Latn - {0xCD050000u, 44u}, // fit -> Latn - {0x666A0000u, 44u}, // fj -> Latn - {0xC5650000u, 44u}, // flr -> Latn - {0xBD850000u, 44u}, // fmp -> Latn - {0x666F0000u, 44u}, // fo -> Latn - {0x8DC50000u, 44u}, // fod -> Latn - {0xB5C50000u, 44u}, // fon -> Latn - {0xC5C50000u, 44u}, // for -> Latn - {0x91E50000u, 44u}, // fpe -> Latn - {0xCA050000u, 44u}, // fqs -> Latn - {0x66720000u, 44u}, // fr -> Latn - {0x8A250000u, 44u}, // frc -> Latn - {0xBE250000u, 44u}, // frp -> Latn - {0xC6250000u, 44u}, // frr -> Latn - {0xCA250000u, 44u}, // frs -> Latn + {0xAD050000u, 46u}, // fil -> Latn + {0xCD050000u, 46u}, // fit -> Latn + {0x666A0000u, 46u}, // fj -> Latn + {0xC5650000u, 46u}, // flr -> Latn + {0xBD850000u, 46u}, // fmp -> Latn + {0x666F0000u, 46u}, // fo -> Latn + {0x8DC50000u, 46u}, // fod -> Latn + {0xB5C50000u, 46u}, // fon -> Latn + {0xC5C50000u, 46u}, // for -> Latn + {0x91E50000u, 46u}, // fpe -> Latn + {0xCA050000u, 46u}, // fqs -> Latn + {0x66720000u, 46u}, // fr -> Latn + {0x8A250000u, 46u}, // frc -> Latn + {0xBE250000u, 46u}, // frp -> Latn + {0xC6250000u, 46u}, // frr -> Latn + {0xCA250000u, 46u}, // frs -> Latn {0x86850000u, 1u}, // fub -> Arab - {0x8E850000u, 44u}, // fud -> Latn - {0x92850000u, 44u}, // fue -> Latn - {0x96850000u, 44u}, // fuf -> Latn - {0x9E850000u, 44u}, // fuh -> Latn - {0xC2850000u, 44u}, // fuq -> Latn - {0xC6850000u, 44u}, // fur -> Latn - {0xD6850000u, 44u}, // fuv -> Latn - {0xE2850000u, 44u}, // fuy -> Latn - {0xC6A50000u, 44u}, // fvr -> Latn - {0x66790000u, 44u}, // fy -> Latn - {0x67610000u, 44u}, // ga -> Latn - {0x80060000u, 44u}, // gaa -> Latn - {0x94060000u, 44u}, // gaf -> Latn - {0x98060000u, 44u}, // gag -> Latn - {0x9C060000u, 44u}, // gah -> Latn - {0xA4060000u, 44u}, // gaj -> Latn - {0xB0060000u, 44u}, // gam -> Latn - {0xB4060000u, 27u}, // gan -> Hans - {0xD8060000u, 44u}, // gaw -> Latn - {0xE0060000u, 44u}, // gay -> Latn - {0x80260000u, 44u}, // gba -> Latn - {0x94260000u, 44u}, // gbf -> Latn - {0xB0260000u, 17u}, // gbm -> Deva - {0xE0260000u, 44u}, // gby -> Latn + {0x8E850000u, 46u}, // fud -> Latn + {0x92850000u, 46u}, // fue -> Latn + {0x96850000u, 46u}, // fuf -> Latn + {0x9E850000u, 46u}, // fuh -> Latn + {0xC2850000u, 46u}, // fuq -> Latn + {0xC6850000u, 46u}, // fur -> Latn + {0xD6850000u, 46u}, // fuv -> Latn + {0xE2850000u, 46u}, // fuy -> Latn + {0xC6A50000u, 46u}, // fvr -> Latn + {0x66790000u, 46u}, // fy -> Latn + {0x67610000u, 46u}, // ga -> Latn + {0x80060000u, 46u}, // gaa -> Latn + {0x94060000u, 46u}, // gaf -> Latn + {0x98060000u, 46u}, // gag -> Latn + {0x9C060000u, 46u}, // gah -> Latn + {0xA4060000u, 46u}, // gaj -> Latn + {0xB0060000u, 46u}, // gam -> Latn + {0xB4060000u, 28u}, // gan -> Hans + {0xD8060000u, 46u}, // gaw -> Latn + {0xE0060000u, 46u}, // gay -> Latn + {0x80260000u, 46u}, // gba -> Latn + {0x94260000u, 46u}, // gbf -> Latn + {0xB0260000u, 18u}, // gbm -> Deva + {0xE0260000u, 46u}, // gby -> Latn {0xE4260000u, 1u}, // gbz -> Arab - {0xC4460000u, 44u}, // gcr -> Latn - {0x67640000u, 44u}, // gd -> Latn - {0x90660000u, 44u}, // gde -> Latn - {0xB4660000u, 44u}, // gdn -> Latn - {0xC4660000u, 44u}, // gdr -> Latn - {0x84860000u, 44u}, // geb -> Latn - {0xA4860000u, 44u}, // gej -> Latn - {0xAC860000u, 44u}, // gel -> Latn - {0xE4860000u, 19u}, // gez -> Ethi - {0xA8A60000u, 44u}, // gfk -> Latn - {0xB4C60000u, 17u}, // ggn -> Deva - {0xC8E60000u, 44u}, // ghs -> Latn - {0xAD060000u, 44u}, // gil -> Latn - {0xB1060000u, 44u}, // gim -> Latn + {0xC4460000u, 46u}, // gcr -> Latn + {0x67640000u, 46u}, // gd -> Latn + {0x90660000u, 46u}, // gde -> Latn + {0xB4660000u, 46u}, // gdn -> Latn + {0xC4660000u, 46u}, // gdr -> Latn + {0x84860000u, 46u}, // geb -> Latn + {0xA4860000u, 46u}, // gej -> Latn + {0xAC860000u, 46u}, // gel -> Latn + {0xE4860000u, 20u}, // gez -> Ethi + {0xA8A60000u, 46u}, // gfk -> Latn + {0xB4C60000u, 18u}, // ggn -> Deva + {0xC8E60000u, 46u}, // ghs -> Latn + {0xAD060000u, 46u}, // gil -> Latn + {0xB1060000u, 46u}, // gim -> Latn {0xA9260000u, 1u}, // gjk -> Arab - {0xB5260000u, 44u}, // gjn -> Latn + {0xB5260000u, 46u}, // gjn -> Latn {0xD1260000u, 1u}, // gju -> Arab - {0xB5460000u, 44u}, // gkn -> Latn - {0xBD460000u, 44u}, // gkp -> Latn - {0x676C0000u, 44u}, // gl -> Latn + {0xB5460000u, 46u}, // gkn -> Latn + {0xBD460000u, 46u}, // gkp -> Latn + {0x676C0000u, 46u}, // gl -> Latn {0xA9660000u, 1u}, // glk -> Arab - {0xB1860000u, 44u}, // gmm -> Latn - {0xD5860000u, 19u}, // gmv -> Ethi - {0x676E0000u, 44u}, // gn -> Latn - {0x8DA60000u, 44u}, // gnd -> Latn - {0x99A60000u, 44u}, // gng -> Latn - {0x8DC60000u, 44u}, // god -> Latn - {0x95C60000u, 19u}, // gof -> Ethi - {0xA1C60000u, 44u}, // goi -> Latn - {0xB1C60000u, 17u}, // gom -> Deva - {0xB5C60000u, 84u}, // gon -> Telu - {0xC5C60000u, 44u}, // gor -> Latn - {0xC9C60000u, 44u}, // gos -> Latn - {0xCDC60000u, 23u}, // got -> Goth - {0x86260000u, 44u}, // grb -> Latn - {0x8A260000u, 15u}, // grc -> Cprt + {0xB1860000u, 46u}, // gmm -> Latn + {0xD5860000u, 20u}, // gmv -> Ethi + {0x676E0000u, 46u}, // gn -> Latn + {0x8DA60000u, 46u}, // gnd -> Latn + {0x99A60000u, 46u}, // gng -> Latn + {0x8DC60000u, 46u}, // god -> Latn + {0x95C60000u, 20u}, // gof -> Ethi + {0xA1C60000u, 46u}, // goi -> Latn + {0xB1C60000u, 18u}, // gom -> Deva + {0xB5C60000u, 86u}, // gon -> Telu + {0xC5C60000u, 46u}, // gor -> Latn + {0xC9C60000u, 46u}, // gos -> Latn + {0xCDC60000u, 24u}, // got -> Goth + {0x86260000u, 46u}, // grb -> Latn + {0x8A260000u, 16u}, // grc -> Cprt {0xCE260000u, 7u}, // grt -> Beng - {0xDA260000u, 44u}, // grw -> Latn - {0xDA460000u, 44u}, // gsw -> Latn - {0x67750000u, 25u}, // gu -> Gujr - {0x86860000u, 44u}, // gub -> Latn - {0x8A860000u, 44u}, // guc -> Latn - {0x8E860000u, 44u}, // gud -> Latn - {0xC6860000u, 44u}, // gur -> Latn - {0xDA860000u, 44u}, // guw -> Latn - {0xDE860000u, 44u}, // gux -> Latn - {0xE6860000u, 44u}, // guz -> Latn - {0x67760000u, 44u}, // gv -> Latn - {0x96A60000u, 44u}, // gvf -> Latn - {0xC6A60000u, 17u}, // gvr -> Deva - {0xCAA60000u, 44u}, // gvs -> Latn + {0xDA260000u, 46u}, // grw -> Latn + {0xDA460000u, 46u}, // gsw -> Latn + {0x67750000u, 26u}, // gu -> Gujr + {0x86860000u, 46u}, // gub -> Latn + {0x8A860000u, 46u}, // guc -> Latn + {0x8E860000u, 46u}, // gud -> Latn + {0xC6860000u, 46u}, // gur -> Latn + {0xDA860000u, 46u}, // guw -> Latn + {0xDE860000u, 46u}, // gux -> Latn + {0xE6860000u, 46u}, // guz -> Latn + {0x67760000u, 46u}, // gv -> Latn + {0x96A60000u, 46u}, // gvf -> Latn + {0xC6A60000u, 18u}, // gvr -> Deva + {0xCAA60000u, 46u}, // gvs -> Latn {0x8AC60000u, 1u}, // gwc -> Arab - {0xA2C60000u, 44u}, // gwi -> Latn + {0xA2C60000u, 46u}, // gwi -> Latn {0xCEC60000u, 1u}, // gwt -> Arab - {0xA3060000u, 44u}, // gyi -> Latn - {0x68610000u, 44u}, // ha -> Latn + {0xA3060000u, 46u}, // gyi -> Latn + {0x68610000u, 46u}, // ha -> Latn {0x6861434Du, 1u}, // ha-CM -> Arab {0x68615344u, 1u}, // ha-SD -> Arab - {0x98070000u, 44u}, // hag -> Latn - {0xA8070000u, 27u}, // hak -> Hans - {0xB0070000u, 44u}, // ham -> Latn - {0xD8070000u, 44u}, // haw -> Latn + {0x98070000u, 46u}, // hag -> Latn + {0xA8070000u, 28u}, // hak -> Hans + {0xB0070000u, 46u}, // ham -> Latn + {0xD8070000u, 46u}, // haw -> Latn {0xE4070000u, 1u}, // haz -> Arab - {0x84270000u, 44u}, // hbb -> Latn - {0xE0670000u, 19u}, // hdy -> Ethi - {0x68650000u, 30u}, // he -> Hebr - {0xE0E70000u, 44u}, // hhy -> Latn - {0x68690000u, 17u}, // hi -> Deva - {0x81070000u, 44u}, // hia -> Latn - {0x95070000u, 44u}, // hif -> Latn - {0x99070000u, 44u}, // hig -> Latn - {0x9D070000u, 44u}, // hih -> Latn - {0xAD070000u, 44u}, // hil -> Latn - {0x81670000u, 44u}, // hla -> Latn - {0xD1670000u, 31u}, // hlu -> Hluw - {0x8D870000u, 67u}, // hmd -> Plrd - {0xCD870000u, 44u}, // hmt -> Latn + {0x84270000u, 46u}, // hbb -> Latn + {0xE0670000u, 20u}, // hdy -> Ethi + {0x68650000u, 31u}, // he -> Hebr + {0xE0E70000u, 46u}, // hhy -> Latn + {0x68690000u, 18u}, // hi -> Deva + {0x81070000u, 46u}, // hia -> Latn + {0x95070000u, 46u}, // hif -> Latn + {0x99070000u, 46u}, // hig -> Latn + {0x9D070000u, 46u}, // hih -> Latn + {0xAD070000u, 46u}, // hil -> Latn + {0x81670000u, 46u}, // hla -> Latn + {0xD1670000u, 32u}, // hlu -> Hluw + {0x8D870000u, 69u}, // hmd -> Plrd + {0xCD870000u, 46u}, // hmt -> Latn {0x8DA70000u, 1u}, // hnd -> Arab - {0x91A70000u, 17u}, // hne -> Deva - {0xA5A70000u, 32u}, // hnj -> Hmng - {0xB5A70000u, 44u}, // hnn -> Latn + {0x91A70000u, 18u}, // hne -> Deva + {0xA5A70000u, 33u}, // hnj -> Hmng + {0xB5A70000u, 46u}, // hnn -> Latn {0xB9A70000u, 1u}, // hno -> Arab - {0x686F0000u, 44u}, // ho -> Latn - {0x89C70000u, 17u}, // hoc -> Deva - {0xA5C70000u, 17u}, // hoj -> Deva - {0xCDC70000u, 44u}, // hot -> Latn - {0x68720000u, 44u}, // hr -> Latn - {0x86470000u, 44u}, // hsb -> Latn - {0xB6470000u, 27u}, // hsn -> Hans - {0x68740000u, 44u}, // ht -> Latn - {0x68750000u, 44u}, // hu -> Latn - {0xA2870000u, 44u}, // hui -> Latn + {0x686F0000u, 46u}, // ho -> Latn + {0x89C70000u, 18u}, // hoc -> Deva + {0xA5C70000u, 18u}, // hoj -> Deva + {0xCDC70000u, 46u}, // hot -> Latn + {0x68720000u, 46u}, // hr -> Latn + {0x86470000u, 46u}, // hsb -> Latn + {0xB6470000u, 28u}, // hsn -> Hans + {0x68740000u, 46u}, // ht -> Latn + {0x68750000u, 46u}, // hu -> Latn + {0xA2870000u, 46u}, // hui -> Latn {0x68790000u, 3u}, // hy -> Armn - {0x687A0000u, 44u}, // hz -> Latn - {0x69610000u, 44u}, // ia -> Latn - {0xB4080000u, 44u}, // ian -> Latn - {0xC4080000u, 44u}, // iar -> Latn - {0x80280000u, 44u}, // iba -> Latn - {0x84280000u, 44u}, // ibb -> Latn - {0xE0280000u, 44u}, // iby -> Latn - {0x80480000u, 44u}, // ica -> Latn - {0x9C480000u, 44u}, // ich -> Latn - {0x69640000u, 44u}, // id -> Latn - {0x8C680000u, 44u}, // idd -> Latn - {0xA0680000u, 44u}, // idi -> Latn - {0xD0680000u, 44u}, // idu -> Latn - {0x90A80000u, 44u}, // ife -> Latn - {0x69670000u, 44u}, // ig -> Latn - {0x84C80000u, 44u}, // igb -> Latn - {0x90C80000u, 44u}, // ige -> Latn - {0x69690000u, 94u}, // ii -> Yiii - {0xA5280000u, 44u}, // ijj -> Latn - {0x696B0000u, 44u}, // ik -> Latn - {0xA9480000u, 44u}, // ikk -> Latn - {0xCD480000u, 44u}, // ikt -> Latn - {0xD9480000u, 44u}, // ikw -> Latn - {0xDD480000u, 44u}, // ikx -> Latn - {0xB9680000u, 44u}, // ilo -> Latn - {0xB9880000u, 44u}, // imo -> Latn - {0x696E0000u, 44u}, // in -> Latn - {0x9DA80000u, 16u}, // inh -> Cyrl - {0x696F0000u, 44u}, // io -> Latn - {0xD1C80000u, 44u}, // iou -> Latn - {0xA2280000u, 44u}, // iri -> Latn - {0x69730000u, 44u}, // is -> Latn - {0x69740000u, 44u}, // it -> Latn + {0x687A0000u, 46u}, // hz -> Latn + {0x69610000u, 46u}, // ia -> Latn + {0xB4080000u, 46u}, // ian -> Latn + {0xC4080000u, 46u}, // iar -> Latn + {0x80280000u, 46u}, // iba -> Latn + {0x84280000u, 46u}, // ibb -> Latn + {0xE0280000u, 46u}, // iby -> Latn + {0x80480000u, 46u}, // ica -> Latn + {0x9C480000u, 46u}, // ich -> Latn + {0x69640000u, 46u}, // id -> Latn + {0x8C680000u, 46u}, // idd -> Latn + {0xA0680000u, 46u}, // idi -> Latn + {0xD0680000u, 46u}, // idu -> Latn + {0x90A80000u, 46u}, // ife -> Latn + {0x69670000u, 46u}, // ig -> Latn + {0x84C80000u, 46u}, // igb -> Latn + {0x90C80000u, 46u}, // ige -> Latn + {0x69690000u, 96u}, // ii -> Yiii + {0xA5280000u, 46u}, // ijj -> Latn + {0x696B0000u, 46u}, // ik -> Latn + {0xA9480000u, 46u}, // ikk -> Latn + {0xCD480000u, 46u}, // ikt -> Latn + {0xD9480000u, 46u}, // ikw -> Latn + {0xDD480000u, 46u}, // ikx -> Latn + {0xB9680000u, 46u}, // ilo -> Latn + {0xB9880000u, 46u}, // imo -> Latn + {0x696E0000u, 46u}, // in -> Latn + {0x9DA80000u, 17u}, // inh -> Cyrl + {0x696F0000u, 46u}, // io -> Latn + {0xD1C80000u, 46u}, // iou -> Latn + {0xA2280000u, 46u}, // iri -> Latn + {0x69730000u, 46u}, // is -> Latn + {0x69740000u, 46u}, // it -> Latn {0x69750000u, 10u}, // iu -> Cans - {0x69770000u, 30u}, // iw -> Hebr - {0xB2C80000u, 44u}, // iwm -> Latn - {0xCAC80000u, 44u}, // iws -> Latn - {0x9F280000u, 44u}, // izh -> Latn - {0xA3280000u, 44u}, // izi -> Latn - {0x6A610000u, 35u}, // ja -> Jpan - {0x84090000u, 44u}, // jab -> Latn - {0xB0090000u, 44u}, // jam -> Latn - {0xB8290000u, 44u}, // jbo -> Latn - {0xD0290000u, 44u}, // jbu -> Latn - {0xB4890000u, 44u}, // jen -> Latn - {0xA8C90000u, 44u}, // jgk -> Latn - {0xB8C90000u, 44u}, // jgo -> Latn - {0x6A690000u, 30u}, // ji -> Hebr - {0x85090000u, 44u}, // jib -> Latn - {0x89890000u, 44u}, // jmc -> Latn - {0xAD890000u, 17u}, // jml -> Deva - {0x82290000u, 44u}, // jra -> Latn - {0xCE890000u, 44u}, // jut -> Latn - {0x6A760000u, 44u}, // jv -> Latn - {0x6A770000u, 44u}, // jw -> Latn - {0x6B610000u, 20u}, // ka -> Geor - {0x800A0000u, 16u}, // kaa -> Cyrl - {0x840A0000u, 44u}, // kab -> Latn - {0x880A0000u, 44u}, // kac -> Latn - {0x8C0A0000u, 44u}, // kad -> Latn - {0xA00A0000u, 44u}, // kai -> Latn - {0xA40A0000u, 44u}, // kaj -> Latn - {0xB00A0000u, 44u}, // kam -> Latn - {0xB80A0000u, 44u}, // kao -> Latn - {0x8C2A0000u, 16u}, // kbd -> Cyrl - {0xB02A0000u, 44u}, // kbm -> Latn - {0xBC2A0000u, 44u}, // kbp -> Latn - {0xC02A0000u, 44u}, // kbq -> Latn - {0xDC2A0000u, 44u}, // kbx -> Latn + {0x69770000u, 31u}, // iw -> Hebr + {0xB2C80000u, 46u}, // iwm -> Latn + {0xCAC80000u, 46u}, // iws -> Latn + {0x9F280000u, 46u}, // izh -> Latn + {0xA3280000u, 46u}, // izi -> Latn + {0x6A610000u, 36u}, // ja -> Jpan + {0x84090000u, 46u}, // jab -> Latn + {0xB0090000u, 46u}, // jam -> Latn + {0xB8290000u, 46u}, // jbo -> Latn + {0xD0290000u, 46u}, // jbu -> Latn + {0xB4890000u, 46u}, // jen -> Latn + {0xA8C90000u, 46u}, // jgk -> Latn + {0xB8C90000u, 46u}, // jgo -> Latn + {0x6A690000u, 31u}, // ji -> Hebr + {0x85090000u, 46u}, // jib -> Latn + {0x89890000u, 46u}, // jmc -> Latn + {0xAD890000u, 18u}, // jml -> Deva + {0x82290000u, 46u}, // jra -> Latn + {0xCE890000u, 46u}, // jut -> Latn + {0x6A760000u, 46u}, // jv -> Latn + {0x6A770000u, 46u}, // jw -> Latn + {0x6B610000u, 21u}, // ka -> Geor + {0x800A0000u, 17u}, // kaa -> Cyrl + {0x840A0000u, 46u}, // kab -> Latn + {0x880A0000u, 46u}, // kac -> Latn + {0x8C0A0000u, 46u}, // kad -> Latn + {0xA00A0000u, 46u}, // kai -> Latn + {0xA40A0000u, 46u}, // kaj -> Latn + {0xB00A0000u, 46u}, // kam -> Latn + {0xB80A0000u, 46u}, // kao -> Latn + {0x8C2A0000u, 17u}, // kbd -> Cyrl + {0xB02A0000u, 46u}, // kbm -> Latn + {0xBC2A0000u, 46u}, // kbp -> Latn + {0xC02A0000u, 46u}, // kbq -> Latn + {0xDC2A0000u, 46u}, // kbx -> Latn {0xE02A0000u, 1u}, // kby -> Arab - {0x984A0000u, 44u}, // kcg -> Latn - {0xA84A0000u, 44u}, // kck -> Latn - {0xAC4A0000u, 44u}, // kcl -> Latn - {0xCC4A0000u, 44u}, // kct -> Latn - {0x906A0000u, 44u}, // kde -> Latn + {0x984A0000u, 46u}, // kcg -> Latn + {0xA84A0000u, 46u}, // kck -> Latn + {0xAC4A0000u, 46u}, // kcl -> Latn + {0xCC4A0000u, 46u}, // kct -> Latn + {0x906A0000u, 46u}, // kde -> Latn {0x9C6A0000u, 1u}, // kdh -> Arab - {0xAC6A0000u, 44u}, // kdl -> Latn - {0xCC6A0000u, 87u}, // kdt -> Thai - {0x808A0000u, 44u}, // kea -> Latn - {0xB48A0000u, 44u}, // ken -> Latn - {0xE48A0000u, 44u}, // kez -> Latn - {0xB8AA0000u, 44u}, // kfo -> Latn - {0xC4AA0000u, 17u}, // kfr -> Deva - {0xE0AA0000u, 17u}, // kfy -> Deva - {0x6B670000u, 44u}, // kg -> Latn - {0x90CA0000u, 44u}, // kge -> Latn - {0x94CA0000u, 44u}, // kgf -> Latn - {0xBCCA0000u, 44u}, // kgp -> Latn - {0x80EA0000u, 44u}, // kha -> Latn - {0x84EA0000u, 80u}, // khb -> Talu - {0xB4EA0000u, 17u}, // khn -> Deva - {0xC0EA0000u, 44u}, // khq -> Latn - {0xC8EA0000u, 44u}, // khs -> Latn - {0xCCEA0000u, 56u}, // kht -> Mymr + {0xAC6A0000u, 46u}, // kdl -> Latn + {0xCC6A0000u, 89u}, // kdt -> Thai + {0x808A0000u, 46u}, // kea -> Latn + {0xB48A0000u, 46u}, // ken -> Latn + {0xE48A0000u, 46u}, // kez -> Latn + {0xB8AA0000u, 46u}, // kfo -> Latn + {0xC4AA0000u, 18u}, // kfr -> Deva + {0xE0AA0000u, 18u}, // kfy -> Deva + {0x6B670000u, 46u}, // kg -> Latn + {0x90CA0000u, 46u}, // kge -> Latn + {0x94CA0000u, 46u}, // kgf -> Latn + {0xBCCA0000u, 46u}, // kgp -> Latn + {0x80EA0000u, 46u}, // kha -> Latn + {0x84EA0000u, 82u}, // khb -> Talu + {0xB4EA0000u, 18u}, // khn -> Deva + {0xC0EA0000u, 46u}, // khq -> Latn + {0xC8EA0000u, 46u}, // khs -> Latn + {0xCCEA0000u, 58u}, // kht -> Mymr {0xD8EA0000u, 1u}, // khw -> Arab - {0xE4EA0000u, 44u}, // khz -> Latn - {0x6B690000u, 44u}, // ki -> Latn - {0xA50A0000u, 44u}, // kij -> Latn - {0xD10A0000u, 44u}, // kiu -> Latn - {0xD90A0000u, 44u}, // kiw -> Latn - {0x6B6A0000u, 44u}, // kj -> Latn - {0x8D2A0000u, 44u}, // kjd -> Latn - {0x992A0000u, 43u}, // kjg -> Laoo - {0xC92A0000u, 44u}, // kjs -> Latn - {0xE12A0000u, 44u}, // kjy -> Latn - {0x6B6B0000u, 16u}, // kk -> Cyrl + {0xE4EA0000u, 46u}, // khz -> Latn + {0x6B690000u, 46u}, // ki -> Latn + {0xA50A0000u, 46u}, // kij -> Latn + {0xD10A0000u, 46u}, // kiu -> Latn + {0xD90A0000u, 46u}, // kiw -> Latn + {0x6B6A0000u, 46u}, // kj -> Latn + {0x8D2A0000u, 46u}, // kjd -> Latn + {0x992A0000u, 45u}, // kjg -> Laoo + {0xC92A0000u, 46u}, // kjs -> Latn + {0xE12A0000u, 46u}, // kjy -> Latn + {0x6B6B0000u, 17u}, // kk -> Cyrl {0x6B6B4146u, 1u}, // kk-AF -> Arab {0x6B6B434Eu, 1u}, // kk-CN -> Arab {0x6B6B4952u, 1u}, // kk-IR -> Arab {0x6B6B4D4Eu, 1u}, // kk-MN -> Arab - {0x894A0000u, 44u}, // kkc -> Latn - {0xA54A0000u, 44u}, // kkj -> Latn - {0x6B6C0000u, 44u}, // kl -> Latn - {0xB56A0000u, 44u}, // kln -> Latn - {0xC16A0000u, 44u}, // klq -> Latn - {0xCD6A0000u, 44u}, // klt -> Latn - {0xDD6A0000u, 44u}, // klx -> Latn - {0x6B6D0000u, 39u}, // km -> Khmr - {0x858A0000u, 44u}, // kmb -> Latn - {0x9D8A0000u, 44u}, // kmh -> Latn - {0xB98A0000u, 44u}, // kmo -> Latn - {0xC98A0000u, 44u}, // kms -> Latn - {0xD18A0000u, 44u}, // kmu -> Latn - {0xD98A0000u, 44u}, // kmw -> Latn - {0x6B6E0000u, 40u}, // kn -> Knda - {0x95AA0000u, 44u}, // knf -> Latn - {0xBDAA0000u, 44u}, // knp -> Latn - {0x6B6F0000u, 41u}, // ko -> Kore - {0xA1CA0000u, 16u}, // koi -> Cyrl - {0xA9CA0000u, 17u}, // kok -> Deva - {0xADCA0000u, 44u}, // kol -> Latn - {0xC9CA0000u, 44u}, // kos -> Latn - {0xE5CA0000u, 44u}, // koz -> Latn - {0x91EA0000u, 44u}, // kpe -> Latn - {0x95EA0000u, 44u}, // kpf -> Latn - {0xB9EA0000u, 44u}, // kpo -> Latn - {0xC5EA0000u, 44u}, // kpr -> Latn - {0xDDEA0000u, 44u}, // kpx -> Latn - {0x860A0000u, 44u}, // kqb -> Latn - {0x960A0000u, 44u}, // kqf -> Latn - {0xCA0A0000u, 44u}, // kqs -> Latn - {0xE20A0000u, 19u}, // kqy -> Ethi - {0x6B720000u, 44u}, // kr -> Latn - {0x8A2A0000u, 16u}, // krc -> Cyrl - {0xA22A0000u, 44u}, // kri -> Latn - {0xA62A0000u, 44u}, // krj -> Latn - {0xAE2A0000u, 44u}, // krl -> Latn - {0xCA2A0000u, 44u}, // krs -> Latn - {0xD22A0000u, 17u}, // kru -> Deva + {0x894A0000u, 46u}, // kkc -> Latn + {0xA54A0000u, 46u}, // kkj -> Latn + {0x6B6C0000u, 46u}, // kl -> Latn + {0xB56A0000u, 46u}, // kln -> Latn + {0xC16A0000u, 46u}, // klq -> Latn + {0xCD6A0000u, 46u}, // klt -> Latn + {0xDD6A0000u, 46u}, // klx -> Latn + {0x6B6D0000u, 40u}, // km -> Khmr + {0x858A0000u, 46u}, // kmb -> Latn + {0x9D8A0000u, 46u}, // kmh -> Latn + {0xB98A0000u, 46u}, // kmo -> Latn + {0xC98A0000u, 46u}, // kms -> Latn + {0xD18A0000u, 46u}, // kmu -> Latn + {0xD98A0000u, 46u}, // kmw -> Latn + {0x6B6E0000u, 42u}, // kn -> Knda + {0x95AA0000u, 46u}, // knf -> Latn + {0xBDAA0000u, 46u}, // knp -> Latn + {0x6B6F0000u, 43u}, // ko -> Kore + {0xA1CA0000u, 17u}, // koi -> Cyrl + {0xA9CA0000u, 18u}, // kok -> Deva + {0xADCA0000u, 46u}, // kol -> Latn + {0xC9CA0000u, 46u}, // kos -> Latn + {0xE5CA0000u, 46u}, // koz -> Latn + {0x91EA0000u, 46u}, // kpe -> Latn + {0x95EA0000u, 46u}, // kpf -> Latn + {0xB9EA0000u, 46u}, // kpo -> Latn + {0xC5EA0000u, 46u}, // kpr -> Latn + {0xDDEA0000u, 46u}, // kpx -> Latn + {0x860A0000u, 46u}, // kqb -> Latn + {0x960A0000u, 46u}, // kqf -> Latn + {0xCA0A0000u, 46u}, // kqs -> Latn + {0xE20A0000u, 20u}, // kqy -> Ethi + {0x6B720000u, 46u}, // kr -> Latn + {0x8A2A0000u, 17u}, // krc -> Cyrl + {0xA22A0000u, 46u}, // kri -> Latn + {0xA62A0000u, 46u}, // krj -> Latn + {0xAE2A0000u, 46u}, // krl -> Latn + {0xCA2A0000u, 46u}, // krs -> Latn + {0xD22A0000u, 18u}, // kru -> Deva {0x6B730000u, 1u}, // ks -> Arab - {0x864A0000u, 44u}, // ksb -> Latn - {0x8E4A0000u, 44u}, // ksd -> Latn - {0x964A0000u, 44u}, // ksf -> Latn - {0x9E4A0000u, 44u}, // ksh -> Latn - {0xA64A0000u, 44u}, // ksj -> Latn - {0xC64A0000u, 44u}, // ksr -> Latn - {0x866A0000u, 19u}, // ktb -> Ethi - {0xB26A0000u, 44u}, // ktm -> Latn - {0xBA6A0000u, 44u}, // kto -> Latn - {0xC66A0000u, 44u}, // ktr -> Latn - {0x6B750000u, 44u}, // ku -> Latn + {0x864A0000u, 46u}, // ksb -> Latn + {0x8E4A0000u, 46u}, // ksd -> Latn + {0x964A0000u, 46u}, // ksf -> Latn + {0x9E4A0000u, 46u}, // ksh -> Latn + {0xA64A0000u, 46u}, // ksj -> Latn + {0xC64A0000u, 46u}, // ksr -> Latn + {0x866A0000u, 20u}, // ktb -> Ethi + {0xB26A0000u, 46u}, // ktm -> Latn + {0xBA6A0000u, 46u}, // kto -> Latn + {0xC66A0000u, 46u}, // ktr -> Latn + {0x6B750000u, 46u}, // ku -> Latn {0x6B754952u, 1u}, // ku-IR -> Arab {0x6B754C42u, 1u}, // ku-LB -> Arab - {0x868A0000u, 44u}, // kub -> Latn - {0x8E8A0000u, 44u}, // kud -> Latn - {0x928A0000u, 44u}, // kue -> Latn - {0xA68A0000u, 44u}, // kuj -> Latn - {0xB28A0000u, 16u}, // kum -> Cyrl - {0xB68A0000u, 44u}, // kun -> Latn - {0xBE8A0000u, 44u}, // kup -> Latn - {0xCA8A0000u, 44u}, // kus -> Latn - {0x6B760000u, 16u}, // kv -> Cyrl - {0x9AAA0000u, 44u}, // kvg -> Latn - {0xC6AA0000u, 44u}, // kvr -> Latn + {0x868A0000u, 46u}, // kub -> Latn + {0x8E8A0000u, 46u}, // kud -> Latn + {0x928A0000u, 46u}, // kue -> Latn + {0xA68A0000u, 46u}, // kuj -> Latn + {0xB28A0000u, 17u}, // kum -> Cyrl + {0xB68A0000u, 46u}, // kun -> Latn + {0xBE8A0000u, 46u}, // kup -> Latn + {0xCA8A0000u, 46u}, // kus -> Latn + {0x6B760000u, 17u}, // kv -> Cyrl + {0x9AAA0000u, 46u}, // kvg -> Latn + {0xC6AA0000u, 46u}, // kvr -> Latn {0xDEAA0000u, 1u}, // kvx -> Arab - {0x6B770000u, 44u}, // kw -> Latn - {0xA6CA0000u, 44u}, // kwj -> Latn - {0xBACA0000u, 44u}, // kwo -> Latn - {0xC2CA0000u, 44u}, // kwq -> Latn - {0x82EA0000u, 44u}, // kxa -> Latn - {0x8AEA0000u, 19u}, // kxc -> Ethi - {0x92EA0000u, 44u}, // kxe -> Latn - {0xB2EA0000u, 87u}, // kxm -> Thai + {0x6B770000u, 46u}, // kw -> Latn + {0xA6CA0000u, 46u}, // kwj -> Latn + {0xBACA0000u, 46u}, // kwo -> Latn + {0xC2CA0000u, 46u}, // kwq -> Latn + {0x82EA0000u, 46u}, // kxa -> Latn + {0x8AEA0000u, 20u}, // kxc -> Ethi + {0x92EA0000u, 46u}, // kxe -> Latn + {0xB2EA0000u, 89u}, // kxm -> Thai {0xBEEA0000u, 1u}, // kxp -> Arab - {0xDAEA0000u, 44u}, // kxw -> Latn - {0xE6EA0000u, 44u}, // kxz -> Latn - {0x6B790000u, 16u}, // ky -> Cyrl + {0xDAEA0000u, 46u}, // kxw -> Latn + {0xE6EA0000u, 46u}, // kxz -> Latn + {0x6B790000u, 17u}, // ky -> Cyrl {0x6B79434Eu, 1u}, // ky-CN -> Arab - {0x6B795452u, 44u}, // ky-TR -> Latn - {0x930A0000u, 44u}, // kye -> Latn - {0xDF0A0000u, 44u}, // kyx -> Latn - {0xA72A0000u, 44u}, // kzj -> Latn - {0xC72A0000u, 44u}, // kzr -> Latn - {0xCF2A0000u, 44u}, // kzt -> Latn - {0x6C610000u, 44u}, // la -> Latn - {0x840B0000u, 46u}, // lab -> Lina - {0x8C0B0000u, 30u}, // lad -> Hebr - {0x980B0000u, 44u}, // lag -> Latn + {0x6B795452u, 46u}, // ky-TR -> Latn + {0x930A0000u, 46u}, // kye -> Latn + {0xDF0A0000u, 46u}, // kyx -> Latn + {0xA72A0000u, 46u}, // kzj -> Latn + {0xC72A0000u, 46u}, // kzr -> Latn + {0xCF2A0000u, 46u}, // kzt -> Latn + {0x6C610000u, 46u}, // la -> Latn + {0x840B0000u, 48u}, // lab -> Lina + {0x8C0B0000u, 31u}, // lad -> Hebr + {0x980B0000u, 46u}, // lag -> Latn {0x9C0B0000u, 1u}, // lah -> Arab - {0xA40B0000u, 44u}, // laj -> Latn - {0xC80B0000u, 44u}, // las -> Latn - {0x6C620000u, 44u}, // lb -> Latn - {0x902B0000u, 16u}, // lbe -> Cyrl - {0xD02B0000u, 44u}, // lbu -> Latn - {0xD82B0000u, 44u}, // lbw -> Latn - {0xB04B0000u, 44u}, // lcm -> Latn - {0xBC4B0000u, 87u}, // lcp -> Thai - {0x846B0000u, 44u}, // ldb -> Latn - {0x8C8B0000u, 44u}, // led -> Latn - {0x908B0000u, 44u}, // lee -> Latn - {0xB08B0000u, 44u}, // lem -> Latn - {0xBC8B0000u, 45u}, // lep -> Lepc - {0xC08B0000u, 44u}, // leq -> Latn - {0xD08B0000u, 44u}, // leu -> Latn - {0xE48B0000u, 16u}, // lez -> Cyrl - {0x6C670000u, 44u}, // lg -> Latn - {0x98CB0000u, 44u}, // lgg -> Latn - {0x6C690000u, 44u}, // li -> Latn - {0x810B0000u, 44u}, // lia -> Latn - {0x8D0B0000u, 44u}, // lid -> Latn - {0x950B0000u, 17u}, // lif -> Deva - {0x990B0000u, 44u}, // lig -> Latn - {0x9D0B0000u, 44u}, // lih -> Latn - {0xA50B0000u, 44u}, // lij -> Latn - {0xC90B0000u, 47u}, // lis -> Lisu - {0xBD2B0000u, 44u}, // ljp -> Latn + {0xA40B0000u, 46u}, // laj -> Latn + {0xC80B0000u, 46u}, // las -> Latn + {0x6C620000u, 46u}, // lb -> Latn + {0x902B0000u, 17u}, // lbe -> Cyrl + {0xD02B0000u, 46u}, // lbu -> Latn + {0xD82B0000u, 46u}, // lbw -> Latn + {0xB04B0000u, 46u}, // lcm -> Latn + {0xBC4B0000u, 89u}, // lcp -> Thai + {0x846B0000u, 46u}, // ldb -> Latn + {0x8C8B0000u, 46u}, // led -> Latn + {0x908B0000u, 46u}, // lee -> Latn + {0xB08B0000u, 46u}, // lem -> Latn + {0xBC8B0000u, 47u}, // lep -> Lepc + {0xC08B0000u, 46u}, // leq -> Latn + {0xD08B0000u, 46u}, // leu -> Latn + {0xE48B0000u, 17u}, // lez -> Cyrl + {0x6C670000u, 46u}, // lg -> Latn + {0x98CB0000u, 46u}, // lgg -> Latn + {0x6C690000u, 46u}, // li -> Latn + {0x810B0000u, 46u}, // lia -> Latn + {0x8D0B0000u, 46u}, // lid -> Latn + {0x950B0000u, 18u}, // lif -> Deva + {0x990B0000u, 46u}, // lig -> Latn + {0x9D0B0000u, 46u}, // lih -> Latn + {0xA50B0000u, 46u}, // lij -> Latn + {0xC90B0000u, 49u}, // lis -> Lisu + {0xBD2B0000u, 46u}, // ljp -> Latn {0xA14B0000u, 1u}, // lki -> Arab - {0xCD4B0000u, 44u}, // lkt -> Latn - {0x916B0000u, 44u}, // lle -> Latn - {0xB56B0000u, 44u}, // lln -> Latn - {0xB58B0000u, 84u}, // lmn -> Telu - {0xB98B0000u, 44u}, // lmo -> Latn - {0xBD8B0000u, 44u}, // lmp -> Latn - {0x6C6E0000u, 44u}, // ln -> Latn - {0xC9AB0000u, 44u}, // lns -> Latn - {0xD1AB0000u, 44u}, // lnu -> Latn - {0x6C6F0000u, 43u}, // lo -> Laoo - {0xA5CB0000u, 44u}, // loj -> Latn - {0xA9CB0000u, 44u}, // lok -> Latn - {0xADCB0000u, 44u}, // lol -> Latn - {0xC5CB0000u, 44u}, // lor -> Latn - {0xC9CB0000u, 44u}, // los -> Latn - {0xE5CB0000u, 44u}, // loz -> Latn + {0xCD4B0000u, 46u}, // lkt -> Latn + {0x916B0000u, 46u}, // lle -> Latn + {0xB56B0000u, 46u}, // lln -> Latn + {0xB58B0000u, 86u}, // lmn -> Telu + {0xB98B0000u, 46u}, // lmo -> Latn + {0xBD8B0000u, 46u}, // lmp -> Latn + {0x6C6E0000u, 46u}, // ln -> Latn + {0xC9AB0000u, 46u}, // lns -> Latn + {0xD1AB0000u, 46u}, // lnu -> Latn + {0x6C6F0000u, 45u}, // lo -> Laoo + {0xA5CB0000u, 46u}, // loj -> Latn + {0xA9CB0000u, 46u}, // lok -> Latn + {0xADCB0000u, 46u}, // lol -> Latn + {0xC5CB0000u, 46u}, // lor -> Latn + {0xC9CB0000u, 46u}, // los -> Latn + {0xE5CB0000u, 46u}, // loz -> Latn {0x8A2B0000u, 1u}, // lrc -> Arab - {0x6C740000u, 44u}, // lt -> Latn - {0x9A6B0000u, 44u}, // ltg -> Latn - {0x6C750000u, 44u}, // lu -> Latn - {0x828B0000u, 44u}, // lua -> Latn - {0xBA8B0000u, 44u}, // luo -> Latn - {0xE28B0000u, 44u}, // luy -> Latn + {0x6C740000u, 46u}, // lt -> Latn + {0x9A6B0000u, 46u}, // ltg -> Latn + {0x6C750000u, 46u}, // lu -> Latn + {0x828B0000u, 46u}, // lua -> Latn + {0xBA8B0000u, 46u}, // luo -> Latn + {0xE28B0000u, 46u}, // luy -> Latn {0xE68B0000u, 1u}, // luz -> Arab - {0x6C760000u, 44u}, // lv -> Latn - {0xAECB0000u, 87u}, // lwl -> Thai - {0x9F2B0000u, 27u}, // lzh -> Hans - {0xE72B0000u, 44u}, // lzz -> Latn - {0x8C0C0000u, 44u}, // mad -> Latn - {0x940C0000u, 44u}, // maf -> Latn - {0x980C0000u, 17u}, // mag -> Deva - {0xA00C0000u, 17u}, // mai -> Deva - {0xA80C0000u, 44u}, // mak -> Latn - {0xB40C0000u, 44u}, // man -> Latn - {0xB40C474Eu, 58u}, // man-GN -> Nkoo - {0xC80C0000u, 44u}, // mas -> Latn - {0xD80C0000u, 44u}, // maw -> Latn - {0xE40C0000u, 44u}, // maz -> Latn - {0x9C2C0000u, 44u}, // mbh -> Latn - {0xB82C0000u, 44u}, // mbo -> Latn - {0xC02C0000u, 44u}, // mbq -> Latn - {0xD02C0000u, 44u}, // mbu -> Latn - {0xD82C0000u, 44u}, // mbw -> Latn - {0xA04C0000u, 44u}, // mci -> Latn - {0xBC4C0000u, 44u}, // mcp -> Latn - {0xC04C0000u, 44u}, // mcq -> Latn - {0xC44C0000u, 44u}, // mcr -> Latn - {0xD04C0000u, 44u}, // mcu -> Latn - {0x806C0000u, 44u}, // mda -> Latn + {0x6C760000u, 46u}, // lv -> Latn + {0xAECB0000u, 89u}, // lwl -> Thai + {0x9F2B0000u, 28u}, // lzh -> Hans + {0xE72B0000u, 46u}, // lzz -> Latn + {0x8C0C0000u, 46u}, // mad -> Latn + {0x940C0000u, 46u}, // maf -> Latn + {0x980C0000u, 18u}, // mag -> Deva + {0xA00C0000u, 18u}, // mai -> Deva + {0xA80C0000u, 46u}, // mak -> Latn + {0xB40C0000u, 46u}, // man -> Latn + {0xB40C474Eu, 60u}, // man-GN -> Nkoo + {0xC80C0000u, 46u}, // mas -> Latn + {0xD80C0000u, 46u}, // maw -> Latn + {0xE40C0000u, 46u}, // maz -> Latn + {0x9C2C0000u, 46u}, // mbh -> Latn + {0xB82C0000u, 46u}, // mbo -> Latn + {0xC02C0000u, 46u}, // mbq -> Latn + {0xD02C0000u, 46u}, // mbu -> Latn + {0xD82C0000u, 46u}, // mbw -> Latn + {0xA04C0000u, 46u}, // mci -> Latn + {0xBC4C0000u, 46u}, // mcp -> Latn + {0xC04C0000u, 46u}, // mcq -> Latn + {0xC44C0000u, 46u}, // mcr -> Latn + {0xD04C0000u, 46u}, // mcu -> Latn + {0x806C0000u, 46u}, // mda -> Latn {0x906C0000u, 1u}, // mde -> Arab - {0x946C0000u, 16u}, // mdf -> Cyrl - {0x9C6C0000u, 44u}, // mdh -> Latn - {0xA46C0000u, 44u}, // mdj -> Latn - {0xC46C0000u, 44u}, // mdr -> Latn - {0xDC6C0000u, 19u}, // mdx -> Ethi - {0x8C8C0000u, 44u}, // med -> Latn - {0x908C0000u, 44u}, // mee -> Latn - {0xA88C0000u, 44u}, // mek -> Latn - {0xB48C0000u, 44u}, // men -> Latn - {0xC48C0000u, 44u}, // mer -> Latn - {0xCC8C0000u, 44u}, // met -> Latn - {0xD08C0000u, 44u}, // meu -> Latn + {0x946C0000u, 17u}, // mdf -> Cyrl + {0x9C6C0000u, 46u}, // mdh -> Latn + {0xA46C0000u, 46u}, // mdj -> Latn + {0xC46C0000u, 46u}, // mdr -> Latn + {0xDC6C0000u, 20u}, // mdx -> Ethi + {0x8C8C0000u, 46u}, // med -> Latn + {0x908C0000u, 46u}, // mee -> Latn + {0xA88C0000u, 46u}, // mek -> Latn + {0xB48C0000u, 46u}, // men -> Latn + {0xC48C0000u, 46u}, // mer -> Latn + {0xCC8C0000u, 46u}, // met -> Latn + {0xD08C0000u, 46u}, // meu -> Latn {0x80AC0000u, 1u}, // mfa -> Arab - {0x90AC0000u, 44u}, // mfe -> Latn - {0xB4AC0000u, 44u}, // mfn -> Latn - {0xB8AC0000u, 44u}, // mfo -> Latn - {0xC0AC0000u, 44u}, // mfq -> Latn - {0x6D670000u, 44u}, // mg -> Latn - {0x9CCC0000u, 44u}, // mgh -> Latn - {0xACCC0000u, 44u}, // mgl -> Latn - {0xB8CC0000u, 44u}, // mgo -> Latn - {0xBCCC0000u, 17u}, // mgp -> Deva - {0xE0CC0000u, 44u}, // mgy -> Latn - {0x6D680000u, 44u}, // mh -> Latn - {0xA0EC0000u, 44u}, // mhi -> Latn - {0xACEC0000u, 44u}, // mhl -> Latn - {0x6D690000u, 44u}, // mi -> Latn - {0x950C0000u, 44u}, // mif -> Latn - {0xB50C0000u, 44u}, // min -> Latn - {0xC90C0000u, 29u}, // mis -> Hatr - {0xD90C0000u, 44u}, // miw -> Latn - {0x6D6B0000u, 16u}, // mk -> Cyrl + {0x90AC0000u, 46u}, // mfe -> Latn + {0xB4AC0000u, 46u}, // mfn -> Latn + {0xB8AC0000u, 46u}, // mfo -> Latn + {0xC0AC0000u, 46u}, // mfq -> Latn + {0x6D670000u, 46u}, // mg -> Latn + {0x9CCC0000u, 46u}, // mgh -> Latn + {0xACCC0000u, 46u}, // mgl -> Latn + {0xB8CC0000u, 46u}, // mgo -> Latn + {0xBCCC0000u, 18u}, // mgp -> Deva + {0xE0CC0000u, 46u}, // mgy -> Latn + {0x6D680000u, 46u}, // mh -> Latn + {0xA0EC0000u, 46u}, // mhi -> Latn + {0xACEC0000u, 46u}, // mhl -> Latn + {0x6D690000u, 46u}, // mi -> Latn + {0x950C0000u, 46u}, // mif -> Latn + {0xB50C0000u, 46u}, // min -> Latn + {0xC90C0000u, 30u}, // mis -> Hatr + {0xD90C0000u, 46u}, // miw -> Latn + {0x6D6B0000u, 17u}, // mk -> Cyrl {0xA14C0000u, 1u}, // mki -> Arab - {0xAD4C0000u, 44u}, // mkl -> Latn - {0xBD4C0000u, 44u}, // mkp -> Latn - {0xD94C0000u, 44u}, // mkw -> Latn - {0x6D6C0000u, 53u}, // ml -> Mlym - {0x916C0000u, 44u}, // mle -> Latn - {0xBD6C0000u, 44u}, // mlp -> Latn - {0xC96C0000u, 44u}, // mls -> Latn - {0xB98C0000u, 44u}, // mmo -> Latn - {0xD18C0000u, 44u}, // mmu -> Latn - {0xDD8C0000u, 44u}, // mmx -> Latn - {0x6D6E0000u, 16u}, // mn -> Cyrl - {0x6D6E434Eu, 54u}, // mn-CN -> Mong - {0x81AC0000u, 44u}, // mna -> Latn - {0x95AC0000u, 44u}, // mnf -> Latn + {0xAD4C0000u, 46u}, // mkl -> Latn + {0xBD4C0000u, 46u}, // mkp -> Latn + {0xD94C0000u, 46u}, // mkw -> Latn + {0x6D6C0000u, 55u}, // ml -> Mlym + {0x916C0000u, 46u}, // mle -> Latn + {0xBD6C0000u, 46u}, // mlp -> Latn + {0xC96C0000u, 46u}, // mls -> Latn + {0xB98C0000u, 46u}, // mmo -> Latn + {0xD18C0000u, 46u}, // mmu -> Latn + {0xDD8C0000u, 46u}, // mmx -> Latn + {0x6D6E0000u, 17u}, // mn -> Cyrl + {0x6D6E434Eu, 56u}, // mn-CN -> Mong + {0x81AC0000u, 46u}, // mna -> Latn + {0x95AC0000u, 46u}, // mnf -> Latn {0xA1AC0000u, 7u}, // mni -> Beng - {0xD9AC0000u, 56u}, // mnw -> Mymr - {0x6D6F0000u, 44u}, // mo -> Latn - {0x81CC0000u, 44u}, // moa -> Latn - {0x91CC0000u, 44u}, // moe -> Latn - {0x9DCC0000u, 44u}, // moh -> Latn - {0xC9CC0000u, 44u}, // mos -> Latn - {0xDDCC0000u, 44u}, // mox -> Latn - {0xBDEC0000u, 44u}, // mpp -> Latn - {0xC9EC0000u, 44u}, // mps -> Latn - {0xCDEC0000u, 44u}, // mpt -> Latn - {0xDDEC0000u, 44u}, // mpx -> Latn - {0xAE0C0000u, 44u}, // mql -> Latn - {0x6D720000u, 17u}, // mr -> Deva - {0x8E2C0000u, 17u}, // mrd -> Deva - {0xA62C0000u, 16u}, // mrj -> Cyrl - {0xBA2C0000u, 55u}, // mro -> Mroo - {0x6D730000u, 44u}, // ms -> Latn + {0xD9AC0000u, 58u}, // mnw -> Mymr + {0x6D6F0000u, 46u}, // mo -> Latn + {0x81CC0000u, 46u}, // moa -> Latn + {0x91CC0000u, 46u}, // moe -> Latn + {0x9DCC0000u, 46u}, // moh -> Latn + {0xC9CC0000u, 46u}, // mos -> Latn + {0xDDCC0000u, 46u}, // mox -> Latn + {0xBDEC0000u, 46u}, // mpp -> Latn + {0xC9EC0000u, 46u}, // mps -> Latn + {0xCDEC0000u, 46u}, // mpt -> Latn + {0xDDEC0000u, 46u}, // mpx -> Latn + {0xAE0C0000u, 46u}, // mql -> Latn + {0x6D720000u, 18u}, // mr -> Deva + {0x8E2C0000u, 18u}, // mrd -> Deva + {0xA62C0000u, 17u}, // mrj -> Cyrl + {0xBA2C0000u, 57u}, // mro -> Mroo + {0x6D730000u, 46u}, // ms -> Latn {0x6D734343u, 1u}, // ms-CC -> Arab {0x6D734944u, 1u}, // ms-ID -> Arab - {0x6D740000u, 44u}, // mt -> Latn - {0x8A6C0000u, 44u}, // mtc -> Latn - {0x966C0000u, 44u}, // mtf -> Latn - {0xA26C0000u, 44u}, // mti -> Latn - {0xC66C0000u, 17u}, // mtr -> Deva - {0x828C0000u, 44u}, // mua -> Latn - {0xC68C0000u, 44u}, // mur -> Latn - {0xCA8C0000u, 44u}, // mus -> Latn - {0x82AC0000u, 44u}, // mva -> Latn - {0xB6AC0000u, 44u}, // mvn -> Latn + {0x6D740000u, 46u}, // mt -> Latn + {0x8A6C0000u, 46u}, // mtc -> Latn + {0x966C0000u, 46u}, // mtf -> Latn + {0xA26C0000u, 46u}, // mti -> Latn + {0xC66C0000u, 18u}, // mtr -> Deva + {0x828C0000u, 46u}, // mua -> Latn + {0xC68C0000u, 46u}, // mur -> Latn + {0xCA8C0000u, 46u}, // mus -> Latn + {0x82AC0000u, 46u}, // mva -> Latn + {0xB6AC0000u, 46u}, // mvn -> Latn {0xE2AC0000u, 1u}, // mvy -> Arab - {0xAACC0000u, 44u}, // mwk -> Latn - {0xC6CC0000u, 17u}, // mwr -> Deva - {0xD6CC0000u, 44u}, // mwv -> Latn - {0xDACC0000u, 33u}, // mww -> Hmnp - {0x8AEC0000u, 44u}, // mxc -> Latn - {0xB2EC0000u, 44u}, // mxm -> Latn - {0x6D790000u, 56u}, // my -> Mymr - {0xAB0C0000u, 44u}, // myk -> Latn - {0xB30C0000u, 19u}, // mym -> Ethi - {0xD70C0000u, 16u}, // myv -> Cyrl - {0xDB0C0000u, 44u}, // myw -> Latn - {0xDF0C0000u, 44u}, // myx -> Latn - {0xE70C0000u, 50u}, // myz -> Mand - {0xAB2C0000u, 44u}, // mzk -> Latn - {0xB32C0000u, 44u}, // mzm -> Latn + {0xAACC0000u, 46u}, // mwk -> Latn + {0xC6CC0000u, 18u}, // mwr -> Deva + {0xD6CC0000u, 46u}, // mwv -> Latn + {0xDACC0000u, 34u}, // mww -> Hmnp + {0x8AEC0000u, 46u}, // mxc -> Latn + {0xB2EC0000u, 46u}, // mxm -> Latn + {0x6D790000u, 58u}, // my -> Mymr + {0xAB0C0000u, 46u}, // myk -> Latn + {0xB30C0000u, 20u}, // mym -> Ethi + {0xD70C0000u, 17u}, // myv -> Cyrl + {0xDB0C0000u, 46u}, // myw -> Latn + {0xDF0C0000u, 46u}, // myx -> Latn + {0xE70C0000u, 52u}, // myz -> Mand + {0xAB2C0000u, 46u}, // mzk -> Latn + {0xB32C0000u, 46u}, // mzm -> Latn {0xB72C0000u, 1u}, // mzn -> Arab - {0xBF2C0000u, 44u}, // mzp -> Latn - {0xDB2C0000u, 44u}, // mzw -> Latn - {0xE72C0000u, 44u}, // mzz -> Latn - {0x6E610000u, 44u}, // na -> Latn - {0x880D0000u, 44u}, // nac -> Latn - {0x940D0000u, 44u}, // naf -> Latn - {0xA80D0000u, 44u}, // nak -> Latn - {0xB40D0000u, 27u}, // nan -> Hans - {0xBC0D0000u, 44u}, // nap -> Latn - {0xC00D0000u, 44u}, // naq -> Latn - {0xC80D0000u, 44u}, // nas -> Latn - {0x6E620000u, 44u}, // nb -> Latn - {0x804D0000u, 44u}, // nca -> Latn - {0x904D0000u, 44u}, // nce -> Latn - {0x944D0000u, 44u}, // ncf -> Latn - {0x9C4D0000u, 44u}, // nch -> Latn - {0xB84D0000u, 44u}, // nco -> Latn - {0xD04D0000u, 44u}, // ncu -> Latn - {0x6E640000u, 44u}, // nd -> Latn - {0x886D0000u, 44u}, // ndc -> Latn - {0xC86D0000u, 44u}, // nds -> Latn - {0x6E650000u, 17u}, // ne -> Deva - {0x848D0000u, 44u}, // neb -> Latn - {0xD88D0000u, 17u}, // new -> Deva - {0xDC8D0000u, 44u}, // nex -> Latn - {0xC4AD0000u, 44u}, // nfr -> Latn - {0x6E670000u, 44u}, // ng -> Latn - {0x80CD0000u, 44u}, // nga -> Latn - {0x84CD0000u, 44u}, // ngb -> Latn - {0xACCD0000u, 44u}, // ngl -> Latn - {0x84ED0000u, 44u}, // nhb -> Latn - {0x90ED0000u, 44u}, // nhe -> Latn - {0xD8ED0000u, 44u}, // nhw -> Latn - {0x950D0000u, 44u}, // nif -> Latn - {0xA10D0000u, 44u}, // nii -> Latn - {0xA50D0000u, 44u}, // nij -> Latn - {0xB50D0000u, 44u}, // nin -> Latn - {0xD10D0000u, 44u}, // niu -> Latn - {0xE10D0000u, 44u}, // niy -> Latn - {0xE50D0000u, 44u}, // niz -> Latn - {0xB92D0000u, 44u}, // njo -> Latn - {0x994D0000u, 44u}, // nkg -> Latn - {0xB94D0000u, 44u}, // nko -> Latn - {0x6E6C0000u, 44u}, // nl -> Latn - {0x998D0000u, 44u}, // nmg -> Latn - {0xE58D0000u, 44u}, // nmz -> Latn - {0x6E6E0000u, 44u}, // nn -> Latn - {0x95AD0000u, 44u}, // nnf -> Latn - {0x9DAD0000u, 44u}, // nnh -> Latn - {0xA9AD0000u, 44u}, // nnk -> Latn - {0xB1AD0000u, 44u}, // nnm -> Latn - {0xBDAD0000u, 91u}, // nnp -> Wcho - {0x6E6F0000u, 44u}, // no -> Latn - {0x8DCD0000u, 42u}, // nod -> Lana - {0x91CD0000u, 17u}, // noe -> Deva - {0xB5CD0000u, 69u}, // non -> Runr - {0xBDCD0000u, 44u}, // nop -> Latn - {0xD1CD0000u, 44u}, // nou -> Latn - {0xBA0D0000u, 58u}, // nqo -> Nkoo - {0x6E720000u, 44u}, // nr -> Latn - {0x862D0000u, 44u}, // nrb -> Latn + {0xBF2C0000u, 46u}, // mzp -> Latn + {0xDB2C0000u, 46u}, // mzw -> Latn + {0xE72C0000u, 46u}, // mzz -> Latn + {0x6E610000u, 46u}, // na -> Latn + {0x880D0000u, 46u}, // nac -> Latn + {0x940D0000u, 46u}, // naf -> Latn + {0xA80D0000u, 46u}, // nak -> Latn + {0xB40D0000u, 28u}, // nan -> Hans + {0xBC0D0000u, 46u}, // nap -> Latn + {0xC00D0000u, 46u}, // naq -> Latn + {0xC80D0000u, 46u}, // nas -> Latn + {0x6E620000u, 46u}, // nb -> Latn + {0x804D0000u, 46u}, // nca -> Latn + {0x904D0000u, 46u}, // nce -> Latn + {0x944D0000u, 46u}, // ncf -> Latn + {0x9C4D0000u, 46u}, // nch -> Latn + {0xB84D0000u, 46u}, // nco -> Latn + {0xD04D0000u, 46u}, // ncu -> Latn + {0x6E640000u, 46u}, // nd -> Latn + {0x886D0000u, 46u}, // ndc -> Latn + {0xC86D0000u, 46u}, // nds -> Latn + {0x6E650000u, 18u}, // ne -> Deva + {0x848D0000u, 46u}, // neb -> Latn + {0xD88D0000u, 18u}, // new -> Deva + {0xDC8D0000u, 46u}, // nex -> Latn + {0xC4AD0000u, 46u}, // nfr -> Latn + {0x6E670000u, 46u}, // ng -> Latn + {0x80CD0000u, 46u}, // nga -> Latn + {0x84CD0000u, 46u}, // ngb -> Latn + {0xACCD0000u, 46u}, // ngl -> Latn + {0x84ED0000u, 46u}, // nhb -> Latn + {0x90ED0000u, 46u}, // nhe -> Latn + {0xD8ED0000u, 46u}, // nhw -> Latn + {0x950D0000u, 46u}, // nif -> Latn + {0xA10D0000u, 46u}, // nii -> Latn + {0xA50D0000u, 46u}, // nij -> Latn + {0xB50D0000u, 46u}, // nin -> Latn + {0xD10D0000u, 46u}, // niu -> Latn + {0xE10D0000u, 46u}, // niy -> Latn + {0xE50D0000u, 46u}, // niz -> Latn + {0xB92D0000u, 46u}, // njo -> Latn + {0x994D0000u, 46u}, // nkg -> Latn + {0xB94D0000u, 46u}, // nko -> Latn + {0x6E6C0000u, 46u}, // nl -> Latn + {0x998D0000u, 46u}, // nmg -> Latn + {0xE58D0000u, 46u}, // nmz -> Latn + {0x6E6E0000u, 46u}, // nn -> Latn + {0x95AD0000u, 46u}, // nnf -> Latn + {0x9DAD0000u, 46u}, // nnh -> Latn + {0xA9AD0000u, 46u}, // nnk -> Latn + {0xB1AD0000u, 46u}, // nnm -> Latn + {0xBDAD0000u, 93u}, // nnp -> Wcho + {0x6E6F0000u, 46u}, // no -> Latn + {0x8DCD0000u, 44u}, // nod -> Lana + {0x91CD0000u, 18u}, // noe -> Deva + {0xB5CD0000u, 71u}, // non -> Runr + {0xBDCD0000u, 46u}, // nop -> Latn + {0xD1CD0000u, 46u}, // nou -> Latn + {0xBA0D0000u, 60u}, // nqo -> Nkoo + {0x6E720000u, 46u}, // nr -> Latn + {0x862D0000u, 46u}, // nrb -> Latn {0xAA4D0000u, 10u}, // nsk -> Cans - {0xB64D0000u, 44u}, // nsn -> Latn - {0xBA4D0000u, 44u}, // nso -> Latn - {0xCA4D0000u, 44u}, // nss -> Latn - {0xB26D0000u, 44u}, // ntm -> Latn - {0xC66D0000u, 44u}, // ntr -> Latn - {0xA28D0000u, 44u}, // nui -> Latn - {0xBE8D0000u, 44u}, // nup -> Latn - {0xCA8D0000u, 44u}, // nus -> Latn - {0xD68D0000u, 44u}, // nuv -> Latn - {0xDE8D0000u, 44u}, // nux -> Latn - {0x6E760000u, 44u}, // nv -> Latn - {0x86CD0000u, 44u}, // nwb -> Latn - {0xC2ED0000u, 44u}, // nxq -> Latn - {0xC6ED0000u, 44u}, // nxr -> Latn - {0x6E790000u, 44u}, // ny -> Latn - {0xB30D0000u, 44u}, // nym -> Latn - {0xB70D0000u, 44u}, // nyn -> Latn - {0xA32D0000u, 44u}, // nzi -> Latn - {0x6F630000u, 44u}, // oc -> Latn - {0x88CE0000u, 44u}, // ogc -> Latn - {0xC54E0000u, 44u}, // okr -> Latn - {0xD54E0000u, 44u}, // okv -> Latn - {0x6F6D0000u, 44u}, // om -> Latn - {0x99AE0000u, 44u}, // ong -> Latn - {0xB5AE0000u, 44u}, // onn -> Latn - {0xC9AE0000u, 44u}, // ons -> Latn - {0xB1EE0000u, 44u}, // opm -> Latn - {0x6F720000u, 62u}, // or -> Orya - {0xBA2E0000u, 44u}, // oro -> Latn + {0xB64D0000u, 46u}, // nsn -> Latn + {0xBA4D0000u, 46u}, // nso -> Latn + {0xCA4D0000u, 46u}, // nss -> Latn + {0xB26D0000u, 46u}, // ntm -> Latn + {0xC66D0000u, 46u}, // ntr -> Latn + {0xA28D0000u, 46u}, // nui -> Latn + {0xBE8D0000u, 46u}, // nup -> Latn + {0xCA8D0000u, 46u}, // nus -> Latn + {0xD68D0000u, 46u}, // nuv -> Latn + {0xDE8D0000u, 46u}, // nux -> Latn + {0x6E760000u, 46u}, // nv -> Latn + {0x86CD0000u, 46u}, // nwb -> Latn + {0xC2ED0000u, 46u}, // nxq -> Latn + {0xC6ED0000u, 46u}, // nxr -> Latn + {0x6E790000u, 46u}, // ny -> Latn + {0xB30D0000u, 46u}, // nym -> Latn + {0xB70D0000u, 46u}, // nyn -> Latn + {0xA32D0000u, 46u}, // nzi -> Latn + {0x6F630000u, 46u}, // oc -> Latn + {0x88CE0000u, 46u}, // ogc -> Latn + {0xC54E0000u, 46u}, // okr -> Latn + {0xD54E0000u, 46u}, // okv -> Latn + {0x6F6D0000u, 46u}, // om -> Latn + {0x99AE0000u, 46u}, // ong -> Latn + {0xB5AE0000u, 46u}, // onn -> Latn + {0xC9AE0000u, 46u}, // ons -> Latn + {0xB1EE0000u, 46u}, // opm -> Latn + {0x6F720000u, 64u}, // or -> Orya + {0xBA2E0000u, 46u}, // oro -> Latn {0xD22E0000u, 1u}, // oru -> Arab - {0x6F730000u, 16u}, // os -> Cyrl - {0x824E0000u, 63u}, // osa -> Osge + {0x6F730000u, 17u}, // os -> Cyrl + {0x824E0000u, 65u}, // osa -> Osge {0x826E0000u, 1u}, // ota -> Arab - {0xAA6E0000u, 61u}, // otk -> Orkh - {0xB32E0000u, 44u}, // ozm -> Latn - {0x70610000u, 26u}, // pa -> Guru + {0xAA6E0000u, 63u}, // otk -> Orkh + {0xB32E0000u, 46u}, // ozm -> Latn + {0x70610000u, 27u}, // pa -> Guru {0x7061504Bu, 1u}, // pa-PK -> Arab - {0x980F0000u, 44u}, // pag -> Latn - {0xAC0F0000u, 65u}, // pal -> Phli - {0xB00F0000u, 44u}, // pam -> Latn - {0xBC0F0000u, 44u}, // pap -> Latn - {0xD00F0000u, 44u}, // pau -> Latn - {0xA02F0000u, 44u}, // pbi -> Latn - {0x8C4F0000u, 44u}, // pcd -> Latn - {0xB04F0000u, 44u}, // pcm -> Latn - {0x886F0000u, 44u}, // pdc -> Latn - {0xCC6F0000u, 44u}, // pdt -> Latn - {0x8C8F0000u, 44u}, // ped -> Latn - {0xB88F0000u, 92u}, // peo -> Xpeo - {0xDC8F0000u, 44u}, // pex -> Latn - {0xACAF0000u, 44u}, // pfl -> Latn + {0x980F0000u, 46u}, // pag -> Latn + {0xAC0F0000u, 67u}, // pal -> Phli + {0xB00F0000u, 46u}, // pam -> Latn + {0xBC0F0000u, 46u}, // pap -> Latn + {0xD00F0000u, 46u}, // pau -> Latn + {0xA02F0000u, 46u}, // pbi -> Latn + {0x8C4F0000u, 46u}, // pcd -> Latn + {0xB04F0000u, 46u}, // pcm -> Latn + {0x886F0000u, 46u}, // pdc -> Latn + {0xCC6F0000u, 46u}, // pdt -> Latn + {0x8C8F0000u, 46u}, // ped -> Latn + {0xB88F0000u, 94u}, // peo -> Xpeo + {0xDC8F0000u, 46u}, // pex -> Latn + {0xACAF0000u, 46u}, // pfl -> Latn {0xACEF0000u, 1u}, // phl -> Arab - {0xB4EF0000u, 66u}, // phn -> Phnx - {0xAD0F0000u, 44u}, // pil -> Latn - {0xBD0F0000u, 44u}, // pip -> Latn + {0xB4EF0000u, 68u}, // phn -> Phnx + {0xAD0F0000u, 46u}, // pil -> Latn + {0xBD0F0000u, 46u}, // pip -> Latn {0x814F0000u, 8u}, // pka -> Brah - {0xB94F0000u, 44u}, // pko -> Latn - {0x706C0000u, 44u}, // pl -> Latn - {0x816F0000u, 44u}, // pla -> Latn - {0xC98F0000u, 44u}, // pms -> Latn - {0x99AF0000u, 44u}, // png -> Latn - {0xB5AF0000u, 44u}, // pnn -> Latn - {0xCDAF0000u, 24u}, // pnt -> Grek - {0xB5CF0000u, 44u}, // pon -> Latn - {0x81EF0000u, 17u}, // ppa -> Deva - {0xB9EF0000u, 44u}, // ppo -> Latn - {0x822F0000u, 38u}, // pra -> Khar + {0xB94F0000u, 46u}, // pko -> Latn + {0x706C0000u, 46u}, // pl -> Latn + {0x816F0000u, 46u}, // pla -> Latn + {0xC98F0000u, 46u}, // pms -> Latn + {0x99AF0000u, 46u}, // png -> Latn + {0xB5AF0000u, 46u}, // pnn -> Latn + {0xCDAF0000u, 25u}, // pnt -> Grek + {0xB5CF0000u, 46u}, // pon -> Latn + {0x81EF0000u, 18u}, // ppa -> Deva + {0xB9EF0000u, 46u}, // ppo -> Latn + {0x822F0000u, 39u}, // pra -> Khar {0x8E2F0000u, 1u}, // prd -> Arab - {0x9A2F0000u, 44u}, // prg -> Latn + {0x9A2F0000u, 46u}, // prg -> Latn {0x70730000u, 1u}, // ps -> Arab - {0xCA4F0000u, 44u}, // pss -> Latn - {0x70740000u, 44u}, // pt -> Latn - {0xBE6F0000u, 44u}, // ptp -> Latn - {0xD28F0000u, 44u}, // puu -> Latn - {0x82CF0000u, 44u}, // pwa -> Latn - {0x71750000u, 44u}, // qu -> Latn - {0x8A900000u, 44u}, // quc -> Latn - {0x9A900000u, 44u}, // qug -> Latn - {0xA0110000u, 44u}, // rai -> Latn - {0xA4110000u, 17u}, // raj -> Deva - {0xB8110000u, 44u}, // rao -> Latn - {0x94510000u, 44u}, // rcf -> Latn - {0xA4910000u, 44u}, // rej -> Latn - {0xAC910000u, 44u}, // rel -> Latn - {0xC8910000u, 44u}, // res -> Latn - {0xB4D10000u, 44u}, // rgn -> Latn + {0xCA4F0000u, 46u}, // pss -> Latn + {0x70740000u, 46u}, // pt -> Latn + {0xBE6F0000u, 46u}, // ptp -> Latn + {0xD28F0000u, 46u}, // puu -> Latn + {0x82CF0000u, 46u}, // pwa -> Latn + {0x71750000u, 46u}, // qu -> Latn + {0x8A900000u, 46u}, // quc -> Latn + {0x9A900000u, 46u}, // qug -> Latn + {0xA0110000u, 46u}, // rai -> Latn + {0xA4110000u, 18u}, // raj -> Deva + {0xB8110000u, 46u}, // rao -> Latn + {0x94510000u, 46u}, // rcf -> Latn + {0xA4910000u, 46u}, // rej -> Latn + {0xAC910000u, 46u}, // rel -> Latn + {0xC8910000u, 46u}, // res -> Latn + {0xB4D10000u, 46u}, // rgn -> Latn {0x98F10000u, 1u}, // rhg -> Arab - {0x81110000u, 44u}, // ria -> Latn - {0x95110000u, 85u}, // rif -> Tfng - {0x95114E4Cu, 44u}, // rif-NL -> Latn - {0xC9310000u, 17u}, // rjs -> Deva + {0x81110000u, 46u}, // ria -> Latn + {0x95110000u, 87u}, // rif -> Tfng + {0x95114E4Cu, 46u}, // rif-NL -> Latn + {0xC9310000u, 18u}, // rjs -> Deva {0xCD510000u, 7u}, // rkt -> Beng - {0x726D0000u, 44u}, // rm -> Latn - {0x95910000u, 44u}, // rmf -> Latn - {0xB9910000u, 44u}, // rmo -> Latn + {0x726D0000u, 46u}, // rm -> Latn + {0x95910000u, 46u}, // rmf -> Latn + {0xB9910000u, 46u}, // rmo -> Latn {0xCD910000u, 1u}, // rmt -> Arab - {0xD1910000u, 44u}, // rmu -> Latn - {0x726E0000u, 44u}, // rn -> Latn - {0x81B10000u, 44u}, // rna -> Latn - {0x99B10000u, 44u}, // rng -> Latn - {0x726F0000u, 44u}, // ro -> Latn - {0x85D10000u, 44u}, // rob -> Latn - {0x95D10000u, 44u}, // rof -> Latn - {0xB9D10000u, 44u}, // roo -> Latn - {0xBA310000u, 44u}, // rro -> Latn - {0xB2710000u, 44u}, // rtm -> Latn - {0x72750000u, 16u}, // ru -> Cyrl - {0x92910000u, 16u}, // rue -> Cyrl - {0x9A910000u, 44u}, // rug -> Latn - {0x72770000u, 44u}, // rw -> Latn - {0xAAD10000u, 44u}, // rwk -> Latn - {0xBAD10000u, 44u}, // rwo -> Latn - {0xD3110000u, 37u}, // ryu -> Kana - {0x73610000u, 17u}, // sa -> Deva - {0x94120000u, 44u}, // saf -> Latn - {0x9C120000u, 16u}, // sah -> Cyrl - {0xC0120000u, 44u}, // saq -> Latn - {0xC8120000u, 44u}, // sas -> Latn - {0xCC120000u, 44u}, // sat -> Latn - {0xD4120000u, 44u}, // sav -> Latn - {0xE4120000u, 72u}, // saz -> Saur - {0x80320000u, 44u}, // sba -> Latn - {0x90320000u, 44u}, // sbe -> Latn - {0xBC320000u, 44u}, // sbp -> Latn - {0x73630000u, 44u}, // sc -> Latn - {0xA8520000u, 17u}, // sck -> Deva + {0xD1910000u, 46u}, // rmu -> Latn + {0x726E0000u, 46u}, // rn -> Latn + {0x81B10000u, 46u}, // rna -> Latn + {0x99B10000u, 46u}, // rng -> Latn + {0x726F0000u, 46u}, // ro -> Latn + {0x85D10000u, 46u}, // rob -> Latn + {0x95D10000u, 46u}, // rof -> Latn + {0xB9D10000u, 46u}, // roo -> Latn + {0xBA310000u, 46u}, // rro -> Latn + {0xB2710000u, 46u}, // rtm -> Latn + {0x72750000u, 17u}, // ru -> Cyrl + {0x92910000u, 17u}, // rue -> Cyrl + {0x9A910000u, 46u}, // rug -> Latn + {0x72770000u, 46u}, // rw -> Latn + {0xAAD10000u, 46u}, // rwk -> Latn + {0xBAD10000u, 46u}, // rwo -> Latn + {0xD3110000u, 38u}, // ryu -> Kana + {0x73610000u, 18u}, // sa -> Deva + {0x94120000u, 46u}, // saf -> Latn + {0x9C120000u, 17u}, // sah -> Cyrl + {0xC0120000u, 46u}, // saq -> Latn + {0xC8120000u, 46u}, // sas -> Latn + {0xCC120000u, 46u}, // sat -> Latn + {0xD4120000u, 46u}, // sav -> Latn + {0xE4120000u, 74u}, // saz -> Saur + {0x80320000u, 46u}, // sba -> Latn + {0x90320000u, 46u}, // sbe -> Latn + {0xBC320000u, 46u}, // sbp -> Latn + {0x73630000u, 46u}, // sc -> Latn + {0xA8520000u, 18u}, // sck -> Deva {0xAC520000u, 1u}, // scl -> Arab - {0xB4520000u, 44u}, // scn -> Latn - {0xB8520000u, 44u}, // sco -> Latn - {0xC8520000u, 44u}, // scs -> Latn + {0xB4520000u, 46u}, // scn -> Latn + {0xB8520000u, 46u}, // sco -> Latn + {0xC8520000u, 46u}, // scs -> Latn {0x73640000u, 1u}, // sd -> Arab - {0x88720000u, 44u}, // sdc -> Latn + {0x88720000u, 46u}, // sdc -> Latn {0x9C720000u, 1u}, // sdh -> Arab - {0x73650000u, 44u}, // se -> Latn - {0x94920000u, 44u}, // sef -> Latn - {0x9C920000u, 44u}, // seh -> Latn - {0xA0920000u, 44u}, // sei -> Latn - {0xC8920000u, 44u}, // ses -> Latn - {0x73670000u, 44u}, // sg -> Latn - {0x80D20000u, 60u}, // sga -> Ogam - {0xC8D20000u, 44u}, // sgs -> Latn - {0xD8D20000u, 19u}, // sgw -> Ethi - {0xE4D20000u, 44u}, // sgz -> Latn - {0x73680000u, 44u}, // sh -> Latn - {0xA0F20000u, 85u}, // shi -> Tfng - {0xA8F20000u, 44u}, // shk -> Latn - {0xB4F20000u, 56u}, // shn -> Mymr + {0x73650000u, 46u}, // se -> Latn + {0x94920000u, 46u}, // sef -> Latn + {0x9C920000u, 46u}, // seh -> Latn + {0xA0920000u, 46u}, // sei -> Latn + {0xC8920000u, 46u}, // ses -> Latn + {0x73670000u, 46u}, // sg -> Latn + {0x80D20000u, 62u}, // sga -> Ogam + {0xC8D20000u, 46u}, // sgs -> Latn + {0xD8D20000u, 20u}, // sgw -> Ethi + {0xE4D20000u, 46u}, // sgz -> Latn + {0x73680000u, 46u}, // sh -> Latn + {0xA0F20000u, 87u}, // shi -> Tfng + {0xA8F20000u, 46u}, // shk -> Latn + {0xB4F20000u, 58u}, // shn -> Mymr {0xD0F20000u, 1u}, // shu -> Arab - {0x73690000u, 74u}, // si -> Sinh - {0x8D120000u, 44u}, // sid -> Latn - {0x99120000u, 44u}, // sig -> Latn - {0xAD120000u, 44u}, // sil -> Latn - {0xB1120000u, 44u}, // sim -> Latn - {0xC5320000u, 44u}, // sjr -> Latn - {0x736B0000u, 44u}, // sk -> Latn - {0x89520000u, 44u}, // skc -> Latn + {0x73690000u, 76u}, // si -> Sinh + {0x8D120000u, 46u}, // sid -> Latn + {0x99120000u, 46u}, // sig -> Latn + {0xAD120000u, 46u}, // sil -> Latn + {0xB1120000u, 46u}, // sim -> Latn + {0xC5320000u, 46u}, // sjr -> Latn + {0x736B0000u, 46u}, // sk -> Latn + {0x89520000u, 46u}, // skc -> Latn {0xC5520000u, 1u}, // skr -> Arab - {0xC9520000u, 44u}, // sks -> Latn - {0x736C0000u, 44u}, // sl -> Latn - {0x8D720000u, 44u}, // sld -> Latn - {0xA1720000u, 44u}, // sli -> Latn - {0xAD720000u, 44u}, // sll -> Latn - {0xE1720000u, 44u}, // sly -> Latn - {0x736D0000u, 44u}, // sm -> Latn - {0x81920000u, 44u}, // sma -> Latn - {0xA5920000u, 44u}, // smj -> Latn - {0xB5920000u, 44u}, // smn -> Latn - {0xBD920000u, 70u}, // smp -> Samr - {0xC1920000u, 44u}, // smq -> Latn - {0xC9920000u, 44u}, // sms -> Latn - {0x736E0000u, 44u}, // sn -> Latn - {0x89B20000u, 44u}, // snc -> Latn - {0xA9B20000u, 44u}, // snk -> Latn - {0xBDB20000u, 44u}, // snp -> Latn - {0xDDB20000u, 44u}, // snx -> Latn - {0xE1B20000u, 44u}, // sny -> Latn - {0x736F0000u, 44u}, // so -> Latn - {0x99D20000u, 75u}, // sog -> Sogd - {0xA9D20000u, 44u}, // sok -> Latn - {0xC1D20000u, 44u}, // soq -> Latn - {0xD1D20000u, 87u}, // sou -> Thai - {0xE1D20000u, 44u}, // soy -> Latn - {0x8DF20000u, 44u}, // spd -> Latn - {0xADF20000u, 44u}, // spl -> Latn - {0xC9F20000u, 44u}, // sps -> Latn - {0x73710000u, 44u}, // sq -> Latn - {0x73720000u, 16u}, // sr -> Cyrl - {0x73724D45u, 44u}, // sr-ME -> Latn - {0x7372524Fu, 44u}, // sr-RO -> Latn - {0x73725255u, 44u}, // sr-RU -> Latn - {0x73725452u, 44u}, // sr-TR -> Latn - {0x86320000u, 76u}, // srb -> Sora - {0xB6320000u, 44u}, // srn -> Latn - {0xC6320000u, 44u}, // srr -> Latn - {0xDE320000u, 17u}, // srx -> Deva - {0x73730000u, 44u}, // ss -> Latn - {0x8E520000u, 44u}, // ssd -> Latn - {0x9A520000u, 44u}, // ssg -> Latn - {0xE2520000u, 44u}, // ssy -> Latn - {0x73740000u, 44u}, // st -> Latn - {0xAA720000u, 44u}, // stk -> Latn - {0xC2720000u, 44u}, // stq -> Latn - {0x73750000u, 44u}, // su -> Latn - {0x82920000u, 44u}, // sua -> Latn - {0x92920000u, 44u}, // sue -> Latn - {0xAA920000u, 44u}, // suk -> Latn - {0xC6920000u, 44u}, // sur -> Latn - {0xCA920000u, 44u}, // sus -> Latn - {0x73760000u, 44u}, // sv -> Latn - {0x73770000u, 44u}, // sw -> Latn + {0xC9520000u, 46u}, // sks -> Latn + {0x736C0000u, 46u}, // sl -> Latn + {0x8D720000u, 46u}, // sld -> Latn + {0xA1720000u, 46u}, // sli -> Latn + {0xAD720000u, 46u}, // sll -> Latn + {0xE1720000u, 46u}, // sly -> Latn + {0x736D0000u, 46u}, // sm -> Latn + {0x81920000u, 46u}, // sma -> Latn + {0xA5920000u, 46u}, // smj -> Latn + {0xB5920000u, 46u}, // smn -> Latn + {0xBD920000u, 72u}, // smp -> Samr + {0xC1920000u, 46u}, // smq -> Latn + {0xC9920000u, 46u}, // sms -> Latn + {0x736E0000u, 46u}, // sn -> Latn + {0x89B20000u, 46u}, // snc -> Latn + {0xA9B20000u, 46u}, // snk -> Latn + {0xBDB20000u, 46u}, // snp -> Latn + {0xDDB20000u, 46u}, // snx -> Latn + {0xE1B20000u, 46u}, // sny -> Latn + {0x736F0000u, 46u}, // so -> Latn + {0x99D20000u, 77u}, // sog -> Sogd + {0xA9D20000u, 46u}, // sok -> Latn + {0xC1D20000u, 46u}, // soq -> Latn + {0xD1D20000u, 89u}, // sou -> Thai + {0xE1D20000u, 46u}, // soy -> Latn + {0x8DF20000u, 46u}, // spd -> Latn + {0xADF20000u, 46u}, // spl -> Latn + {0xC9F20000u, 46u}, // sps -> Latn + {0x73710000u, 46u}, // sq -> Latn + {0x73720000u, 17u}, // sr -> Cyrl + {0x73724D45u, 46u}, // sr-ME -> Latn + {0x7372524Fu, 46u}, // sr-RO -> Latn + {0x73725255u, 46u}, // sr-RU -> Latn + {0x73725452u, 46u}, // sr-TR -> Latn + {0x86320000u, 78u}, // srb -> Sora + {0xB6320000u, 46u}, // srn -> Latn + {0xC6320000u, 46u}, // srr -> Latn + {0xDE320000u, 18u}, // srx -> Deva + {0x73730000u, 46u}, // ss -> Latn + {0x8E520000u, 46u}, // ssd -> Latn + {0x9A520000u, 46u}, // ssg -> Latn + {0xE2520000u, 46u}, // ssy -> Latn + {0x73740000u, 46u}, // st -> Latn + {0xAA720000u, 46u}, // stk -> Latn + {0xC2720000u, 46u}, // stq -> Latn + {0x73750000u, 46u}, // su -> Latn + {0x82920000u, 46u}, // sua -> Latn + {0x92920000u, 46u}, // sue -> Latn + {0xAA920000u, 46u}, // suk -> Latn + {0xC6920000u, 46u}, // sur -> Latn + {0xCA920000u, 46u}, // sus -> Latn + {0x73760000u, 46u}, // sv -> Latn + {0x73770000u, 46u}, // sw -> Latn {0x86D20000u, 1u}, // swb -> Arab - {0x8AD20000u, 44u}, // swc -> Latn - {0x9AD20000u, 44u}, // swg -> Latn - {0xBED20000u, 44u}, // swp -> Latn - {0xD6D20000u, 17u}, // swv -> Deva - {0xB6F20000u, 44u}, // sxn -> Latn - {0xDAF20000u, 44u}, // sxw -> Latn + {0x8AD20000u, 46u}, // swc -> Latn + {0x9AD20000u, 46u}, // swg -> Latn + {0xBED20000u, 46u}, // swp -> Latn + {0xD6D20000u, 18u}, // swv -> Deva + {0xB6F20000u, 46u}, // sxn -> Latn + {0xDAF20000u, 46u}, // sxw -> Latn {0xAF120000u, 7u}, // syl -> Beng - {0xC7120000u, 78u}, // syr -> Syrc - {0xAF320000u, 44u}, // szl -> Latn - {0x74610000u, 81u}, // ta -> Taml - {0xA4130000u, 17u}, // taj -> Deva - {0xAC130000u, 44u}, // tal -> Latn - {0xB4130000u, 44u}, // tan -> Latn - {0xC0130000u, 44u}, // taq -> Latn - {0x88330000u, 44u}, // tbc -> Latn - {0x8C330000u, 44u}, // tbd -> Latn - {0x94330000u, 44u}, // tbf -> Latn - {0x98330000u, 44u}, // tbg -> Latn - {0xB8330000u, 44u}, // tbo -> Latn - {0xD8330000u, 44u}, // tbw -> Latn - {0xE4330000u, 44u}, // tbz -> Latn - {0xA0530000u, 44u}, // tci -> Latn - {0xE0530000u, 40u}, // tcy -> Knda - {0x8C730000u, 79u}, // tdd -> Tale - {0x98730000u, 17u}, // tdg -> Deva - {0x9C730000u, 17u}, // tdh -> Deva - {0xD0730000u, 44u}, // tdu -> Latn - {0x74650000u, 84u}, // te -> Telu - {0x8C930000u, 44u}, // ted -> Latn - {0xB0930000u, 44u}, // tem -> Latn - {0xB8930000u, 44u}, // teo -> Latn - {0xCC930000u, 44u}, // tet -> Latn - {0xA0B30000u, 44u}, // tfi -> Latn - {0x74670000u, 16u}, // tg -> Cyrl + {0xC7120000u, 80u}, // syr -> Syrc + {0xAF320000u, 46u}, // szl -> Latn + {0x74610000u, 83u}, // ta -> Taml + {0xA4130000u, 18u}, // taj -> Deva + {0xAC130000u, 46u}, // tal -> Latn + {0xB4130000u, 46u}, // tan -> Latn + {0xC0130000u, 46u}, // taq -> Latn + {0x88330000u, 46u}, // tbc -> Latn + {0x8C330000u, 46u}, // tbd -> Latn + {0x94330000u, 46u}, // tbf -> Latn + {0x98330000u, 46u}, // tbg -> Latn + {0xB8330000u, 46u}, // tbo -> Latn + {0xD8330000u, 46u}, // tbw -> Latn + {0xE4330000u, 46u}, // tbz -> Latn + {0xA0530000u, 46u}, // tci -> Latn + {0xE0530000u, 42u}, // tcy -> Knda + {0x8C730000u, 81u}, // tdd -> Tale + {0x98730000u, 18u}, // tdg -> Deva + {0x9C730000u, 18u}, // tdh -> Deva + {0xD0730000u, 46u}, // tdu -> Latn + {0x74650000u, 86u}, // te -> Telu + {0x8C930000u, 46u}, // ted -> Latn + {0xB0930000u, 46u}, // tem -> Latn + {0xB8930000u, 46u}, // teo -> Latn + {0xCC930000u, 46u}, // tet -> Latn + {0xA0B30000u, 46u}, // tfi -> Latn + {0x74670000u, 17u}, // tg -> Cyrl {0x7467504Bu, 1u}, // tg-PK -> Arab - {0x88D30000u, 44u}, // tgc -> Latn - {0xB8D30000u, 44u}, // tgo -> Latn - {0xD0D30000u, 44u}, // tgu -> Latn - {0x74680000u, 87u}, // th -> Thai - {0xACF30000u, 17u}, // thl -> Deva - {0xC0F30000u, 17u}, // thq -> Deva - {0xC4F30000u, 17u}, // thr -> Deva - {0x74690000u, 19u}, // ti -> Ethi - {0x95130000u, 44u}, // tif -> Latn - {0x99130000u, 19u}, // tig -> Ethi - {0xA9130000u, 44u}, // tik -> Latn - {0xB1130000u, 44u}, // tim -> Latn - {0xB9130000u, 44u}, // tio -> Latn - {0xD5130000u, 44u}, // tiv -> Latn - {0x746B0000u, 44u}, // tk -> Latn - {0xAD530000u, 44u}, // tkl -> Latn - {0xC5530000u, 44u}, // tkr -> Latn - {0xCD530000u, 17u}, // tkt -> Deva - {0x746C0000u, 44u}, // tl -> Latn - {0x95730000u, 44u}, // tlf -> Latn - {0xDD730000u, 44u}, // tlx -> Latn - {0xE1730000u, 44u}, // tly -> Latn - {0x9D930000u, 44u}, // tmh -> Latn - {0xE1930000u, 44u}, // tmy -> Latn - {0x746E0000u, 44u}, // tn -> Latn - {0x9DB30000u, 44u}, // tnh -> Latn - {0x746F0000u, 44u}, // to -> Latn - {0x95D30000u, 44u}, // tof -> Latn - {0x99D30000u, 44u}, // tog -> Latn - {0xC1D30000u, 44u}, // toq -> Latn - {0xA1F30000u, 44u}, // tpi -> Latn - {0xB1F30000u, 44u}, // tpm -> Latn - {0xE5F30000u, 44u}, // tpz -> Latn - {0xBA130000u, 44u}, // tqo -> Latn - {0x74720000u, 44u}, // tr -> Latn - {0xD2330000u, 44u}, // tru -> Latn - {0xD6330000u, 44u}, // trv -> Latn + {0x88D30000u, 46u}, // tgc -> Latn + {0xB8D30000u, 46u}, // tgo -> Latn + {0xD0D30000u, 46u}, // tgu -> Latn + {0x74680000u, 89u}, // th -> Thai + {0xACF30000u, 18u}, // thl -> Deva + {0xC0F30000u, 18u}, // thq -> Deva + {0xC4F30000u, 18u}, // thr -> Deva + {0x74690000u, 20u}, // ti -> Ethi + {0x95130000u, 46u}, // tif -> Latn + {0x99130000u, 20u}, // tig -> Ethi + {0xA9130000u, 46u}, // tik -> Latn + {0xB1130000u, 46u}, // tim -> Latn + {0xB9130000u, 46u}, // tio -> Latn + {0xD5130000u, 46u}, // tiv -> Latn + {0x746B0000u, 46u}, // tk -> Latn + {0xAD530000u, 46u}, // tkl -> Latn + {0xC5530000u, 46u}, // tkr -> Latn + {0xCD530000u, 18u}, // tkt -> Deva + {0x746C0000u, 46u}, // tl -> Latn + {0x95730000u, 46u}, // tlf -> Latn + {0xDD730000u, 46u}, // tlx -> Latn + {0xE1730000u, 46u}, // tly -> Latn + {0x9D930000u, 46u}, // tmh -> Latn + {0xE1930000u, 46u}, // tmy -> Latn + {0x746E0000u, 46u}, // tn -> Latn + {0x9DB30000u, 46u}, // tnh -> Latn + {0x746F0000u, 46u}, // to -> Latn + {0x95D30000u, 46u}, // tof -> Latn + {0x99D30000u, 46u}, // tog -> Latn + {0xC1D30000u, 46u}, // toq -> Latn + {0xA1F30000u, 46u}, // tpi -> Latn + {0xB1F30000u, 46u}, // tpm -> Latn + {0xE5F30000u, 46u}, // tpz -> Latn + {0xBA130000u, 46u}, // tqo -> Latn + {0x74720000u, 46u}, // tr -> Latn + {0xD2330000u, 46u}, // tru -> Latn + {0xD6330000u, 46u}, // trv -> Latn {0xDA330000u, 1u}, // trw -> Arab - {0x74730000u, 44u}, // ts -> Latn - {0x8E530000u, 24u}, // tsd -> Grek - {0x96530000u, 17u}, // tsf -> Deva - {0x9A530000u, 44u}, // tsg -> Latn - {0xA6530000u, 88u}, // tsj -> Tibt - {0xDA530000u, 44u}, // tsw -> Latn - {0x74740000u, 16u}, // tt -> Cyrl - {0x8E730000u, 44u}, // ttd -> Latn - {0x92730000u, 44u}, // tte -> Latn - {0xA6730000u, 44u}, // ttj -> Latn - {0xC6730000u, 44u}, // ttr -> Latn - {0xCA730000u, 87u}, // tts -> Thai - {0xCE730000u, 44u}, // ttt -> Latn - {0x9E930000u, 44u}, // tuh -> Latn - {0xAE930000u, 44u}, // tul -> Latn - {0xB2930000u, 44u}, // tum -> Latn - {0xC2930000u, 44u}, // tuq -> Latn - {0x8EB30000u, 44u}, // tvd -> Latn - {0xAEB30000u, 44u}, // tvl -> Latn - {0xD2B30000u, 44u}, // tvu -> Latn - {0x9ED30000u, 44u}, // twh -> Latn - {0xC2D30000u, 44u}, // twq -> Latn - {0x9AF30000u, 82u}, // txg -> Tang - {0x74790000u, 44u}, // ty -> Latn - {0x83130000u, 44u}, // tya -> Latn - {0xD7130000u, 16u}, // tyv -> Cyrl - {0xB3330000u, 44u}, // tzm -> Latn - {0xD0340000u, 44u}, // ubu -> Latn - {0xB0740000u, 16u}, // udm -> Cyrl + {0x74730000u, 46u}, // ts -> Latn + {0x8E530000u, 25u}, // tsd -> Grek + {0x96530000u, 18u}, // tsf -> Deva + {0x9A530000u, 46u}, // tsg -> Latn + {0xA6530000u, 90u}, // tsj -> Tibt + {0xDA530000u, 46u}, // tsw -> Latn + {0x74740000u, 17u}, // tt -> Cyrl + {0x8E730000u, 46u}, // ttd -> Latn + {0x92730000u, 46u}, // tte -> Latn + {0xA6730000u, 46u}, // ttj -> Latn + {0xC6730000u, 46u}, // ttr -> Latn + {0xCA730000u, 89u}, // tts -> Thai + {0xCE730000u, 46u}, // ttt -> Latn + {0x9E930000u, 46u}, // tuh -> Latn + {0xAE930000u, 46u}, // tul -> Latn + {0xB2930000u, 46u}, // tum -> Latn + {0xC2930000u, 46u}, // tuq -> Latn + {0x8EB30000u, 46u}, // tvd -> Latn + {0xAEB30000u, 46u}, // tvl -> Latn + {0xD2B30000u, 46u}, // tvu -> Latn + {0x9ED30000u, 46u}, // twh -> Latn + {0xC2D30000u, 46u}, // twq -> Latn + {0x9AF30000u, 84u}, // txg -> Tang + {0x74790000u, 46u}, // ty -> Latn + {0x83130000u, 46u}, // tya -> Latn + {0xD7130000u, 17u}, // tyv -> Cyrl + {0xB3330000u, 46u}, // tzm -> Latn + {0xD0340000u, 46u}, // ubu -> Latn + {0xB0740000u, 17u}, // udm -> Cyrl {0x75670000u, 1u}, // ug -> Arab - {0x75674B5Au, 16u}, // ug-KZ -> Cyrl - {0x75674D4Eu, 16u}, // ug-MN -> Cyrl - {0x80D40000u, 89u}, // uga -> Ugar - {0x756B0000u, 16u}, // uk -> Cyrl - {0xA1740000u, 44u}, // uli -> Latn - {0x85940000u, 44u}, // umb -> Latn + {0x75674B5Au, 17u}, // ug-KZ -> Cyrl + {0x75674D4Eu, 17u}, // ug-MN -> Cyrl + {0x80D40000u, 91u}, // uga -> Ugar + {0x756B0000u, 17u}, // uk -> Cyrl + {0xA1740000u, 46u}, // uli -> Latn + {0x85940000u, 46u}, // umb -> Latn {0xC5B40000u, 7u}, // unr -> Beng - {0xC5B44E50u, 17u}, // unr-NP -> Deva + {0xC5B44E50u, 18u}, // unr-NP -> Deva {0xDDB40000u, 7u}, // unx -> Beng - {0xA9D40000u, 44u}, // uok -> Latn + {0xA9D40000u, 46u}, // uok -> Latn {0x75720000u, 1u}, // ur -> Arab - {0xA2340000u, 44u}, // uri -> Latn - {0xCE340000u, 44u}, // urt -> Latn - {0xDA340000u, 44u}, // urw -> Latn - {0x82540000u, 44u}, // usa -> Latn - {0xC6740000u, 44u}, // utr -> Latn - {0x9EB40000u, 44u}, // uvh -> Latn - {0xAEB40000u, 44u}, // uvl -> Latn - {0x757A0000u, 44u}, // uz -> Latn + {0xA2340000u, 46u}, // uri -> Latn + {0xCE340000u, 46u}, // urt -> Latn + {0xDA340000u, 46u}, // urw -> Latn + {0x82540000u, 46u}, // usa -> Latn + {0xC6740000u, 46u}, // utr -> Latn + {0x9EB40000u, 46u}, // uvh -> Latn + {0xAEB40000u, 46u}, // uvl -> Latn + {0x757A0000u, 46u}, // uz -> Latn {0x757A4146u, 1u}, // uz-AF -> Arab - {0x757A434Eu, 16u}, // uz-CN -> Cyrl - {0x98150000u, 44u}, // vag -> Latn - {0xA0150000u, 90u}, // vai -> Vaii - {0xB4150000u, 44u}, // van -> Latn - {0x76650000u, 44u}, // ve -> Latn - {0x88950000u, 44u}, // vec -> Latn - {0xBC950000u, 44u}, // vep -> Latn - {0x76690000u, 44u}, // vi -> Latn - {0x89150000u, 44u}, // vic -> Latn - {0xD5150000u, 44u}, // viv -> Latn - {0xC9750000u, 44u}, // vls -> Latn - {0x95950000u, 44u}, // vmf -> Latn - {0xD9950000u, 44u}, // vmw -> Latn - {0x766F0000u, 44u}, // vo -> Latn - {0xCDD50000u, 44u}, // vot -> Latn - {0xBA350000u, 44u}, // vro -> Latn - {0xB6950000u, 44u}, // vun -> Latn - {0xCE950000u, 44u}, // vut -> Latn - {0x77610000u, 44u}, // wa -> Latn - {0x90160000u, 44u}, // wae -> Latn - {0xA4160000u, 44u}, // waj -> Latn - {0xAC160000u, 19u}, // wal -> Ethi - {0xB4160000u, 44u}, // wan -> Latn - {0xC4160000u, 44u}, // war -> Latn - {0xBC360000u, 44u}, // wbp -> Latn - {0xC0360000u, 84u}, // wbq -> Telu - {0xC4360000u, 17u}, // wbr -> Deva - {0xA0560000u, 44u}, // wci -> Latn - {0xC4960000u, 44u}, // wer -> Latn - {0xA0D60000u, 44u}, // wgi -> Latn - {0x98F60000u, 44u}, // whg -> Latn - {0x85160000u, 44u}, // wib -> Latn - {0xD1160000u, 44u}, // wiu -> Latn - {0xD5160000u, 44u}, // wiv -> Latn - {0x81360000u, 44u}, // wja -> Latn - {0xA1360000u, 44u}, // wji -> Latn - {0xC9760000u, 44u}, // wls -> Latn - {0xB9960000u, 44u}, // wmo -> Latn - {0x89B60000u, 44u}, // wnc -> Latn + {0x757A434Eu, 17u}, // uz-CN -> Cyrl + {0x98150000u, 46u}, // vag -> Latn + {0xA0150000u, 92u}, // vai -> Vaii + {0xB4150000u, 46u}, // van -> Latn + {0x76650000u, 46u}, // ve -> Latn + {0x88950000u, 46u}, // vec -> Latn + {0xBC950000u, 46u}, // vep -> Latn + {0x76690000u, 46u}, // vi -> Latn + {0x89150000u, 46u}, // vic -> Latn + {0xD5150000u, 46u}, // viv -> Latn + {0xC9750000u, 46u}, // vls -> Latn + {0x95950000u, 46u}, // vmf -> Latn + {0xD9950000u, 46u}, // vmw -> Latn + {0x766F0000u, 46u}, // vo -> Latn + {0xCDD50000u, 46u}, // vot -> Latn + {0xBA350000u, 46u}, // vro -> Latn + {0xB6950000u, 46u}, // vun -> Latn + {0xCE950000u, 46u}, // vut -> Latn + {0x77610000u, 46u}, // wa -> Latn + {0x90160000u, 46u}, // wae -> Latn + {0xA4160000u, 46u}, // waj -> Latn + {0xAC160000u, 20u}, // wal -> Ethi + {0xB4160000u, 46u}, // wan -> Latn + {0xC4160000u, 46u}, // war -> Latn + {0xBC360000u, 46u}, // wbp -> Latn + {0xC0360000u, 86u}, // wbq -> Telu + {0xC4360000u, 18u}, // wbr -> Deva + {0xA0560000u, 46u}, // wci -> Latn + {0xC4960000u, 46u}, // wer -> Latn + {0xA0D60000u, 46u}, // wgi -> Latn + {0x98F60000u, 46u}, // whg -> Latn + {0x85160000u, 46u}, // wib -> Latn + {0xD1160000u, 46u}, // wiu -> Latn + {0xD5160000u, 46u}, // wiv -> Latn + {0x81360000u, 46u}, // wja -> Latn + {0xA1360000u, 46u}, // wji -> Latn + {0xC9760000u, 46u}, // wls -> Latn + {0xB9960000u, 46u}, // wmo -> Latn + {0x89B60000u, 46u}, // wnc -> Latn {0xA1B60000u, 1u}, // wni -> Arab - {0xD1B60000u, 44u}, // wnu -> Latn - {0x776F0000u, 44u}, // wo -> Latn - {0x85D60000u, 44u}, // wob -> Latn - {0xC9D60000u, 44u}, // wos -> Latn - {0xCA360000u, 44u}, // wrs -> Latn - {0x9A560000u, 21u}, // wsg -> Gong - {0xAA560000u, 44u}, // wsk -> Latn - {0xB2760000u, 17u}, // wtm -> Deva - {0xD2960000u, 27u}, // wuu -> Hans - {0xD6960000u, 44u}, // wuv -> Latn - {0x82D60000u, 44u}, // wwa -> Latn - {0xD4170000u, 44u}, // xav -> Latn - {0xA0370000u, 44u}, // xbi -> Latn + {0xD1B60000u, 46u}, // wnu -> Latn + {0x776F0000u, 46u}, // wo -> Latn + {0x85D60000u, 46u}, // wob -> Latn + {0xC9D60000u, 46u}, // wos -> Latn + {0xCA360000u, 46u}, // wrs -> Latn + {0x9A560000u, 22u}, // wsg -> Gong + {0xAA560000u, 46u}, // wsk -> Latn + {0xB2760000u, 18u}, // wtm -> Deva + {0xD2960000u, 28u}, // wuu -> Hans + {0xD6960000u, 46u}, // wuv -> Latn + {0x82D60000u, 46u}, // wwa -> Latn + {0xD4170000u, 46u}, // xav -> Latn + {0xA0370000u, 46u}, // xbi -> Latn + {0xB8570000u, 14u}, // xco -> Chrs {0xC4570000u, 11u}, // xcr -> Cari - {0xC8970000u, 44u}, // xes -> Latn - {0x78680000u, 44u}, // xh -> Latn - {0x81770000u, 44u}, // xla -> Latn - {0x89770000u, 48u}, // xlc -> Lyci - {0x8D770000u, 49u}, // xld -> Lydi - {0x95970000u, 20u}, // xmf -> Geor - {0xB5970000u, 51u}, // xmn -> Mani - {0xC5970000u, 52u}, // xmr -> Merc - {0x81B70000u, 57u}, // xna -> Narb - {0xC5B70000u, 17u}, // xnr -> Deva - {0x99D70000u, 44u}, // xog -> Latn - {0xB5D70000u, 44u}, // xon -> Latn - {0xC5F70000u, 68u}, // xpr -> Prti - {0x86370000u, 44u}, // xrb -> Latn - {0x82570000u, 71u}, // xsa -> Sarb - {0xA2570000u, 44u}, // xsi -> Latn - {0xB2570000u, 44u}, // xsm -> Latn - {0xC6570000u, 17u}, // xsr -> Deva - {0x92D70000u, 44u}, // xwe -> Latn - {0xB0180000u, 44u}, // yam -> Latn - {0xB8180000u, 44u}, // yao -> Latn - {0xBC180000u, 44u}, // yap -> Latn - {0xC8180000u, 44u}, // yas -> Latn - {0xCC180000u, 44u}, // yat -> Latn - {0xD4180000u, 44u}, // yav -> Latn - {0xE0180000u, 44u}, // yay -> Latn - {0xE4180000u, 44u}, // yaz -> Latn - {0x80380000u, 44u}, // yba -> Latn - {0x84380000u, 44u}, // ybb -> Latn - {0xE0380000u, 44u}, // yby -> Latn - {0xC4980000u, 44u}, // yer -> Latn - {0xC4D80000u, 44u}, // ygr -> Latn - {0xD8D80000u, 44u}, // ygw -> Latn - {0x79690000u, 30u}, // yi -> Hebr - {0xB9580000u, 44u}, // yko -> Latn - {0x91780000u, 44u}, // yle -> Latn - {0x99780000u, 44u}, // ylg -> Latn - {0xAD780000u, 44u}, // yll -> Latn - {0xAD980000u, 44u}, // yml -> Latn - {0x796F0000u, 44u}, // yo -> Latn - {0xB5D80000u, 44u}, // yon -> Latn - {0x86380000u, 44u}, // yrb -> Latn - {0x92380000u, 44u}, // yre -> Latn - {0xAE380000u, 44u}, // yrl -> Latn - {0xCA580000u, 44u}, // yss -> Latn - {0x82980000u, 44u}, // yua -> Latn - {0x92980000u, 28u}, // yue -> Hant - {0x9298434Eu, 27u}, // yue-CN -> Hans - {0xA6980000u, 44u}, // yuj -> Latn - {0xCE980000u, 44u}, // yut -> Latn - {0xDA980000u, 44u}, // yuw -> Latn - {0x7A610000u, 44u}, // za -> Latn - {0x98190000u, 44u}, // zag -> Latn + {0xC8970000u, 46u}, // xes -> Latn + {0x78680000u, 46u}, // xh -> Latn + {0x81770000u, 46u}, // xla -> Latn + {0x89770000u, 50u}, // xlc -> Lyci + {0x8D770000u, 51u}, // xld -> Lydi + {0x95970000u, 21u}, // xmf -> Geor + {0xB5970000u, 53u}, // xmn -> Mani + {0xC5970000u, 54u}, // xmr -> Merc + {0x81B70000u, 59u}, // xna -> Narb + {0xC5B70000u, 18u}, // xnr -> Deva + {0x99D70000u, 46u}, // xog -> Latn + {0xB5D70000u, 46u}, // xon -> Latn + {0xC5F70000u, 70u}, // xpr -> Prti + {0x86370000u, 46u}, // xrb -> Latn + {0x82570000u, 73u}, // xsa -> Sarb + {0xA2570000u, 46u}, // xsi -> Latn + {0xB2570000u, 46u}, // xsm -> Latn + {0xC6570000u, 18u}, // xsr -> Deva + {0x92D70000u, 46u}, // xwe -> Latn + {0xB0180000u, 46u}, // yam -> Latn + {0xB8180000u, 46u}, // yao -> Latn + {0xBC180000u, 46u}, // yap -> Latn + {0xC8180000u, 46u}, // yas -> Latn + {0xCC180000u, 46u}, // yat -> Latn + {0xD4180000u, 46u}, // yav -> Latn + {0xE0180000u, 46u}, // yay -> Latn + {0xE4180000u, 46u}, // yaz -> Latn + {0x80380000u, 46u}, // yba -> Latn + {0x84380000u, 46u}, // ybb -> Latn + {0xE0380000u, 46u}, // yby -> Latn + {0xC4980000u, 46u}, // yer -> Latn + {0xC4D80000u, 46u}, // ygr -> Latn + {0xD8D80000u, 46u}, // ygw -> Latn + {0x79690000u, 31u}, // yi -> Hebr + {0xB9580000u, 46u}, // yko -> Latn + {0x91780000u, 46u}, // yle -> Latn + {0x99780000u, 46u}, // ylg -> Latn + {0xAD780000u, 46u}, // yll -> Latn + {0xAD980000u, 46u}, // yml -> Latn + {0x796F0000u, 46u}, // yo -> Latn + {0xB5D80000u, 46u}, // yon -> Latn + {0x86380000u, 46u}, // yrb -> Latn + {0x92380000u, 46u}, // yre -> Latn + {0xAE380000u, 46u}, // yrl -> Latn + {0xCA580000u, 46u}, // yss -> Latn + {0x82980000u, 46u}, // yua -> Latn + {0x92980000u, 29u}, // yue -> Hant + {0x9298434Eu, 28u}, // yue-CN -> Hans + {0xA6980000u, 46u}, // yuj -> Latn + {0xCE980000u, 46u}, // yut -> Latn + {0xDA980000u, 46u}, // yuw -> Latn + {0x7A610000u, 46u}, // za -> Latn + {0x98190000u, 46u}, // zag -> Latn {0xA4790000u, 1u}, // zdj -> Arab - {0x80990000u, 44u}, // zea -> Latn - {0x9CD90000u, 85u}, // zgh -> Tfng - {0x7A680000u, 27u}, // zh -> Hans - {0x7A684155u, 28u}, // zh-AU -> Hant - {0x7A68424Eu, 28u}, // zh-BN -> Hant - {0x7A684742u, 28u}, // zh-GB -> Hant - {0x7A684746u, 28u}, // zh-GF -> Hant - {0x7A68484Bu, 28u}, // zh-HK -> Hant - {0x7A684944u, 28u}, // zh-ID -> Hant - {0x7A684D4Fu, 28u}, // zh-MO -> Hant - {0x7A684D59u, 28u}, // zh-MY -> Hant - {0x7A685041u, 28u}, // zh-PA -> Hant - {0x7A685046u, 28u}, // zh-PF -> Hant - {0x7A685048u, 28u}, // zh-PH -> Hant - {0x7A685352u, 28u}, // zh-SR -> Hant - {0x7A685448u, 28u}, // zh-TH -> Hant - {0x7A685457u, 28u}, // zh-TW -> Hant - {0x7A685553u, 28u}, // zh-US -> Hant - {0x7A68564Eu, 28u}, // zh-VN -> Hant - {0xDCF90000u, 59u}, // zhx -> Nshu - {0x81190000u, 44u}, // zia -> Latn - {0xB1790000u, 44u}, // zlm -> Latn - {0xA1990000u, 44u}, // zmi -> Latn - {0x91B90000u, 44u}, // zne -> Latn - {0x7A750000u, 44u}, // zu -> Latn - {0x83390000u, 44u}, // zza -> Latn + {0x80990000u, 46u}, // zea -> Latn + {0x9CD90000u, 87u}, // zgh -> Tfng + {0x7A680000u, 28u}, // zh -> Hans + {0x7A684155u, 29u}, // zh-AU -> Hant + {0x7A68424Eu, 29u}, // zh-BN -> Hant + {0x7A684742u, 29u}, // zh-GB -> Hant + {0x7A684746u, 29u}, // zh-GF -> Hant + {0x7A68484Bu, 29u}, // zh-HK -> Hant + {0x7A684944u, 29u}, // zh-ID -> Hant + {0x7A684D4Fu, 29u}, // zh-MO -> Hant + {0x7A684D59u, 29u}, // zh-MY -> Hant + {0x7A685041u, 29u}, // zh-PA -> Hant + {0x7A685046u, 29u}, // zh-PF -> Hant + {0x7A685048u, 29u}, // zh-PH -> Hant + {0x7A685352u, 29u}, // zh-SR -> Hant + {0x7A685448u, 29u}, // zh-TH -> Hant + {0x7A685457u, 29u}, // zh-TW -> Hant + {0x7A685553u, 29u}, // zh-US -> Hant + {0x7A68564Eu, 29u}, // zh-VN -> Hant + {0xDCF90000u, 61u}, // zhx -> Nshu + {0x81190000u, 46u}, // zia -> Latn + {0xCD590000u, 41u}, // zkt -> Kits + {0xB1790000u, 46u}, // zlm -> Latn + {0xA1990000u, 46u}, // zmi -> Latn + {0x91B90000u, 46u}, // zne -> Latn + {0x7A750000u, 46u}, // zu -> Latn + {0x83390000u, 46u}, // zza -> Latn }); std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({ @@ -1829,6 +1833,7 @@ std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({ 0xC66A4D594C61746ELLU, // ktr_Latn_MY 0x6B75495141726162LLU, // ku_Arab_IQ 0x6B7554524C61746ELLU, // ku_Latn_TR + 0x6B75474559657A69LLU, // ku_Yezi_GE 0xB28A52554379726CLLU, // kum_Cyrl_RU 0x6B7652554379726CLLU, // kv_Cyrl_RU 0xC6AA49444C61746ELLU, // kvr_Latn_ID @@ -2199,6 +2204,7 @@ std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({ 0xB276494E44657661LLU, // wtm_Deva_IN 0xD296434E48616E73LLU, // wuu_Hans_CN 0xD41742524C61746ELLU, // xav_Latn_BR + 0xB857555A43687273LLU, // xco_Chrs_UZ 0xC457545243617269LLU, // xcr_Cari_TR 0x78685A414C61746ELLU, // xh_Latn_ZA 0x897754524C796369LLU, // xlc_Lyci_TR @@ -2231,6 +2237,7 @@ std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({ 0x7A68434E48616E73LLU, // zh_Hans_CN 0x7A68545748616E74LLU, // zh_Hant_TW 0xDCF9434E4E736875LLU, // zhx_Nshu_CN + 0xCD59434E4B697473LLU, // zkt_Kits_CN 0xB17954474C61746ELLU, // zlm_Latn_TG 0xA1994D594C61746ELLU, // zmi_Latn_MY 0x7A755A414C61746ELLU, // zu_Latn_ZA 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/libs/androidfw/include/androidfw/ConfigDescription.h b/libs/androidfw/include/androidfw/ConfigDescription.h index 6fa089aeb12c..acf413aeaf91 100644 --- a/libs/androidfw/include/androidfw/ConfigDescription.h +++ b/libs/androidfw/include/androidfw/ConfigDescription.h @@ -151,8 +151,8 @@ inline ConfigDescription::ConfigDescription(const android::ResTable_config& o) { size = sizeof(android::ResTable_config); } -inline ConfigDescription::ConfigDescription(const ConfigDescription& o) { - *static_cast<android::ResTable_config*>(this) = o; +inline ConfigDescription::ConfigDescription(const ConfigDescription& o) + : android::ResTable_config(o) { } inline ConfigDescription::ConfigDescription(ConfigDescription&& o) noexcept { 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/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java index 392e8fe7543f..a5da648cf14a 100644 --- a/media/java/android/media/audiofx/Visualizer.java +++ b/media/java/android/media/audiofx/Visualizer.java @@ -20,9 +20,10 @@ import android.app.ActivityThread; import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.Looper; -import android.os.Message; import android.util.Log; +import com.android.internal.annotations.GuardedBy; + import java.lang.ref.WeakReference; /** @@ -158,6 +159,7 @@ public class Visualizer { /** * Indicates the state of the Visualizer instance */ + @GuardedBy("mStateLock") private int mState = STATE_UNINITIALIZED; /** * Lock to synchronize access to mState @@ -166,6 +168,7 @@ public class Visualizer { /** * System wide unique Identifier of the visualizer engine used by this Visualizer instance */ + @GuardedBy("mStateLock") @UnsupportedAppUsage private int mId; @@ -176,19 +179,24 @@ public class Visualizer { /** * Handler for events coming from the native code */ - private NativeEventHandler mNativeEventHandler = null; + @GuardedBy("mListenerLock") + private Handler mNativeEventHandler = null; /** * PCM and FFT capture listener registered by client */ + @GuardedBy("mListenerLock") private OnDataCaptureListener mCaptureListener = null; /** * Server Died listener registered by client */ + @GuardedBy("mListenerLock") private OnServerDiedListener mServerDiedListener = null; // accessed by native methods - private long mNativeVisualizer; - private long mJniData; + private long mNativeVisualizer; // guarded by a static lock in native code + private long mJniData; // set in native_setup, _release; + // get in native_release, _setEnabled, _setPeriodicCapture + // thus, effectively guarded by mStateLock //-------------------------------------------------------------------------- // Constructor, Finalize @@ -244,7 +252,9 @@ public class Visualizer { @Override protected void finalize() { - native_finalize(); + synchronized (mStateLock) { + native_finalize(); + } } /** @@ -601,25 +611,28 @@ public class Visualizer { */ public int setDataCaptureListener(OnDataCaptureListener listener, int rate, boolean waveform, boolean fft) { - synchronized (mListenerLock) { - mCaptureListener = listener; - } if (listener == null) { // make sure capture callback is stopped in native code waveform = false; fft = false; } - int status = native_setPeriodicCapture(rate, waveform, fft); + int status; + synchronized (mStateLock) { + status = native_setPeriodicCapture(rate, waveform, fft); + } if (status == SUCCESS) { - if ((listener != null) && (mNativeEventHandler == null)) { - Looper looper; - if ((looper = Looper.myLooper()) != null) { - mNativeEventHandler = new NativeEventHandler(this, looper); - } else if ((looper = Looper.getMainLooper()) != null) { - mNativeEventHandler = new NativeEventHandler(this, looper); - } else { - mNativeEventHandler = null; - status = ERROR_NO_INIT; + synchronized (mListenerLock) { + mCaptureListener = listener; + if ((listener != null) && (mNativeEventHandler == null)) { + Looper looper; + if ((looper = Looper.myLooper()) != null) { + mNativeEventHandler = new Handler(looper); + } else if ((looper = Looper.getMainLooper()) != null) { + mNativeEventHandler = new Handler(looper); + } else { + mNativeEventHandler = null; + status = ERROR_NO_INIT; + } } } } @@ -663,112 +676,61 @@ public class Visualizer { return SUCCESS; } - /** - * Helper class to handle the forwarding of native events to the appropriate listeners - */ - private class NativeEventHandler extends Handler - { - private Visualizer mVisualizer; - - public NativeEventHandler(Visualizer v, Looper looper) { - super(looper); - mVisualizer = v; - } - - private void handleCaptureMessage(Message msg) { - OnDataCaptureListener l = null; - synchronized (mListenerLock) { - l = mVisualizer.mCaptureListener; - } - - if (l != null) { - byte[] data = (byte[])msg.obj; - int samplingRate = msg.arg1; - - switch(msg.what) { - case NATIVE_EVENT_PCM_CAPTURE: - l.onWaveFormDataCapture(mVisualizer, data, samplingRate); - break; - case NATIVE_EVENT_FFT_CAPTURE: - l.onFftDataCapture(mVisualizer, data, samplingRate); - break; - default: - Log.e(TAG,"Unknown native event in handleCaptureMessge: "+msg.what); - break; - } - } - } - - private void handleServerDiedMessage(Message msg) { - OnServerDiedListener l = null; - synchronized (mListenerLock) { - l = mVisualizer.mServerDiedListener; - } - - if (l != null) - l.onServerDied(); - } - - @Override - public void handleMessage(Message msg) { - if (mVisualizer == null) { - return; - } - - switch(msg.what) { - case NATIVE_EVENT_PCM_CAPTURE: - case NATIVE_EVENT_FFT_CAPTURE: - handleCaptureMessage(msg); - break; - case NATIVE_EVENT_SERVER_DIED: - handleServerDiedMessage(msg); - break; - default: - Log.e(TAG,"Unknown native event: "+msg.what); - break; - } - } - } - //--------------------------------------------------------- // Interface definitions //-------------------- private static native final void native_init(); + @GuardedBy("mStateLock") private native final int native_setup(Object audioeffect_this, int audioSession, int[] id, String opPackageName); + @GuardedBy("mStateLock") private native final void native_finalize(); + @GuardedBy("mStateLock") private native final void native_release(); + @GuardedBy("mStateLock") private native final int native_setEnabled(boolean enabled); + @GuardedBy("mStateLock") private native final boolean native_getEnabled(); + @GuardedBy("mStateLock") private native final int native_setCaptureSize(int size); + @GuardedBy("mStateLock") private native final int native_getCaptureSize(); + @GuardedBy("mStateLock") private native final int native_setScalingMode(int mode); + @GuardedBy("mStateLock") private native final int native_getScalingMode(); + @GuardedBy("mStateLock") private native final int native_setMeasurementMode(int mode); + @GuardedBy("mStateLock") private native final int native_getMeasurementMode(); + @GuardedBy("mStateLock") private native final int native_getSamplingRate(); + @GuardedBy("mStateLock") private native final int native_getWaveForm(byte[] waveform); + @GuardedBy("mStateLock") private native final int native_getFft(byte[] fft); + @GuardedBy("mStateLock") private native final int native_getPeakRms(MeasurementPeakRms measurement); + @GuardedBy("mStateLock") private native final int native_setPeriodicCapture(int rate, boolean waveForm, boolean fft); //--------------------------------------------------------- @@ -776,17 +738,47 @@ public class Visualizer { //-------------------- @SuppressWarnings("unused") private static void postEventFromNative(Object effect_ref, - int what, int arg1, int arg2, Object obj) { - Visualizer visu = (Visualizer)((WeakReference)effect_ref).get(); - if (visu == null) { - return; - } + int what, int samplingRate, byte[] data) { + final Visualizer visualizer = (Visualizer) ((WeakReference) effect_ref).get(); + if (visualizer == null) return; - if (visu.mNativeEventHandler != null) { - Message m = visu.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj); - visu.mNativeEventHandler.sendMessage(m); + final Handler handler; + synchronized (visualizer.mListenerLock) { + handler = visualizer.mNativeEventHandler; } + if (handler == null) return; + switch (what) { + case NATIVE_EVENT_PCM_CAPTURE: + case NATIVE_EVENT_FFT_CAPTURE: + handler.post(() -> { + final OnDataCaptureListener l; + synchronized (visualizer.mListenerLock) { + l = visualizer.mCaptureListener; + } + if (l != null) { + if (what == NATIVE_EVENT_PCM_CAPTURE) { + l.onWaveFormDataCapture(visualizer, data, samplingRate); + } else { // what == NATIVE_EVENT_FFT_CAPTURE + l.onFftDataCapture(visualizer, data, samplingRate); + } + } + }); + break; + case NATIVE_EVENT_SERVER_DIED: + handler.post(() -> { + final OnServerDiedListener l; + synchronized (visualizer.mListenerLock) { + l = visualizer.mServerDiedListener; + } + if (l != null) { + l.onServerDied(); + } + }); + break; + default: + Log.e(TAG, "Unknown native event in postEventFromNative: " + what); + break; + } } } - diff --git a/media/java/android/media/tv/OWNERS b/media/java/android/media/tv/OWNERS index 64c0bb53e894..a891154301ed 100644 --- a/media/java/android/media/tv/OWNERS +++ b/media/java/android/media/tv/OWNERS @@ -3,3 +3,7 @@ nchalko@google.com shubang@google.com quxiangfang@google.com +# For android remote service +per-file ITvRemoteServiceInput.aidl = file:/media/lib/tvremote/OWNERS +per-file ITvRemoteProvider.aidl = file:/media/lib/tvremote/OWNERS + diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp index 83f3b6ed6217..efeb3352d393 100644 --- a/media/jni/audioeffect/Visualizer.cpp +++ b/media/jni/audioeffect/Visualizer.cpp @@ -120,8 +120,9 @@ status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t } if (mCaptureThread != 0) { + sp<CaptureThread> t = mCaptureThread; mCaptureLock.unlock(); - mCaptureThread->requestExitAndWait(); + t->requestExitAndWait(); mCaptureLock.lock(); } diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp index 1362433bb26e..f9a77f474c50 100644 --- a/media/jni/audioeffect/android_media_Visualizer.cpp +++ b/media/jni/audioeffect/android_media_Visualizer.cpp @@ -196,7 +196,6 @@ static void captureCallback(void* user, callbackInfo->visualizer_ref, NATIVE_EVENT_PCM_CAPTURE, samplingrate, - 0, jArray); } } @@ -217,7 +216,6 @@ static void captureCallback(void* user, callbackInfo->visualizer_ref, NATIVE_EVENT_FFT_CAPTURE, samplingrate, - 0, jArray); } } @@ -286,7 +284,7 @@ android_media_visualizer_native_init(JNIEnv *env) // Get the postEvent method fields.midPostNativeEvent = env->GetStaticMethodID( fields.clazzEffect, - "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V"); + "postEventFromNative", "(Ljava/lang/Object;II[B)V"); if (fields.midPostNativeEvent == NULL) { ALOGE("Can't find Visualizer.%s", "postEventFromNative"); return; @@ -343,7 +341,7 @@ static void android_media_visualizer_effect_callback(int32_t event, fields.midPostNativeEvent, callbackInfo->visualizer_ref, NATIVE_EVENT_SERVER_DIED, - 0, 0, NULL); + 0, NULL); } } diff --git a/media/tests/EffectsTest/res/layout/visualizertest.xml b/media/tests/EffectsTest/res/layout/visualizertest.xml index 50ac7bbd8cd0..18d7a3648fbf 100644 --- a/media/tests/EffectsTest/res/layout/visualizertest.xml +++ b/media/tests/EffectsTest/res/layout/visualizertest.xml @@ -56,6 +56,37 @@ android:layout_height="wrap_content" android:scaleType="fitXY"/> + <LinearLayout android:id="@+id/visuMultithreadedLayout" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="10dip" + android:layout_marginTop="10dip" + android:layout_marginRight="10dip" + android:layout_marginBottom="10dip" > + + <TextView android:id="@+id/visuMultithreaded" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_weight="1.0" + android:layout_gravity="center_vertical|left" + android:text="@string/effect_multithreaded" + style="@android:style/TextAppearance.Medium" /> + + <ToggleButton android:id="@+id/visuMultithreadedOnOff" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_gravity="center_vertical|right" + android:layout_weight="0.0" /> + + </LinearLayout> + + <ImageView + android:src="@android:drawable/divider_horizontal_dark" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:scaleType="fitXY"/> + <LinearLayout android:id="@+id/visuControlLayout" android:orientation="horizontal" android:layout_width="fill_parent" diff --git a/media/tests/EffectsTest/res/values/strings.xml b/media/tests/EffectsTest/res/values/strings.xml index 2a8518417565..7c12da1274e3 100644 --- a/media/tests/EffectsTest/res/values/strings.xml +++ b/media/tests/EffectsTest/res/values/strings.xml @@ -35,4 +35,6 @@ <string name="effect_attach_off">Attach</string> <string name="effect_attach_on">Detach</string> <string name="send_level_name">Send Level</string> + <!-- Toggles use of a multi-threaded client for an effect [CHAR LIMIT=24] --> + <string name="effect_multithreaded">Multithreaded Use</string> </resources> diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java new file mode 100644 index 000000000000..817bd3d7bf5e --- /dev/null +++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java @@ -0,0 +1,25 @@ +/* + * 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.effectstest; + +interface VisualizerInstance { + void enableDataCaptureListener(boolean enable); + boolean getEnabled(); + void release(); + void setEnabled(boolean enabled); + void startStopCapture(boolean start); +} diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceMT.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceMT.java new file mode 100644 index 000000000000..89cfbebe17ce --- /dev/null +++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceMT.java @@ -0,0 +1,113 @@ +/* + * 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.effectstest; + +import android.os.Handler; +import android.os.Looper; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; + +class VisualizerInstanceMT implements VisualizerInstance { + + private static final String TAG = "VisualizerInstanceMT"; + + private final Object mLock = new Object(); + private final int mThreadCount; + @GuardedBy("mLock") + private Handler mVisualizerHandler; + @GuardedBy("mLock") + private VisualizerInstanceSync mVisualizer; + + VisualizerInstanceMT(int session, Handler uiHandler, int extraThreadCount) { + Log.d(TAG, "Multi-threaded constructor"); + mThreadCount = 1 + extraThreadCount; + Thread t = new Thread() { + @Override public void run() { + Looper.prepare(); + VisualizerInstanceSync v = new VisualizerInstanceSync(session, uiHandler); + synchronized (mLock) { + mVisualizerHandler = new Handler(); + mVisualizer = v; + } + Looper.loop(); + } + }; + t.start(); + } + + private VisualizerInstance getVisualizer() { + synchronized (mLock) { + return mVisualizer != null ? new VisualizerInstanceSync(mVisualizer) : null; + } + } + + private interface VisualizerOperation { + void run(VisualizerInstance v); + } + + private void runOperationMt(VisualizerOperation op) { + final VisualizerInstance v = getVisualizer(); + if (v == null) return; + for (int i = 0; i < mThreadCount; ++i) { + Thread t = new Thread() { + @Override + public void run() { + op.run(v); + } + }; + t.start(); + } + } + + @Override + public void enableDataCaptureListener(boolean enable) { + runOperationMt(v -> v.enableDataCaptureListener(enable)); + } + + @Override + public boolean getEnabled() { + final VisualizerInstance v = getVisualizer(); + return v != null ? v.getEnabled() : false; + } + + @Override + public void release() { + runOperationMt(v -> v.release()); + synchronized (mLock) { + if (mVisualizerHandler == null) return; + mVisualizerHandler.post(() -> { + synchronized (mLock) { + mVisualizerHandler = null; + mVisualizer = null; + Looper.myLooper().quitSafely(); + } + Log.d(TAG, "Exiting looper"); + }); + } + } + + @Override + public void setEnabled(boolean enabled) { + runOperationMt(v -> v.setEnabled(enabled)); + } + + @Override + public void startStopCapture(boolean start) { + runOperationMt(v -> v.startStopCapture(start)); + } +} diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceSync.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceSync.java new file mode 100644 index 000000000000..e64f4e5785c8 --- /dev/null +++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceSync.java @@ -0,0 +1,170 @@ +/* + * 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.effectstest; + +import android.media.audiofx.Visualizer; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +// This class only has `final' members, thus any thread-safety concerns +// can only come from the Visualizer effect class. +class VisualizerInstanceSync implements VisualizerInstance { + + private static final String TAG = "VisualizerInstance"; + + private final Handler mUiHandler; + private final Visualizer mVisualizer; + private final VisualizerTestHandler mVisualizerTestHandler; + private final VisualizerListener mVisualizerListener; + + VisualizerInstanceSync(int session, Handler uiHandler) { + mUiHandler = uiHandler; + try { + mVisualizer = new Visualizer(session); + } catch (UnsupportedOperationException e) { + Log.e(TAG, "Visualizer library not loaded"); + throw new RuntimeException("Cannot initialize effect"); + } catch (RuntimeException e) { + throw e; + } + mVisualizerTestHandler = new VisualizerTestHandler(); + mVisualizerListener = new VisualizerListener(); + } + + // Not a "deep" copy, only copies the references. + VisualizerInstanceSync(VisualizerInstanceSync other) { + mUiHandler = other.mUiHandler; + mVisualizer = other.mVisualizer; + mVisualizerTestHandler = other.mVisualizerTestHandler; + mVisualizerListener = other.mVisualizerListener; + } + + @Override + public void enableDataCaptureListener(boolean enable) { + mVisualizer.setDataCaptureListener(enable ? mVisualizerListener : null, + 10000, enable, enable); + } + + @Override + public boolean getEnabled() { + return mVisualizer.getEnabled(); + } + + @Override + public void release() { + mVisualizer.release(); + Log.d(TAG, "Visualizer released"); + } + + @Override + public void setEnabled(boolean enabled) { + mVisualizer.setEnabled(enabled); + } + + @Override + public void startStopCapture(boolean start) { + mVisualizerTestHandler.sendMessage(mVisualizerTestHandler.obtainMessage( + start ? MSG_START_CAPTURE : MSG_STOP_CAPTURE)); + } + + private static final int MSG_START_CAPTURE = 0; + private static final int MSG_STOP_CAPTURE = 1; + private static final int MSG_NEW_CAPTURE = 2; + private static final int CAPTURE_PERIOD_MS = 100; + + private static int[] dataToMinMaxCenter(byte[] data, int len) { + int[] minMaxCenter = new int[3]; + minMaxCenter[0] = data[0]; + minMaxCenter[1] = data[len - 1]; + minMaxCenter[2] = data[len / 2]; + return minMaxCenter; + } + + private class VisualizerTestHandler extends Handler { + private final int mCaptureSize; + private boolean mActive = false; + + VisualizerTestHandler() { + mCaptureSize = mVisualizer.getCaptureSize(); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_START_CAPTURE: + if (!mActive) { + Log.d(TAG, "Start capture"); + mActive = true; + sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE), CAPTURE_PERIOD_MS); + } + break; + case MSG_STOP_CAPTURE: + if (mActive) { + Log.d(TAG, "Stop capture"); + mActive = false; + } + break; + case MSG_NEW_CAPTURE: + if (mActive) { + if (mCaptureSize > 0) { + byte[] data = new byte[mCaptureSize]; + if (mVisualizer.getWaveForm(data) == Visualizer.SUCCESS) { + int len = data.length < mCaptureSize ? data.length : mCaptureSize; + mUiHandler.sendMessage( + mUiHandler.obtainMessage( + VisualizerTest.MSG_DISPLAY_WAVEFORM_VAL, + dataToMinMaxCenter(data, len))); + } + if (mVisualizer.getFft(data) == Visualizer.SUCCESS) { + int len = data.length < mCaptureSize ? data.length : mCaptureSize; + mUiHandler.sendMessage( + mUiHandler.obtainMessage(VisualizerTest.MSG_DISPLAY_FFT_VAL, + dataToMinMaxCenter(data, len))); + } + } + sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE), CAPTURE_PERIOD_MS); + } + break; + } + } + } + + private class VisualizerListener implements Visualizer.OnDataCaptureListener { + @Override + public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, + int samplingRate) { + if (visualizer == mVisualizer && waveform.length > 0) { + Log.d(TAG, "onWaveFormDataCapture(): " + waveform[0] + + " smp rate: " + samplingRate / 1000); + mUiHandler.sendMessage( + mUiHandler.obtainMessage(VisualizerTest.MSG_DISPLAY_WAVEFORM_VAL, + dataToMinMaxCenter(waveform, waveform.length))); + } + } + + @Override + public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) { + if (visualizer == mVisualizer && fft.length > 0) { + Log.d(TAG, "onFftDataCapture(): " + fft[0]); + mUiHandler.sendMessage( + mUiHandler.obtainMessage(VisualizerTest.MSG_DISPLAY_FFT_VAL, + dataToMinMaxCenter(fft, fft.length))); + } + } + } +} diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java index 7db1d8d8625e..2e141c5ef7c8 100644 --- a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java +++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java @@ -17,51 +17,42 @@ package com.android.effectstest; import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.media.audiofx.Visualizer; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.KeyEvent; -import android.view.Menu; import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.EditText; import android.widget.TextView; import android.widget.ToggleButton; -import android.widget.SeekBar; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; import java.util.HashMap; -import java.util.Map; public class VisualizerTest extends Activity implements OnCheckedChangeListener { private final static String TAG = "Visualizer Test"; - private Visualizer mVisualizer; + private VisualizerInstance mVisualizer; + ToggleButton mMultithreadedButton; ToggleButton mOnOffButton; ToggleButton mReleaseButton; + boolean mUseMTInstance; boolean mEnabled; EditText mSessionText; static int sSession = 0; - int mCaptureSize; ToggleButton mCallbackButton; boolean mCallbackOn; - VisualizerListener mVisualizerListener; - private static HashMap<Integer, Visualizer> sInstances = new HashMap<Integer, Visualizer>(10); - private VisualizerTestHandler mVisualizerTestHandler = null; + private static HashMap<Integer, VisualizerInstance> sInstances = + new HashMap<Integer, VisualizerInstance>(10); + private Handler mUiHandler; public VisualizerTest() { Log.d(TAG, "contructor"); + mUiHandler = new UiHandler(Looper.getMainLooper()); } @Override @@ -76,109 +67,45 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener mSessionText.setOnKeyListener(mSessionKeyListener); mSessionText.setText(Integer.toString(sSession)); - mReleaseButton = (ToggleButton)findViewById(R.id.visuReleaseButton); - mOnOffButton = (ToggleButton)findViewById(R.id.visualizerOnOff); - mCallbackButton = (ToggleButton)findViewById(R.id.visuCallbackOnOff); + mMultithreadedButton = (ToggleButton) findViewById(R.id.visuMultithreadedOnOff); + mReleaseButton = (ToggleButton) findViewById(R.id.visuReleaseButton); + mOnOffButton = (ToggleButton) findViewById(R.id.visualizerOnOff); + mCallbackButton = (ToggleButton) findViewById(R.id.visuCallbackOnOff); mCallbackOn = false; mCallbackButton.setChecked(mCallbackOn); - mVisualizerTestHandler = new VisualizerTestHandler(); - mVisualizerListener = new VisualizerListener(); - - getEffect(sSession); - - if (mVisualizer != null) { + mMultithreadedButton.setOnCheckedChangeListener(this); + if (getEffect(sSession) != null) { mReleaseButton.setOnCheckedChangeListener(this); mOnOffButton.setOnCheckedChangeListener(this); mCallbackButton.setOnCheckedChangeListener(this); } } - private static final int MSG_START_CAPTURE = 0; - private static final int MSG_STOP_CAPTURE = 1; - private static final int MSG_NEW_CAPTURE = 2; - private static final int CAPTURE_PERIOD_MS = 100; + public static final int MSG_DISPLAY_WAVEFORM_VAL = 0; + public static final int MSG_DISPLAY_FFT_VAL = 1; + + private class UiHandler extends Handler { + UiHandler(Looper looper) { + super(looper); + } - private class VisualizerTestHandler extends Handler { - boolean mActive = false; @Override public void handleMessage(Message msg) { switch (msg.what) { - case MSG_START_CAPTURE: - if (!mActive) { - Log.d(TAG, "Start capture"); - mActive = true; - sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS); - } - break; - case MSG_STOP_CAPTURE: - if (mActive) { - Log.d(TAG, "Stop capture"); - mActive = false; - } - break; - case MSG_NEW_CAPTURE: - if (mActive && mVisualizer != null) { - if (mCaptureSize > 0) { - byte[] data = new byte[mCaptureSize]; - if (mVisualizer.getWaveForm(data) == Visualizer.SUCCESS) { - int len = data.length < mCaptureSize ? data.length : mCaptureSize; - displayVal(R.id.waveformMin, data[0]); - displayVal(R.id.waveformMax, data[len-1]); - displayVal(R.id.waveformCenter, data[len/2]); - }; - if (mVisualizer.getFft(data) == Visualizer.SUCCESS) { - int len = data.length < mCaptureSize ? data.length : mCaptureSize; - displayVal(R.id.fftMin, data[0]); - displayVal(R.id.fftMax, data[len-1]); - displayVal(R.id.fftCenter, data[len/2]); - }; - } - sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS); - } - break; - } - } - } - - private class VisualizerListener implements Visualizer.OnDataCaptureListener { - - public VisualizerListener() { - } - public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) { - if (visualizer == mVisualizer) { - if (waveform.length > 0) { - Log.d(TAG, "onWaveFormDataCapture(): "+waveform[0]+" smp rate: "+samplingRate/1000); - displayVal(R.id.waveformMin, waveform[0]); - displayVal(R.id.waveformMax, waveform[waveform.length - 1]); - displayVal(R.id.waveformCenter, waveform[waveform.length/2]); + case MSG_DISPLAY_WAVEFORM_VAL: + case MSG_DISPLAY_FFT_VAL: + int[] minMaxCenter = (int[]) msg.obj; + boolean waveform = msg.what == MSG_DISPLAY_WAVEFORM_VAL; + displayVal(waveform ? R.id.waveformMin : R.id.fftMin, minMaxCenter[0]); + displayVal(waveform ? R.id.waveformMax : R.id.fftMax, minMaxCenter[1]); + displayVal(waveform ? R.id.waveformCenter : R.id.fftCenter, minMaxCenter[2]); + break; } - } - } - public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) { - if (visualizer == mVisualizer) { - if (fft.length > 0) { - Log.d(TAG, "onFftDataCapture(): "+fft[0]); - displayVal(R.id.fftMin, fft[0]); - displayVal(R.id.fftMax, fft[fft.length - 1]); - displayVal(R.id.fftCenter, fft[fft.length/2]); - } - } } } - @Override - public void onResume() { - super.onResume(); - } - - @Override - public void onPause() { - super.onPause(); - } - - private View.OnKeyListener mSessionKeyListener - = new View.OnKeyListener() { + private View.OnKeyListener mSessionKeyListener = new View.OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { switch (keyCode) { @@ -199,29 +126,26 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener }; // OnCheckedChangeListener + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (buttonView.getId() == R.id.visuMultithreadedOnOff) { + mUseMTInstance = isChecked; + Log.d(TAG, "Multi-threaded client: " + (isChecked ? "enabled" : "disabled")); + } if (buttonView.getId() == R.id.visualizerOnOff) { if (mVisualizer != null) { mEnabled = isChecked; mCallbackButton.setEnabled(!mEnabled); if (mCallbackOn && mEnabled) { - mVisualizer.setDataCaptureListener(mVisualizerListener, - 10000, - true, - true); + mVisualizer.enableDataCaptureListener(true); } mVisualizer.setEnabled(mEnabled); if (mCallbackOn) { if (!mEnabled) { - mVisualizer.setDataCaptureListener(null, - 10000, - false, - false); + mVisualizer.enableDataCaptureListener(false); } } else { - int msg = isChecked ? MSG_START_CAPTURE : MSG_STOP_CAPTURE; - mVisualizerTestHandler.sendMessage( - mVisualizerTestHandler.obtainMessage(msg, 0, 0, null)); + mVisualizer.startStopCapture(isChecked); } } } @@ -248,16 +172,15 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener } - private void getEffect(int session) { + private VisualizerInstance getEffect(int session) { synchronized (sInstances) { if (sInstances.containsKey(session)) { mVisualizer = sInstances.get(session); } else { - try{ - mVisualizer = new Visualizer(session); - } catch (UnsupportedOperationException e) { - Log.e(TAG,"Visualizer library not loaded"); - throw (new RuntimeException("Cannot initialize effect")); + try { + mVisualizer = mUseMTInstance + ? new VisualizerInstanceMT(session, mUiHandler, 0 /*extraThreadCount*/) + : new VisualizerInstanceSync(session, mUiHandler); } catch (RuntimeException e) { throw e; } @@ -267,8 +190,6 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener mReleaseButton.setEnabled(false); mOnOffButton.setEnabled(false); if (mVisualizer != null) { - mCaptureSize = mVisualizer.getCaptureSize(); - mReleaseButton.setChecked(true); mReleaseButton.setEnabled(true); @@ -278,6 +199,7 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener mCallbackButton.setEnabled(!mEnabled); } + return mVisualizer; } private void putEffect(int session) { @@ -286,9 +208,8 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener synchronized (sInstances) { if (mVisualizer != null) { mVisualizer.release(); - Log.d(TAG,"Visualizer released"); - mVisualizer = null; sInstances.remove(session); + mVisualizer = null; } } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java index c9c847ff7194..3c7856048860 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java @@ -218,24 +218,32 @@ public class A2dpProfile implements LocalBluetoothProfile { } public boolean supportsHighQualityAudio(BluetoothDevice device) { - int support = mService.supportsOptionalCodecs(device); + BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice(); + if (bluetoothDevice == null) { + return false; + } + int support = mService.isOptionalCodecsSupported(bluetoothDevice); return support == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED; } public boolean isHighQualityAudioEnabled(BluetoothDevice device) { - int enabled = mService.getOptionalCodecsEnabled(device); + BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice(); + if (bluetoothDevice == null) { + return false; + } + int enabled = mService.isOptionalCodecsEnabled(bluetoothDevice); if (enabled != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN) { return enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED; - } else if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED && - supportsHighQualityAudio(device)) { + } else if (getConnectionStatus(bluetoothDevice) != BluetoothProfile.STATE_CONNECTED + && supportsHighQualityAudio(bluetoothDevice)) { // Since we don't have a stored preference and the device isn't connected, just return // true since the default behavior when the device gets connected in the future would be // to have optional codecs enabled. return true; } BluetoothCodecConfig codecConfig = null; - if (mService.getCodecStatus(device) != null) { - codecConfig = mService.getCodecStatus(device).getCodecConfig(); + if (mService.getCodecStatus(bluetoothDevice) != null) { + codecConfig = mService.getCodecStatus(bluetoothDevice).getCodecConfig(); } if (codecConfig != null) { return !codecConfig.isMandatoryCodec(); @@ -245,23 +253,28 @@ public class A2dpProfile implements LocalBluetoothProfile { } public void setHighQualityAudioEnabled(BluetoothDevice device, boolean enabled) { + BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice(); + if (bluetoothDevice == null) { + return; + } int prefValue = enabled ? BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED : BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED; - mService.setOptionalCodecsEnabled(device, prefValue); - if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) { + mService.setOptionalCodecsEnabled(bluetoothDevice, prefValue); + if (getConnectionStatus(bluetoothDevice) != BluetoothProfile.STATE_CONNECTED) { return; } if (enabled) { - mService.enableOptionalCodecs(device); + mService.enableOptionalCodecs(bluetoothDevice); } else { - mService.disableOptionalCodecs(device); + mService.disableOptionalCodecs(bluetoothDevice); } } public String getHighQualityAudioOptionLabel(BluetoothDevice device) { + BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice(); int unknownCodecId = R.string.bluetooth_profile_a2dp_high_quality_unknown_codec; - if (!supportsHighQualityAudio(device) + if (bluetoothDevice == null || !supportsHighQualityAudio(device) || getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) { return mContext.getString(unknownCodecId); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index bb9d42ecd77c..994a9b32550d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -611,8 +611,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> * If a connect was attempted earlier without any UUID, we will do the connect now. * Otherwise, allow the connect on UUID change. */ - if (!mProfiles.isEmpty() - && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime())) { + if ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()) { + Log.d(TAG, "onUuidChanged: triggering connectAllEnabledProfiles"); connectAllEnabledProfiles(); } diff --git a/packages/SettingsLib/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/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java index 414c39bc0ce9..9afdd43ce73c 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java @@ -69,30 +69,31 @@ public class A2dpProfileTest { mProfile = new A2dpProfile(mContext, mDeviceManager, mProfileManager); mServiceListener = mShadowBluetoothAdapter.getServiceListener(); mServiceListener.onServiceConnected(BluetoothProfile.A2DP, mBluetoothA2dp); + when(mBluetoothA2dp.getActiveDevice()).thenReturn(mDevice); } @Test public void supportsHighQualityAudio() { - when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED); assertThat(mProfile.supportsHighQualityAudio(mDevice)).isTrue(); - when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED); assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse(); - when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN); assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse(); } @Test public void isHighQualityAudioEnabled() { - when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue(); - when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED); assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse(); @@ -100,16 +101,16 @@ public class A2dpProfileTest { // then isHighQualityAudioEnabled() should return true or false based on whether optional // codecs are supported. If the device is connected then we should ask it directly, but if // the device isn't connected then rely on the stored pref about such support. - when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN); when(mBluetoothA2dp.getConnectionState(any())).thenReturn( BluetoothProfile.STATE_DISCONNECTED); - when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED); assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse(); - when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED); assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue(); @@ -151,14 +152,14 @@ public class A2dpProfileTest { // Most tests want to simulate optional codecs being supported by the device, so do that // by default here. - when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsSupported(any())).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED); } @Test public void getLableCodecsNotSupported() { setupLabelTest(); - when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn( + when(mBluetoothA2dp.isOptionalCodecsSupported(any())).thenReturn( BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED); assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(UNKNOWN_CODEC_LABEL); } diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index f44f9cf671c7..ff91c797e9b1 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -241,6 +241,12 @@ <!-- Permission needed to read wifi network credentials for CtsNetTestCases --> <uses-permission android:name="android.permission.READ_WIFI_CREDENTIAL" /> + <!-- Permission needed to use wifi usability API's for CtsNetTestCases --> + <uses-permission android:name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE" /> + + <!-- Permission required for testing system audio effect APIs. --> + <uses-permission android:name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"/> + <application android:label="@string/app_label" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:defaultToDeviceProtectedStorage="true" 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/SystemUI/res/drawable/ic_qs_nfc_enabled.xml b/packages/SystemUI/res/drawable/ic_qs_nfc.xml index becb18ad8ba2..2c080964b48e 100644 --- a/packages/SystemUI/res/drawable/ic_qs_nfc_enabled.xml +++ b/packages/SystemUI/res/drawable/ic_qs_nfc.xml @@ -14,8 +14,8 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="48dp" + android:height="48dp" android:viewportWidth="24" android:viewportHeight="24"> diff --git a/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml deleted file mode 100644 index 558f3d083f42..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- - Copyright (C) 2016 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M4 20h16V4H4v16z" /> - <path - android:fillColor="#4DFFFFFF" - android:pathData="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1 .9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 -18H4V4h16v16zM18 6h-5c-1.1 0-2 .9-2 2v2.28c-.6 .35 -1 .98-1 1.72 0 1.1 .9 2 2 -2s2-.9 2-2c0-.74-.4-1.38-1-1.72V8h3v8H8V8h2V6H6v12h12V6z" /> - <path - android:pathData="M0 0h24v24H0z" /> -</vector> diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml index 24374e80b211..df717f601763 100644 --- a/packages/SystemUI/res/layout/menu_ime.xml +++ b/packages/SystemUI/res/layout/menu_ime.xml @@ -17,13 +17,13 @@ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:id="@+id/menu_container" - android:layout_width="@dimen/navigation_key_width" + android:layout_width="@dimen/navigation_side_padding" android:layout_height="match_parent" android:importantForAccessibility="no" > <!-- Use nav button width & height=match_parent for parent FrameLayout and buttons because they are placed inside a view that has a size controlled by weight. Ensure weight is large enough to - support icon size. --> + support icon size. Use layout_width=navigation_side_padding like other navbar buttons. --> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java index 476a239de721..d0bd073e2480 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java @@ -38,6 +38,8 @@ import javax.inject.Inject; /** Quick settings tile: Enable/Disable NFC **/ public class NfcTile extends QSTileImpl<BooleanState> { + private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_nfc); + private NfcAdapter mAdapter; private boolean mListening; @@ -105,8 +107,7 @@ public class NfcTile extends QSTileImpl<BooleanState> { state.state = getAdapter() == null ? Tile.STATE_UNAVAILABLE : state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; - state.icon = ResourceIcon.get( - state.value ? R.drawable.ic_qs_nfc_enabled : R.drawable.ic_qs_nfc_disabled); + state.icon = mIcon; state.label = mContext.getString(R.string.quick_settings_nfc_label); state.expandedAccessibilityClassName = Switch.class.getName(); state.contentDescription = state.label; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java index ef09434aa395..7f7db2f3ed3d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java @@ -23,6 +23,7 @@ import android.app.NotificationManager; import android.content.Context; import android.database.ContentObserver; import android.hardware.display.AmbientDisplayConfiguration; +import android.os.Build; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; @@ -53,7 +54,7 @@ public class NotificationInterruptionStateProvider { private static final String TAG = "InterruptionStateProvider"; private static final boolean DEBUG = false; - private static final boolean DEBUG_HEADS_UP = true; + private static final boolean DEBUG_HEADS_UP = Build.IS_DEBUGGABLE; private static final boolean ENABLE_HEADS_UP = true; private static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up"; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 7892381ae19f..48534f6c985a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -577,7 +577,7 @@ public class MobileSignalController extends SignalController< } boolean isDataDisabled() { - return !mPhone.isDataConnectionEnabled(); + return !mPhone.isDataConnectionAllowed(); } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index c08726de9b66..e3d8ea2f9048 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN; import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT; import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE; @@ -160,6 +161,7 @@ public class NetworkControllerImpl extends BroadcastReceiver ServiceState mLastServiceState; private boolean mUserSetup; private boolean mSimDetected; + private boolean mForceCellularValidated; /** * Construct this controller object and register for updates. @@ -275,12 +277,41 @@ public class NetworkControllerImpl extends BroadcastReceiver mPhoneStateListener = new PhoneStateListener(bgLooper) { @Override public void onActiveDataSubscriptionIdChanged(int subId) { + // For data switching from A to B, we assume B is validated for up to 2 seconds iff: + // 1) A and B are in the same subscription group e.g. CBRS data switch. And + // 2) A was validated before the switch. + // This is to provide smooth transition for UI without showing cross during data + // switch. + if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) { + if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true."); + mForceCellularValidated = true; + mReceiverHandler.removeCallbacks(mClearForceValidated); + mReceiverHandler.postDelayed(mClearForceValidated, 2000); + } mActiveMobileDataSubscription = subId; doUpdateMobileControllers(); } }; } + private final Runnable mClearForceValidated = () -> { + if (DEBUG) Log.d(TAG, ": mClearForceValidated"); + mForceCellularValidated = false; + updateConnectivity(); + }; + + boolean isInGroupDataSwitch(int subId1, int subId2) { + SubscriptionInfo info1 = mSubscriptionManager.getActiveSubscriptionInfo(subId1); + SubscriptionInfo info2 = mSubscriptionManager.getActiveSubscriptionInfo(subId2); + return (info1 != null && info2 != null && info1.getGroupUuid() != null + && info1.getGroupUuid().equals(info2.getGroupUuid())); + } + + boolean keepCellularValidationBitInSwitch(int sourceSubId, int destSubId) { + return mValidatedTransports.get(TRANSPORT_CELLULAR) + && isInGroupDataSwitch(sourceSubId, destSubId); + } + public DataSaverController getDataSaverController() { return mDataSaverController; } @@ -794,6 +825,8 @@ public class NetworkControllerImpl extends BroadcastReceiver } } + if (mForceCellularValidated) mValidatedTransports.set(TRANSPORT_CELLULAR); + if (CHATTY) { Log.d(TAG, "updateConnectivity: mConnectedTransports=" + mConnectedTransports); Log.d(TAG, "updateConnectivity: mValidatedTransports=" + mValidatedTransports); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java index 5a8ff4bfbeff..7f4d614f1d33 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java @@ -19,7 +19,7 @@ package com.android.keyguard; import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE; import static android.telephony.SubscriptionManager.DATA_ROAMING_ENABLE; -import static android.telephony.SubscriptionManager.NAME_SOURCE_DEFAULT; +import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID; import static junit.framework.Assert.assertTrue; import static junit.framework.TestCase.assertFalse; @@ -79,14 +79,14 @@ public class CarrierTextControllerTest extends SysuiTestCase { private static final String TEST_CARRIER_2 = "TEST_CARRIER_2"; private static final int TEST_CARRIER_ID = 1; private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(0, "", 0, - TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT, 0xFFFFFF, "", + TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "", DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", false, null, TEST_CARRIER_ID, 0); private static final SubscriptionInfo TEST_SUBSCRIPTION_NULL = new SubscriptionInfo(0, "", 0, - TEST_CARRIER, null, NAME_SOURCE_DEFAULT, 0xFFFFFF, "", DATA_ROAMING_DISABLE, + TEST_CARRIER, null, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "", DATA_ROAMING_DISABLE, null, null, null, null, false, null, ""); private static final SubscriptionInfo TEST_SUBSCRIPTION_ROAMING = new SubscriptionInfo(0, "", 0, - TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT, 0xFFFFFF, "", + TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "", DATA_ROAMING_ENABLE, null, null, null, null, false, null, ""); @Mock private WifiManager mWifiManager; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 78687a2964c9..9271caf0b721 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -17,7 +17,7 @@ package com.android.keyguard; import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE; -import static android.telephony.SubscriptionManager.NAME_SOURCE_DEFAULT; +import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID; import static com.google.common.truth.Truth.assertThat; @@ -83,11 +83,11 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { private static final int TEST_CARRIER_ID = 1; private static final String TEST_GROUP_UUID = "59b5c870-fc4c-47a4-a99e-9db826b48b24"; private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(1, "", 0, - TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT, 0xFFFFFF, "", + TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "", DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", false, TEST_GROUP_UUID, TEST_CARRIER_ID, 0); private static final SubscriptionInfo TEST_SUBSCRIPTION_2 = new SubscriptionInfo(2, "", 0, - TEST_CARRIER, TEST_CARRIER_2, NAME_SOURCE_DEFAULT, 0xFFFFFF, "", + TEST_CARRIER, TEST_CARRIER_2, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "", DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", true, TEST_GROUP_UUID, TEST_CARRIER_ID, 0); @Mock diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java index 264905483ddc..698185fe5154 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java @@ -176,7 +176,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected void setupNetworkController() { // For now just pretend to be the data sim, so we can test that too. mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; - when(mMockTm.isDataConnectionEnabled()).thenReturn(true); + when(mMockTm.isDataConnectionAllowed()).thenReturn(true); setDefaultSubId(mSubId); setSubscriptions(mSubId); mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java index 6b02ff01aafa..bac1b8ca240c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java @@ -119,7 +119,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { @Test public void testNoInternetIcon_withDefaultSub() { setupNetworkController(); - when(mMockTm.isDataConnectionEnabled()).thenReturn(false); + when(mMockTm.isDataConnectionAllowed()).thenReturn(false); setupDefaultSignal(); updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0); setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false); @@ -133,7 +133,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { @Test public void testDataDisabledIcon_withDefaultSub() { setupNetworkController(); - when(mMockTm.isDataConnectionEnabled()).thenReturn(false); + when(mMockTm.isDataConnectionAllowed()).thenReturn(false); setupDefaultSignal(); updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0); setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false); @@ -147,7 +147,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { @Test public void testNonDefaultSIM_showsFullSignal_connected() { setupNetworkController(); - when(mMockTm.isDataConnectionEnabled()).thenReturn(false); + when(mMockTm.isDataConnectionAllowed()).thenReturn(false); setupDefaultSignal(); setDefaultSubId(mSubId + 1); updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0); @@ -162,7 +162,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { @Test public void testNonDefaultSIM_showsFullSignal_disconnected() { setupNetworkController(); - when(mMockTm.isDataConnectionEnabled()).thenReturn(false); + when(mMockTm.isDataConnectionAllowed()).thenReturn(false); setupDefaultSignal(); setDefaultSubId(mSubId + 1); updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0); @@ -177,7 +177,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { @Test public void testDataDisabledIcon_UserNotSetup() { setupNetworkController(); - when(mMockTm.isDataConnectionEnabled()).thenReturn(false); + when(mMockTm.isDataConnectionAllowed()).thenReturn(false); setupDefaultSignal(); updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0); setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false); @@ -192,7 +192,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { @Test public void testAlwaysShowDataRatIcon() { setupDefaultSignal(); - when(mMockTm.isDataConnectionEnabled()).thenReturn(false); + when(mMockTm.isDataConnectionAllowed()).thenReturn(false); updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, TelephonyManager.NETWORK_TYPE_GSM); diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml index c71d0d7bc543..9328611f5d3f 100644 --- a/packages/Tethering/AndroidManifest.xml +++ b/packages/Tethering/AndroidManifest.xml @@ -27,7 +27,7 @@ added to the privileged permissions whitelist for that package. --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.BLUETOOTH" /> - <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.MANAGE_USB" /> diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp index 5b73dd53a285..00d0d9c428ff 100644 --- a/packages/Tethering/common/TetheringLib/Android.bp +++ b/packages/Tethering/common/TetheringLib/Android.bp @@ -60,28 +60,17 @@ java_library { hostdex: true, // for hiddenapi check visibility: ["//frameworks/base/packages/Tethering:__subpackages__"], apex_available: ["com.android.tethering"], + permitted_packages: ["android.net"], } -droidstubs { - name: "framework-tethering-stubs-sources", - defaults: ["framework-module-stubs-defaults-module_libs_api"], +stubs_defaults { + name: "framework-tethering-stubs-defaults", srcs: [ "src/android/net/TetheredClient.java", "src/android/net/TetheringManager.java", "src/android/net/TetheringConstants.java", ], - libs: [ - "tethering-aidl-interfaces-java", - "framework-all", - ], - sdk_version: "core_platform", -} - -java_library { - name: "framework-tethering-stubs", - srcs: [":framework-tethering-stubs-sources"], - libs: ["framework-all"], - sdk_version: "core_platform", + libs: ["tethering-aidl-interfaces-java"], } filegroup { @@ -101,3 +90,53 @@ filegroup { ], path: "src" } + +droidstubs { + name: "framework-tethering-stubs-srcs-publicapi", + defaults: [ + "framework-module-stubs-defaults-publicapi", + "framework-tethering-stubs-defaults", + ], +} + +droidstubs { + name: "framework-tethering-stubs-srcs-systemapi", + defaults: [ + "framework-module-stubs-defaults-systemapi", + "framework-tethering-stubs-defaults", + ], +} + +droidstubs { + name: "framework-tethering-api-module_libs_api", + defaults: [ + "framework-module-api-defaults-module_libs_api", + "framework-tethering-stubs-defaults", + ], +} + +droidstubs { + name: "framework-tethering-stubs-srcs-module_libs_api", + defaults: [ + "framework-module-stubs-defaults-module_libs_api", + "framework-tethering-stubs-defaults", + ], +} + +java_library { + name: "framework-tethering-stubs-publicapi", + srcs: [":framework-tethering-stubs-srcs-publicapi"], + sdk_version: "current", +} + +java_library { + name: "framework-tethering-stubs-systemapi", + srcs: [":framework-tethering-stubs-srcs-systemapi"], + sdk_version: "system_current", +} + +java_library { + name: "framework-tethering-stubs-module_libs_api", + srcs: [":framework-tethering-stubs-srcs-module_libs_api"], + sdk_version: "module_current", +} diff --git a/packages/Tethering/common/TetheringLib/api/current.txt b/packages/Tethering/common/TetheringLib/api/current.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/packages/Tethering/common/TetheringLib/api/current.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/packages/Tethering/common/TetheringLib/api/module-lib-current.txt b/packages/Tethering/common/TetheringLib/api/module-lib-current.txt new file mode 100644 index 000000000000..754584e70fad --- /dev/null +++ b/packages/Tethering/common/TetheringLib/api/module-lib-current.txt @@ -0,0 +1,129 @@ +// Signature format: 2.0 +package android.net { + + public final class TetheredClient implements android.os.Parcelable { + ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int); + method public int describeContents(); + method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses(); + method @NonNull public android.net.MacAddress getMacAddress(); + method public int getTetheringType(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR; + } + + public static final class TetheredClient.AddressInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.net.LinkAddress getAddress(); + method @Nullable public String getHostname(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR; + } + + public final class TetheringConstants { + field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType"; + field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback"; + field public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType"; + field public static final String EXTRA_RUN_PROVISION = "extraRunProvision"; + field public static final String EXTRA_SET_ALARM = "extraSetAlarm"; + } + + public class TetheringManager { + ctor public TetheringManager(@NonNull android.content.Context, @NonNull java.util.function.Supplier<android.os.IBinder>); + method public int getLastTetherError(@NonNull String); + method @NonNull public String[] getTetherableBluetoothRegexs(); + method @NonNull public String[] getTetherableIfaces(); + method @NonNull public String[] getTetherableUsbRegexs(); + method @NonNull public String[] getTetherableWifiRegexs(); + method @NonNull public String[] getTetheredIfaces(); + method @NonNull public String[] getTetheringErroredIfaces(); + method public boolean isTetheringSupported(); + method public boolean isTetheringSupported(@NonNull String); + 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 public void requestLatestTetheringEntitlementResult(int, @NonNull android.os.ResultReceiver, boolean); + method @Deprecated public int setUsbTethering(boolean); + 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 @Deprecated public int tether(@NonNull String); + method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback); + method @Deprecated public int untether(@NonNull String); + field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED"; + field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY"; + field public static final String EXTRA_ACTIVE_TETHER = "tetherArray"; + field public static final String EXTRA_AVAILABLE_TETHER = "availableArray"; + field public static final String EXTRA_ERRORED_TETHER = "erroredArray"; + field public static final int TETHERING_BLUETOOTH = 2; // 0x2 + field public static final int TETHERING_ETHERNET = 5; // 0x5 + field public static final int TETHERING_INVALID = -1; // 0xffffffff + field public static final int TETHERING_NCM = 4; // 0x4 + field public static final int TETHERING_USB = 1; // 0x1 + field public static final int TETHERING_WIFI = 0; // 0x0 + field public static final int TETHERING_WIFI_P2P = 3; // 0x3 + field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc + field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9 + field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8 + field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd + field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa + field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5 + field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf + field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe + field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0 + field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb + field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2 + field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6 + field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4 + field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1 + field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10 + field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3 + field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7 + field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2 + field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1 + field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0 + } + + public static interface TetheringManager.OnTetheringEntitlementResultListener { + method public void onTetheringEntitlementResult(int); + } + + public static interface TetheringManager.StartTetheringCallback { + method public default void onTetheringFailed(int); + method public default void onTetheringStarted(); + } + + public static interface TetheringManager.TetheringEventCallback { + method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>); + method public default void onError(@NonNull String, int); + method public default void onOffloadStatusChanged(int); + method public default void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps); + method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheringSupported(boolean); + method public default void onUpstreamChanged(@Nullable android.net.Network); + } + + public static class TetheringManager.TetheringInterfaceRegexps { + method @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs(); + method @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs(); + method @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs(); + } + + public static class TetheringManager.TetheringRequest { + method @Nullable public android.net.LinkAddress getClientStaticIpv4Address(); + method @Nullable public android.net.LinkAddress getLocalIpv4Address(); + method public boolean getShouldShowEntitlementUi(); + method public int getTetheringType(); + method public boolean isExemptFromEntitlementCheck(); + } + + public static class TetheringManager.TetheringRequest.Builder { + ctor public TetheringManager.TetheringRequest.Builder(int); + method @NonNull public android.net.TetheringManager.TetheringRequest build(); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress); + } + +} + diff --git a/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt b/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/packages/Tethering/common/TetheringLib/api/removed.txt b/packages/Tethering/common/TetheringLib/api/removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/packages/Tethering/common/TetheringLib/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/packages/Tethering/common/TetheringLib/api/system-current.txt b/packages/Tethering/common/TetheringLib/api/system-current.txt new file mode 100644 index 000000000000..edd1ebb5f751 --- /dev/null +++ b/packages/Tethering/common/TetheringLib/api/system-current.txt @@ -0,0 +1,99 @@ +// Signature format: 2.0 +package android.net { + + public final class TetheredClient implements android.os.Parcelable { + ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int); + method public int describeContents(); + method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses(); + method @NonNull public android.net.MacAddress getMacAddress(); + method public int getTetheringType(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR; + } + + public static final class TetheredClient.AddressInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.net.LinkAddress getAddress(); + method @Nullable public String getHostname(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR; + } + + public class TetheringManager { + 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 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); + field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED"; + field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY"; + field public static final String EXTRA_ACTIVE_TETHER = "tetherArray"; + field public static final String EXTRA_AVAILABLE_TETHER = "availableArray"; + field public static final String EXTRA_ERRORED_TETHER = "erroredArray"; + field public static final int TETHERING_BLUETOOTH = 2; // 0x2 + field public static final int TETHERING_ETHERNET = 5; // 0x5 + field public static final int TETHERING_INVALID = -1; // 0xffffffff + field public static final int TETHERING_NCM = 4; // 0x4 + field public static final int TETHERING_USB = 1; // 0x1 + field public static final int TETHERING_WIFI = 0; // 0x0 + field public static final int TETHERING_WIFI_P2P = 3; // 0x3 + field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc + field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9 + field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8 + field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd + field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa + field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5 + field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf + field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe + field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0 + field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb + field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2 + field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6 + field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4 + field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1 + field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10 + field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3 + field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7 + field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2 + field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1 + field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0 + } + + public static interface TetheringManager.OnTetheringEntitlementResultListener { + method public void onTetheringEntitlementResult(int); + } + + public static interface TetheringManager.StartTetheringCallback { + method public default void onTetheringFailed(int); + method public default void onTetheringStarted(); + } + + public static interface TetheringManager.TetheringEventCallback { + method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>); + method public default void onError(@NonNull String, int); + method public default void onOffloadStatusChanged(int); + method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>); + method public default void onTetheringSupported(boolean); + method public default void onUpstreamChanged(@Nullable android.net.Network); + } + + public static class TetheringManager.TetheringRequest { + method @Nullable public android.net.LinkAddress getClientStaticIpv4Address(); + method @Nullable public android.net.LinkAddress getLocalIpv4Address(); + method public boolean getShouldShowEntitlementUi(); + method public int getTetheringType(); + method public boolean isExemptFromEntitlementCheck(); + } + + public static class TetheringManager.TetheringRequest.Builder { + ctor public TetheringManager.TetheringRequest.Builder(int); + method @NonNull public android.net.TetheringManager.TetheringRequest build(); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress); + } + +} + diff --git a/packages/Tethering/common/TetheringLib/api/system-removed.txt b/packages/Tethering/common/TetheringLib/api/system-removed.txt new file mode 100644 index 000000000000..d802177e249b --- /dev/null +++ b/packages/Tethering/common/TetheringLib/api/system-removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java index 8b8b9e57a500..48be0d96425c 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java @@ -64,16 +64,26 @@ public final class TetheredClient implements Parcelable { dest.writeInt(mTetheringType); } + /** + * Get the MAC address used to identify the client. + */ @NonNull public MacAddress getMacAddress() { return mMacAddress; } + /** + * Get information on the list of addresses that are associated with the client. + */ @NonNull public List<AddressInfo> getAddresses() { return new ArrayList<>(mAddresses); } + /** + * Get the type of tethering used by the client. + * @return one of the {@code TetheringManager#TETHERING_*} constants. + */ public int getTetheringType() { return mTetheringType; } @@ -115,45 +125,47 @@ public final class TetheredClient implements Parcelable { private final LinkAddress mAddress; @Nullable private final String mHostname; - // TODO: use LinkAddress expiration time once it is supported - private final long mExpirationTime; /** @hide */ public AddressInfo(@NonNull LinkAddress address, @Nullable String hostname) { - this(address, hostname, 0); - } - - /** @hide */ - public AddressInfo(@NonNull LinkAddress address, String hostname, long expirationTime) { this.mAddress = address; this.mHostname = hostname; - this.mExpirationTime = expirationTime; } private AddressInfo(Parcel in) { - this(in.readParcelable(null), in.readString(), in.readLong()); + this(in.readParcelable(null), in.readString()); } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeParcelable(mAddress, flags); dest.writeString(mHostname); - dest.writeLong(mExpirationTime); } + /** + * Get the link address (including prefix length and lifetime) used by the client. + * + * This may be an IPv4 or IPv6 address. + */ @NonNull public LinkAddress getAddress() { return mAddress; } + /** + * Get the hostname that was advertised by the client when obtaining its address, if any. + */ @Nullable public String getHostname() { return mHostname; } - /** @hide TODO: use expiration time in LinkAddress */ + /** + * Get the expiration time of the address assigned to the client. + * @hide + */ public long getExpirationTime() { - return mExpirationTime; + return mAddress.getExpirationTime(); } @Override @@ -163,7 +175,7 @@ public final class TetheredClient implements Parcelable { @Override public int hashCode() { - return Objects.hash(mAddress, mHostname, mExpirationTime); + return Objects.hash(mAddress, mHostname); } @Override @@ -173,8 +185,7 @@ public final class TetheredClient implements Parcelable { // Use .equals() for addresses as all changes, including address expiry changes, // should be included. return other.mAddress.equals(mAddress) - && Objects.equals(mHostname, other.mHostname) - && mExpirationTime == other.mExpirationTime; + && Objects.equals(mHostname, other.mHostname); } @NonNull diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java index a18f5da60cad..fd6f171487a9 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java @@ -32,7 +32,7 @@ import android.os.ResultReceiver; * @hide */ @SystemApi(client = MODULE_LIBRARIES) -public class TetheringConstants { +public final class TetheringConstants { /** An explicit private class to avoid exposing constructor.*/ private TetheringConstants() { } diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java index 5d680b0a60a3..0107a7ef5b59 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java @@ -115,6 +115,19 @@ public class TetheringManager { */ public static final String EXTRA_ERRORED_TETHER = "erroredArray"; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = false, value = { + TETHERING_WIFI, + TETHERING_USB, + TETHERING_BLUETOOTH, + TETHERING_WIFI_P2P, + TETHERING_NCM, + TETHERING_ETHERNET, + }) + public @interface TetheringType { + } + /** * Invalid tethering type. * @see #startTethering. @@ -158,22 +171,60 @@ public class TetheringManager { */ public static final int TETHERING_ETHERNET = 5; - public static final int TETHER_ERROR_NO_ERROR = 0; - public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; - public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; - public static final int TETHER_ERROR_UNSUPPORTED = 3; - public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; - public static final int TETHER_ERROR_MASTER_ERROR = 5; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + TETHER_ERROR_NO_ERROR, + TETHER_ERROR_PROVISIONING_FAILED, + TETHER_ERROR_ENTITLEMENT_UNKNOWN, + }) + public @interface EntitlementResult { + } + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + TETHER_ERROR_NO_ERROR, + TETHER_ERROR_UNKNOWN_IFACE, + TETHER_ERROR_SERVICE_UNAVAIL, + TETHER_ERROR_INTERNAL_ERROR, + TETHER_ERROR_TETHER_IFACE_ERROR, + TETHER_ERROR_ENABLE_FORWARDING_ERROR, + TETHER_ERROR_DISABLE_FORWARDING_ERROR, + TETHER_ERROR_IFACE_CFG_ERROR, + TETHER_ERROR_DHCPSERVER_ERROR, + }) + public @interface TetheringIfaceError { + } + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + TETHER_ERROR_SERVICE_UNAVAIL, + TETHER_ERROR_INTERNAL_ERROR, + TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, + TETHER_ERROR_UNKNOWN_TYPE, + }) + public @interface StartTetheringError { + } + + public static final int TETHER_ERROR_NO_ERROR = 0; + public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; + public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; + public static final int TETHER_ERROR_UNSUPPORTED = 3; + public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; + public static final int TETHER_ERROR_INTERNAL_ERROR = 5; public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; - public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; - public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; - public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; - public static final int TETHER_ERROR_PROVISION_FAILED = 11; - public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; + public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; + public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; + public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; + public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; + public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; + public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -508,23 +559,36 @@ public class TetheringManager { private final TetheringRequestParcel mBuilderParcel; /** Default constructor of Builder. */ - public Builder(final int type) { + public Builder(@TetheringType final int type) { mBuilderParcel = new TetheringRequestParcel(); mBuilderParcel.tetheringType = type; mBuilderParcel.localIPv4Address = null; + mBuilderParcel.staticClientAddress = null; mBuilderParcel.exemptFromEntitlementCheck = false; mBuilderParcel.showProvisioningUi = true; } /** - * Configure tethering with static IPv4 assignment (with DHCP disabled). + * Configure tethering with static IPv4 assignment. + * + * 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 address to use. + * @param localIPv4Address The preferred local IPv4 link address to use. + * @param clientAddress The static client address. */ @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) @NonNull - public Builder useStaticIpv4Addresses(@NonNull final LinkAddress localIPv4Address) { + public Builder setStaticIpv4Addresses(@NonNull final LinkAddress localIPv4Address, + @NonNull final LinkAddress clientAddress) { + Objects.requireNonNull(localIPv4Address); + Objects.requireNonNull(clientAddress); + if (!checkStaticAddressConfiguration(localIPv4Address, clientAddress)) { + throw new IllegalArgumentException("Invalid server or client addresses"); + } + mBuilderParcel.localIPv4Address = localIPv4Address; + mBuilderParcel.staticClientAddress = clientAddress; return this; } @@ -536,11 +600,14 @@ public class TetheringManager { return this; } - /** Start tethering without showing the provisioning UI. */ + /** + * If an entitlement check is needed, sets whether to show the entitlement UI or to + * perform a silent entitlement check. By default, the entitlement UI is shown. + */ @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) @NonNull - public Builder setSilentProvisioning(boolean silent) { - mBuilderParcel.showProvisioningUi = silent; + public Builder setShouldShowEntitlementUi(boolean showUi) { + mBuilderParcel.showProvisioningUi = showUi; return this; } @@ -552,6 +619,53 @@ public class TetheringManager { } /** + * Get the local IPv4 address, if one was configured with + * {@link Builder#setStaticIpv4Addresses}. + */ + @Nullable + public LinkAddress getLocalIpv4Address() { + return mRequestParcel.localIPv4Address; + } + + /** + * Get the static IPv4 address of the client, if one was configured with + * {@link Builder#setStaticIpv4Addresses}. + */ + @Nullable + public LinkAddress getClientStaticIpv4Address() { + return mRequestParcel.staticClientAddress; + } + + /** Get tethering type. */ + @TetheringType + public int getTetheringType() { + return mRequestParcel.tetheringType; + } + + /** Check if exempt from entitlement check. */ + public boolean isExemptFromEntitlementCheck() { + return mRequestParcel.exemptFromEntitlementCheck; + } + + /** Check if show entitlement ui. */ + public boolean getShouldShowEntitlementUi() { + return mRequestParcel.showProvisioningUi; + } + + /** + * 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 */ @@ -563,6 +677,7 @@ public class TetheringManager { public String toString() { return "TetheringRequest [ type= " + mRequestParcel.tetheringType + ", localIPv4Address= " + mRequestParcel.localIPv4Address + + ", staticClientAddress= " + mRequestParcel.staticClientAddress + ", exemptFromEntitlementCheck= " + mRequestParcel.exemptFromEntitlementCheck + ", showProvisioningUi= " + mRequestParcel.showProvisioningUi + " ]"; @@ -572,18 +687,18 @@ public class TetheringManager { /** * Callback for use with {@link #startTethering} to find out whether tethering succeeded. */ - public abstract static class StartTetheringCallback { + public interface StartTetheringCallback { /** * Called when tethering has been successfully started. */ - public void onTetheringStarted() {} + default void onTetheringStarted() {} /** * Called when starting tethering failed. * - * @param resultCode One of the {@code TETHER_ERROR_*} constants. + * @param error The error that caused the failure. */ - public void onTetheringFailed(final int resultCode) {} + default void onTetheringFailed(@StartTetheringError final int error) {} } /** @@ -633,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); @@ -654,7 +771,7 @@ public class TetheringManager { android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS }) - public void stopTethering(final int type) { + public void stopTethering(@TetheringType final int type) { final String callerPkg = mContext.getOpPackageName(); Log.i(TAG, "stopTethering caller:" + callerPkg); @@ -679,10 +796,10 @@ public class TetheringManager { * * @param resultCode an int value of entitlement result. It may be one of * {@link #TETHER_ERROR_NO_ERROR}, - * {@link #TETHER_ERROR_PROVISION_FAILED}, or + * {@link #TETHER_ERROR_PROVISIONING_FAILED}, or * {@link #TETHER_ERROR_ENTITLEMENT_UNKNOWN}. */ - void onTetheringEntitlementResult(int resultCode); + void onTetheringEntitlementResult(@EntitlementResult int result); } /** @@ -697,7 +814,8 @@ public class TetheringManager { * fail if a tethering entitlement check is required. * * @param type the downstream type of tethering. Must be one of {@code #TETHERING_*} constants. - * @param showEntitlementUi a boolean indicating whether to run UI-based entitlement check. + * @param showEntitlementUi a boolean indicating whether to check result for the UI-based + * entitlement check or the silent entitlement check. * @param executor the executor on which callback will be invoked. * @param listener an {@link OnTetheringEntitlementResultListener} which will be called to * notify the caller of the result of entitlement check. The listener may be called zero @@ -707,7 +825,8 @@ public class TetheringManager { android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS }) - public void requestLatestTetheringEntitlementResult(int type, boolean showEntitlementUi, + public void requestLatestTetheringEntitlementResult(@TetheringType int type, + boolean showEntitlementUi, @NonNull Executor executor, @NonNull final OnTetheringEntitlementResultListener listener) { if (listener == null) { @@ -736,7 +855,7 @@ public class TetheringManager { */ // TODO: improve the usage of ResultReceiver, b/145096122 @SystemApi(client = MODULE_LIBRARIES) - public void requestLatestTetheringEntitlementResult(final int type, + public void requestLatestTetheringEntitlementResult(@TetheringType final int type, @NonNull final ResultReceiver receiver, final boolean showEntitlementUi) { final String callerPkg = mContext.getOpPackageName(); Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg); @@ -749,7 +868,7 @@ public class TetheringManager { * Callback for use with {@link registerTetheringEventCallback} to find out tethering * upstream status. */ - public abstract static class TetheringEventCallback { + public interface TetheringEventCallback { /** * Called when tethering supported status changed. * @@ -761,7 +880,7 @@ public class TetheringManager { * * @param supported The new supported status */ - public void onTetheringSupported(boolean supported) {} + default void onTetheringSupported(boolean supported) {} /** * Called when tethering upstream changed. @@ -772,7 +891,7 @@ public class TetheringManager { * @param network the {@link Network} of tethering upstream. Null means tethering doesn't * have any upstream. */ - public void onUpstreamChanged(@Nullable Network network) {} + default void onUpstreamChanged(@Nullable Network network) {} /** * Called when there was a change in tethering interface regular expressions. @@ -780,28 +899,30 @@ public class TetheringManager { * <p>This will be called immediately after the callback is registered, and may be called * multiple times later upon changes. * @param reg The new regular expressions. - * @deprecated Referencing interfaces by regular expressions is a deprecated mechanism. + * + * @hide */ - @Deprecated - public void onTetherableInterfaceRegexpsChanged(@NonNull TetheringInterfaceRegexps reg) {} + @SystemApi(client = MODULE_LIBRARIES) + default void onTetherableInterfaceRegexpsChanged(@NonNull TetheringInterfaceRegexps reg) {} /** - * Called when there was a change in the list of tetherable interfaces. + * Called when there was a change in the list of tetherable interfaces. Tetherable + * interface means this interface is available and can be used for tethering. * * <p>This will be called immediately after the callback is registered, and may be called * multiple times later upon changes. - * @param interfaces The list of tetherable interfaces. + * @param interfaces The list of tetherable interface names. */ - public void onTetherableInterfacesChanged(@NonNull List<String> interfaces) {} + default void onTetherableInterfacesChanged(@NonNull List<String> interfaces) {} /** * Called when there was a change in the list of tethered interfaces. * * <p>This will be called immediately after the callback is registered, and may be called * multiple times later upon changes. - * @param interfaces The list of tethered interfaces. + * @param interfaces The list of 0 or more String of currently tethered interface names. */ - public void onTetheredInterfacesChanged(@NonNull List<String> interfaces) {} + default void onTetheredInterfacesChanged(@NonNull List<String> interfaces) {} /** * Called when an error occurred configuring tethering. @@ -811,7 +932,7 @@ public class TetheringManager { * @param ifName Name of the interface. * @param error One of {@code TetheringManager#TETHER_ERROR_*}. */ - public void onError(@NonNull String ifName, int error) {} + default void onError(@NonNull String ifName, @TetheringIfaceError int error) {} /** * Called when the list of tethered clients changes. @@ -824,7 +945,7 @@ public class TetheringManager { * determine if they are still connected. * @param clients The new set of tethered clients; the collection is not ordered. */ - public void onClientsChanged(@NonNull Collection<TetheredClient> clients) {} + default void onClientsChanged(@NonNull Collection<TetheredClient> clients) {} /** * Called when tethering offload status changes. @@ -832,19 +953,20 @@ public class TetheringManager { * <p>This will be called immediately after the callback is registered. * @param status The offload status. */ - public void onOffloadStatusChanged(@TetherOffloadStatus int status) {} + default void onOffloadStatusChanged(@TetherOffloadStatus int status) {} } /** * Regular expressions used to identify tethering interfaces. - * @deprecated Referencing interfaces by regular expressions is a deprecated mechanism. + * @hide */ - @Deprecated + @SystemApi(client = MODULE_LIBRARIES) public static class TetheringInterfaceRegexps { private final String[] mTetherableBluetoothRegexs; private final String[] mTetherableUsbRegexs; private final String[] mTetherableWifiRegexs; + /** @hide */ public TetheringInterfaceRegexps(@NonNull String[] tetherableBluetoothRegexs, @NonNull String[] tetherableUsbRegexs, @NonNull String[] tetherableWifiRegexs) { mTetherableBluetoothRegexs = tetherableBluetoothRegexs.clone(); diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl b/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl index bf19d85f6a83..c0280d3dbfaf 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl @@ -25,6 +25,7 @@ import android.net.LinkAddress; parcelable TetheringRequestParcel { int tetheringType; LinkAddress localIPv4Address; + LinkAddress staticClientAddress; boolean exemptFromEntitlementCheck; boolean showProvisioningUi; } diff --git a/packages/Tethering/res/values-af/strings.xml b/packages/Tethering/res/values-af/strings.xml index 1258805378ea..f06d1a208fd8 100644 --- a/packages/Tethering/res/values-af/strings.xml +++ b/packages/Tethering/res/values-af/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Verbinding of Wi-Fi-warmkol aktief"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om op te stel."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Verbinding is gedeaktiveer"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontak jou administrateur vir besonderhede"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Verbinding of warmkol is aktief"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tik om op te stel."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Verbinding is gedeaktiveer"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontak jou administrateur vir besonderhede"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Warmkol- en verbindingstatus"</string> </resources> diff --git a/packages/Tethering/res/values-am/strings.xml b/packages/Tethering/res/values-am/strings.xml index 9c36192257c0..aa0e6934492f 100644 --- a/packages/Tethering/res/values-am/strings.xml +++ b/packages/Tethering/res/values-am/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"መሰካት ወይም ገባሪ ድረስ ነጥብ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ለማዋቀር መታ ያድርጉ።"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"እንደ ሞደም መሰካት ተሰናክሏል"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"እንደ ሞደም መሰካት ወይም መገናኛ ነጥብ ገባሪ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ለማዋቀር መታ ያድርጉ።"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"እንደ ሞደም መሰካት ተሰናክሏል"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"መገናኛ ነጥብ እና እንደ ሞደም የመሰካት ሁኔታ"</string> </resources> diff --git a/packages/Tethering/res/values-ar/strings.xml b/packages/Tethering/res/values-ar/strings.xml index 9f84ce4090c6..ce7372085b9d 100644 --- a/packages/Tethering/res/values-ar/strings.xml +++ b/packages/Tethering/res/values-ar/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"النطاق أو نقطة الاتصال نشطة"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"انقر للإعداد."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"تم إيقاف التوصيل"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"اتصل بالمشرف للحصول على التفاصيل"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"النطاق نشط أو نقطة الاتصال نشطة"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"انقر للإعداد."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"التوصيل متوقف."</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"تواصَل مع المشرف للحصول على التفاصيل."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"حالة نقطة الاتصال والتوصيل"</string> </resources> diff --git a/packages/Tethering/res/values-as/strings.xml b/packages/Tethering/res/values-as/strings.xml deleted file mode 100644 index 8855822e7c8b..000000000000 --- a/packages/Tethering/res/values-as/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"টেডাৰিং বা হটস্প\'ট সক্ৰিয় অৱস্থাত আছে"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ছেট আপ কৰিবলৈ টিপক।"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"টেডাৰিং অক্ষম কৰি থোৱা হৈছে"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"সবিশেষ জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক"</string> -</resources> diff --git a/packages/Tethering/res/values-az/strings.xml b/packages/Tethering/res/values-az/strings.xml index eba50eb636c1..82661f48e86f 100644 --- a/packages/Tethering/res/values-az/strings.xml +++ b/packages/Tethering/res/values-az/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tezerinq və ya hotspot aktivdir"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Quraşdırmaq üçün tıklayın."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Birləşmə deaktivdir"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Məlumat üçün adminlə əlaqə saxlayın"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Birləşmə və ya hotspot aktivdir"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamaq üçün toxunun."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Birləşmə deaktivdir"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Detallar üçün adminlə əlaqə saxlayın"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot & birləşmə statusu"</string> </resources> diff --git a/packages/Tethering/res/values-b+sr+Latn/strings.xml b/packages/Tethering/res/values-b+sr+Latn/strings.xml index 5b0e488ba5e6..0f1fb9e1590d 100644 --- a/packages/Tethering/res/values-b+sr+Latn/strings.xml +++ b/packages/Tethering/res/values-b+sr+Latn/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivno povezivanje sa internetom preko mobilnog uređaja ili hotspot"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste podesili."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Privezivanje je onemogućeno"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Potražite detalje od administratora"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Privezivanje ili hotspot je aktivan"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste podesili."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Privezivanje je onemogućeno"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Potražite detalje od administratora"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspota i privezivanja"</string> </resources> diff --git a/packages/Tethering/res/values-be/strings.xml b/packages/Tethering/res/values-be/strings.xml index 5966c7155ecd..31c6957a3c12 100644 --- a/packages/Tethering/res/values-be/strings.xml +++ b/packages/Tethering/res/values-be/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"USB-мадэм або хот-спот Wi-Fi актыўныя"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Дакраніцеся, каб наладзіць."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Рэжым мадэма адключаны"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Мадэм або хот-спот актыўныя"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Дакраніцеся, каб наладзіць."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Рэжым мадэма выключаны"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Стан \"Хот-спот і мадэм\""</string> </resources> diff --git a/packages/Tethering/res/values-bg/strings.xml b/packages/Tethering/res/values-bg/strings.xml index ed58d7311aca..22d03202f5c0 100644 --- a/packages/Tethering/res/values-bg/strings.xml +++ b/packages/Tethering/res/values-bg/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Има активна споделена връзка или безжична точка за достъп"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Докоснете, за да настроите."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Функцията за тетъринг е деактивирана"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Свържете се с администратора си за подробности"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Има активна споделена връзка или точка за достъп"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Докоснете, за да настроите."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Функцията за тетъринг е деактивирана"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Свържете се с администратора си за подробности"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Състояние на функцията за точка за достъп и тетъринг"</string> </resources> diff --git a/packages/Tethering/res/values-bn/strings.xml b/packages/Tethering/res/values-bn/strings.xml deleted file mode 100644 index 8d9880aa9aca..000000000000 --- a/packages/Tethering/res/values-bn/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"টিথারিং বা হটস্পট সক্রিয় আছে"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"সেট-আপ করার জন্য আলতো চাপুন৷"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"টিথারিং অক্ষম করা আছে"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"বিশদ বিবরণের জন্য প্রশাসকের সাথে যোগাযোগ করুন"</string> -</resources> diff --git a/packages/Tethering/res/values-bs/strings.xml b/packages/Tethering/res/values-bs/strings.xml index 2361b9dd382c..f22180d4d7b0 100644 --- a/packages/Tethering/res/values-bs/strings.xml +++ b/packages/Tethering/res/values-bs/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Uređaj dijeli vezu ili djeluje kao pristupna tačka"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite za postavke"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezivanje putem mobitela je onemogućeno"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontaktirajte svog administratora za dodatne detalje"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Aktivno je povezivanje putem mobitela ili pristupna tačka"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da postavite."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezivanje putem mobitela je onemogućeno"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontaktirajte svog administratora za detalje"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status pristupne tačke i povezivanja putem mobitela"</string> </resources> diff --git a/packages/Tethering/res/values-ca/strings.xml b/packages/Tethering/res/values-ca/strings.xml index 6752b519e218..a91a9b4fbc7c 100644 --- a/packages/Tethering/res/values-ca/strings.xml +++ b/packages/Tethering/res/values-ca/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Compartició de xarxa o punt d\'accés Wi-Fi activat"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toca per configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"La compartició de xarxa està desactivada"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta amb el teu administrador per obtenir més informació"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Compartició de xarxa o punt d\'accés Wi‑Fi activat"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toca per configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"La compartició de xarxa està desactivada"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta amb el teu administrador per obtenir més informació"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estat del punt d\'accés Wi‑Fi i de la compartició de xarxa"</string> </resources> diff --git a/packages/Tethering/res/values-cs/strings.xml b/packages/Tethering/res/values-cs/strings.xml index 5fdd53adf15c..4a8ce53b4c4f 100644 --- a/packages/Tethering/res/values-cs/strings.xml +++ b/packages/Tethering/res/values-cs/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Sdílené připojení nebo hotspot je aktivní."</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím zahájíte nastavení."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je zakázán"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požádejte administrátora"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering nebo hotspot je aktivní"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím zahájíte nastavení."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je zakázán"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požádejte administrátora"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string> </resources> diff --git a/packages/Tethering/res/values-da/strings.xml b/packages/Tethering/res/values-da/strings.xml index 2775dfa551cb..1fe048bf58c0 100644 --- a/packages/Tethering/res/values-da/strings.xml +++ b/packages/Tethering/res/values-da/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Netdeling eller hotspot er aktivt"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tryk for at konfigurere"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Netdeling er deaktiveret"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakt din administrator for at få oplysninger"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Netdeling eller hotspot er aktivt"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tryk for at konfigurere."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Netdeling er deaktiveret"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakt din administrator for at få oplysninger"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for hotspot og netdeling"</string> </resources> diff --git a/packages/Tethering/res/values-de/strings.xml b/packages/Tethering/res/values-de/strings.xml deleted file mode 100644 index 9046cd5e1144..000000000000 --- a/packages/Tethering/res/values-de/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oder Hotspot aktiv"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Zum Einrichten tippen."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering ist deaktiviert"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Bitte wende dich für weitere Informationen an den Administrator"</string> -</resources> diff --git a/packages/Tethering/res/values-el/strings.xml b/packages/Tethering/res/values-el/strings.xml index 3b9f53733b8a..045d707e82cd 100644 --- a/packages/Tethering/res/values-el/strings.xml +++ b/packages/Tethering/res/values-el/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Πατήστε για ρύθμιση."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Η σύνδεση είναι απενεργοποιημένη"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Πατήστε για ρύθμιση."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Η σύνδεση είναι απενεργοποιημένη"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Κατάσταση σημείου πρόσβασης Wi-Fi και σύνδεσης"</string> </resources> diff --git a/packages/Tethering/res/values-en-rAU/strings.xml b/packages/Tethering/res/values-en-rAU/strings.xml index 56b88a5fb3e1..14bf2aa88fa5 100644 --- a/packages/Tethering/res/values-en-rAU/strings.xml +++ b/packages/Tethering/res/values-en-rAU/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string> </resources> diff --git a/packages/Tethering/res/values-en-rCA/strings.xml b/packages/Tethering/res/values-en-rCA/strings.xml index 56b88a5fb3e1..14bf2aa88fa5 100644 --- a/packages/Tethering/res/values-en-rCA/strings.xml +++ b/packages/Tethering/res/values-en-rCA/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string> </resources> diff --git a/packages/Tethering/res/values-en-rGB/strings.xml b/packages/Tethering/res/values-en-rGB/strings.xml index 56b88a5fb3e1..14bf2aa88fa5 100644 --- a/packages/Tethering/res/values-en-rGB/strings.xml +++ b/packages/Tethering/res/values-en-rGB/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string> </resources> diff --git a/packages/Tethering/res/values-en-rIN/strings.xml b/packages/Tethering/res/values-en-rIN/strings.xml index 56b88a5fb3e1..14bf2aa88fa5 100644 --- a/packages/Tethering/res/values-en-rIN/strings.xml +++ b/packages/Tethering/res/values-en-rIN/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string> </resources> diff --git a/packages/Tethering/res/values-en-rXC/strings.xml b/packages/Tethering/res/values-en-rXC/strings.xml index 7f47fc89d2af..43f504c244a3 100644 --- a/packages/Tethering/res/values-en-rXC/strings.xml +++ b/packages/Tethering/res/values-en-rXC/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot & tethering status"</string> </resources> diff --git a/packages/Tethering/res/values-es-rUS/strings.xml b/packages/Tethering/res/values-es-rUS/strings.xml index e4618b8cec96..8706a93e674a 100644 --- a/packages/Tethering/res/values-es-rUS/strings.xml +++ b/packages/Tethering/res/values-es-rUS/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Anclaje a red o zona activa conectados"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Presiona para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Se inhabilitó la conexión mediante dispositivo portátil"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Para obtener más información, comunícate con el administrador"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Anclaje a red o zona activa conectados"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Presiona para configurar esta opción."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Se inhabilitó la conexión mediante dispositivo portátil"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Para obtener más información, comunícate con el administrador"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del hotspot y la conexión mediante dispositivo portátil"</string> </resources> diff --git a/packages/Tethering/res/values-es/strings.xml b/packages/Tethering/res/values-es/strings.xml index 8dc1575ce8ea..67f8f2eb3dcc 100644 --- a/packages/Tethering/res/values-es/strings.xml +++ b/packages/Tethering/res/values-es/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Compartir conexión/Zona Wi-Fi activada"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toca para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"La conexión compartida está inhabilitada"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ponte en contacto con el administrador para obtener más información"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida o punto de acceso activos"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"La conexión compartida está inhabilitada"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Solicita más información a tu administrador"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del punto de acceso y de la conexión compartida"</string> </resources> diff --git a/packages/Tethering/res/values-et/strings.xml b/packages/Tethering/res/values-et/strings.xml index 872c8a74cc59..1ebf7b124d05 100644 --- a/packages/Tethering/res/values-et/strings.xml +++ b/packages/Tethering/res/values-et/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või kuumkoht on aktiivne"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Puudutage seadistamiseks."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Jagamine on keelatud"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Jagamine või kuumkoht on aktiivne"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Puudutage seadistamiseks."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Jagamine on keelatud"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Kuumkoha ja jagamise olek"</string> </resources> diff --git a/packages/Tethering/res/values-eu/strings.xml b/packages/Tethering/res/values-eu/strings.xml index 6c4605e616c1..8e39d4789e2c 100644 --- a/packages/Tethering/res/values-eu/strings.xml +++ b/packages/Tethering/res/values-eu/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Konexioa partekatzea edo sare publikoa aktibo"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Sakatu konfiguratzeko."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Desgaituta dago konexioa partekatzeko aukera"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Konexioa partekatzea edo sare publikoa aktibo"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Sakatu konfiguratzeko."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Desgaituta dago konexioa partekatzeko aukera"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Sare publikoaren eta konexioa partekatzeko eginbidearen egoera"</string> </resources> diff --git a/packages/Tethering/res/values-fa/strings.xml b/packages/Tethering/res/values-fa/strings.xml index bc2ee23609c3..ee722ffbe784 100644 --- a/packages/Tethering/res/values-fa/strings.xml +++ b/packages/Tethering/res/values-fa/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"اشتراکگذاری اینترنت یا نقطه اتصال فعال"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"برای راهاندازی ضربه بزنید."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"اشتراکگذاری اینترنت غیرفعال است"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"برای جزئیات، با سرپرستتان تماس بگیرید"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"اشتراکگذاری اینترنت یا نقطه اتصال فعال"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"برای راهاندازی ضربه بزنید."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"اشتراکگذاری اینترنت غیرفعال است"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"برای جزئیات، با سرپرستتان تماس بگیرید"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"وضعیت نقطه اتصال و اشتراکگذاری اینترنت"</string> </resources> diff --git a/packages/Tethering/res/values-fi/strings.xml b/packages/Tethering/res/values-fi/strings.xml index ff0fca6502df..fae2e8e9a217 100644 --- a/packages/Tethering/res/values-fi/strings.xml +++ b/packages/Tethering/res/values-fi/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Internetin jakaminen tai yhteyspiste käytössä"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Määritä napauttamalla."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Yhteyden jakaminen poistettu käytöstä"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kysy lisätietoja järjestelmänvalvojalta."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Yhteyden jakaminen tai hotspot käytössä"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ota käyttöön napauttamalla."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Yhteyden jakaminen on poistettu käytöstä"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pyydä lisätietoja järjestelmänvalvojalta"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspotin ja yhteyden jakamisen tila"</string> </resources> diff --git a/packages/Tethering/res/values-fr-rCA/strings.xml b/packages/Tethering/res/values-fr-rCA/strings.xml index 1f5df0ee0cb0..afe5df8c5b3a 100644 --- a/packages/Tethering/res/values-fr-rCA/strings.xml +++ b/packages/Tethering/res/values-fr-rCA/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Touchez pour configurer."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Communiquez avec votre administrateur pour obtenir plus de détails"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès sans fil activé"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Touchez pour configurer."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Communiquez avec votre administrateur pour obtenir plus de détails"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Point d\'accès et partage de connexion"</string> </resources> diff --git a/packages/Tethering/res/values-fr/strings.xml b/packages/Tethering/res/values-fr/strings.xml index daf7c9d830d5..4d54be124bb1 100644 --- a/packages/Tethering/res/values-fr/strings.xml +++ b/packages/Tethering/res/values-fr/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Appuyez ici pour configurer."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Pour en savoir plus, contactez votre administrateur"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès activé"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Appuyez pour effectuer la configuration."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pour en savoir plus, contactez votre administrateur"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"État du point d\'accès et du partage de connexion"</string> </resources> diff --git a/packages/Tethering/res/values-gl/strings.xml b/packages/Tethering/res/values-gl/strings.xml index 0d16a1de094f..8f803e9cda88 100644 --- a/packages/Tethering/res/values-gl/strings.xml +++ b/packages/Tethering/res/values-gl/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Conexión compartida ou zona wifi activada"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tocar para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"A conexión compartida está desactivada"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta co administrador para obter información"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida ou zona wifi activada"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"A conexión compartida está desactivada"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta co administrador para obter información"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona wifi e da conexión compartida"</string> </resources> diff --git a/packages/Tethering/res/values-gu/strings.xml b/packages/Tethering/res/values-gu/strings.xml deleted file mode 100644 index 9d6b02f85fc9..000000000000 --- a/packages/Tethering/res/values-gu/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ટિથરિંગ અથવા હૉટસ્પૉટ સક્રિય"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"સેટ કરવા માટે ટૅપ કરો."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ટિથરિંગ અક્ષમ કરેલ છે"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string> -</resources> diff --git a/packages/Tethering/res/values-hi/strings.xml b/packages/Tethering/res/values-hi/strings.xml deleted file mode 100644 index 9c29d9a8f9a1..000000000000 --- a/packages/Tethering/res/values-hi/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग या हॉटस्पॉट सक्रिय"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करने के लिए टैप करें."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग अक्षम है"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string> -</resources> diff --git a/packages/Tethering/res/values-hr/strings.xml b/packages/Tethering/res/values-hr/strings.xml index d0d25bb755aa..9727bc9dc4a3 100644 --- a/packages/Tethering/res/values-hr/strings.xml +++ b/packages/Tethering/res/values-hr/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ograničenje ili aktivan hotspot"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste postavili."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modemsko je povezivanje onemogućeno"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Obratite se administratoru da biste saznali pojedinosti"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Modemsko povezivanje ili žarišna točka aktivni"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste postavili."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modemsko je povezivanje onemogućeno"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Obratite se administratoru da biste saznali pojedinosti"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status žarišne točke i modemskog povezivanja"</string> </resources> diff --git a/packages/Tethering/res/values-hu/strings.xml b/packages/Tethering/res/values-hu/strings.xml index 31296599231e..ce4ccbec6c1f 100644 --- a/packages/Tethering/res/values-hu/strings.xml +++ b/packages/Tethering/res/values-hu/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Megosztás vagy aktív hotspot"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Koppintson a beállításhoz."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Az internetmegosztás le van tiltva"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"A részletekért forduljon rendszergazdájához"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Megosztás vagy aktív hotspot"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Koppintson a beállításhoz."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Az internetmegosztás le van tiltva"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"A részletekért forduljon rendszergazdájához"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot és internetmegosztás állapota"</string> </resources> diff --git a/packages/Tethering/res/values-hy/strings.xml b/packages/Tethering/res/values-hy/strings.xml index 8ba6435fd58e..b4a68483af78 100644 --- a/packages/Tethering/res/values-hy/strings.xml +++ b/packages/Tethering/res/values-hy/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Մոդեմի ռեժիմը միացված է"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Հպեք՝ կարգավորելու համար:"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Մոդեմի ռեժիմն անջատված է"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Մոդեմի ռեժիմը միացված է"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Հպեք՝ կարգավորելու համար։"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Մոդեմի ռեժիմն անջատված է"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Թեժ կետի և մոդեմի ռեժիմի կարգավիճակը"</string> </resources> diff --git a/packages/Tethering/res/values-in/strings.xml b/packages/Tethering/res/values-in/strings.xml index 1e093ab237e8..6f33685eb912 100644 --- a/packages/Tethering/res/values-in/strings.xml +++ b/packages/Tethering/res/values-in/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering (Penambatan) atau hotspot aktif"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Ketuk untuk menyiapkan."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering dinonaktifkan"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi admin untuk mengetahui detailnya"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering atau hotspot aktif"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ketuk untuk menyiapkan."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering dinonaktifkan"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi admin untuk mengetahui detailnya"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspot & tethering"</string> </resources> diff --git a/packages/Tethering/res/values-is/strings.xml b/packages/Tethering/res/values-is/strings.xml index f5769d5344ae..c149818a56c0 100644 --- a/packages/Tethering/res/values-is/strings.xml +++ b/packages/Tethering/res/values-is/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Kveikt á tjóðrun eða aðgangsstað"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Ýttu til að setja upp."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Slökkt er á tjóðrun"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Kveikt á tjóðrun eða aðgangsstað"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ýttu til að setja upp."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Slökkt er á tjóðrun"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Staða heits reits og tjóðrunar"</string> </resources> diff --git a/packages/Tethering/res/values-it/strings.xml b/packages/Tethering/res/values-it/strings.xml index e0b3724325fc..09d0c92ce6a5 100644 --- a/packages/Tethering/res/values-it/strings.xml +++ b/packages/Tethering/res/values-it/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oppure hotspot attivo"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tocca per impostare."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering disattivato"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contatta il tuo amministratore per avere informazioni dettagliate"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Hotspot o tethering attivo"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tocca per impostare."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering disattivato"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contatta il tuo amministratore per avere informazioni dettagliate"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stato hotspot e tethering"</string> </resources> diff --git a/packages/Tethering/res/values-iw/strings.xml b/packages/Tethering/res/values-iw/strings.xml index c002c44b2361..101fb514b4cb 100644 --- a/packages/Tethering/res/values-iw/strings.xml +++ b/packages/Tethering/res/values-iw/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"שיתוף אינטרנט פעיל"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"הקש כדי להגדיר."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"שיתוף האינטרנט בין ניידים מושבת"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"לפרטים, יש לפנות למנהל המערכת"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"נקודה לשיתוף אינטרנט או שיתוף אינטרנט בין מכשירים: בסטטוס פעיל"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"יש להקיש כדי להגדיר."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"שיתוף האינטרנט בין מכשירים מושבת"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"לפרטים, יש לפנות למנהל המערכת"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"סטטוס של נקודה לשיתוף אינטרנט ושיתוף אינטרנט בין מכשירים"</string> </resources> diff --git a/packages/Tethering/res/values-ja/strings.xml b/packages/Tethering/res/values-ja/strings.xml index 314bde00df02..214780dfa4ce 100644 --- a/packages/Tethering/res/values-ja/strings.xml +++ b/packages/Tethering/res/values-ja/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"タップしてセットアップします。"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"テザリングは無効に設定されています"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳しくは、管理者にお問い合わせください"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"テザリングまたはアクセス ポイントが有効です"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"タップしてセットアップします。"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"テザリングは無効に設定されています"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳しくは、管理者にお問い合わせください"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"アクセス ポイントとテザリングのステータス"</string> </resources> diff --git a/packages/Tethering/res/values-ka/strings.xml b/packages/Tethering/res/values-ka/strings.xml index 7bbd81d3435a..68dcecc174ad 100644 --- a/packages/Tethering/res/values-ka/strings.xml +++ b/packages/Tethering/res/values-ka/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"შეეხეთ დასაყენებლად."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ტეტერინგი გათიშულია"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"შეეხეთ დასაყენებლად."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ტეტერინგი გათიშულია"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"უსადენო ქსელის და ტეტერინგის სტატუსი"</string> </resources> diff --git a/packages/Tethering/res/values-kk/strings.xml b/packages/Tethering/res/values-kk/strings.xml index 7fd87a159657..39de1665456b 100644 --- a/packages/Tethering/res/values-kk/strings.xml +++ b/packages/Tethering/res/values-kk/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Тетеринг немесе хотспот қосулы"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Реттеу үшін түртіңіз."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Тетеринг өшірілді"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Мәліметтерді әкімшіден алыңыз"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Тетеринг немесе хотспот қосулы"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Реттеу үшін түртіңіз."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Тетеринг өшірілді."</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Мәліметтерді әкімшіден алыңыз."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Хотспот және тетеринг күйі"</string> </resources> diff --git a/packages/Tethering/res/values-km/strings.xml b/packages/Tethering/res/values-km/strings.xml index 2f852246790c..be0f0aa69e0f 100644 --- a/packages/Tethering/res/values-km/strings.xml +++ b/packages/Tethering/res/values-km/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬហតស្ពតសកម្ម"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ប៉ះដើម្បីកំណត់"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ការភ្ជាប់ត្រូវបានបិទ"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ទាក់ទងអ្នកគ្រប់គ្រងរបស់អ្នកសម្រាប់ព័ត៌មានលម្អិត"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ការភ្ជាប់ ឬហតស្ប៉តកំពុងដំណើរការ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ចុចដើម្បីរៀបចំ។"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ការភ្ជាប់ត្រូវបានបិទ"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ទាក់ទងអ្នកគ្រប់គ្រងរបស់អ្នក ដើម្បីទទួលបានព័ត៌មានលម្អិត"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ស្ថានភាពការភ្ជាប់ និងហតស្ប៉ត"</string> </resources> diff --git a/packages/Tethering/res/values-kn/strings.xml b/packages/Tethering/res/values-kn/strings.xml deleted file mode 100644 index f11a83ea40ee..000000000000 --- a/packages/Tethering/res/values-kn/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string> -</resources> diff --git a/packages/Tethering/res/values-ko/strings.xml b/packages/Tethering/res/values-ko/strings.xml index 57f24f5b1ae2..7ce45a24ef89 100644 --- a/packages/Tethering/res/values-ko/strings.xml +++ b/packages/Tethering/res/values-ko/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"테더링 또는 핫스팟 사용"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"설정하려면 탭하세요."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"테더링이 사용 중지됨"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"자세한 정보는 관리자에게 문의하세요."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"테더링 또는 핫스팟 사용"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"설정하려면 탭하세요."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"테더링이 사용 중지됨"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"자세한 정보는 관리자에게 문의하세요."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"핫스팟 및 테더링 상태"</string> </resources> diff --git a/packages/Tethering/res/values-ky/strings.xml b/packages/Tethering/res/values-ky/strings.xml index 79854859d41e..9a5088e44edc 100644 --- a/packages/Tethering/res/values-ky/strings.xml +++ b/packages/Tethering/res/values-ky/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Жалгаштыруу же хотспот жандырылган"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Жөндөө үчүн таптап коюңуз."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Жалгаштыруу функциясы өчүрүлгөн"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Жалгаштыруу же хотспот жандырылган"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Жөндөө үчүн таптап коюңуз."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Жалгаштыруу функциясы өчүрүлгөн"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Хотспот жана байланыш түйүнүүн статусу"</string> </resources> diff --git a/packages/Tethering/res/values-lo/strings.xml b/packages/Tethering/res/values-lo/strings.xml index 78f1585f60f7..738423735624 100644 --- a/packages/Tethering/res/values-lo/strings.xml +++ b/packages/Tethering/res/values-lo/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ເປີດການປ່ອຍສັນຍານ ຫຼືຮັອດສະປອດແລ້ວ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ແຕະເພື່ອຕັ້ງຄ່າ."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ເປີດການປ່ອຍສັນຍານ ຫຼື ຮັອດສະປອດແລ້ວ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"ແຕະເພື່ອຕັ້ງຄ່າ."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ສະຖານະຮັອດສະປອດ ແລະ ການປ່ອຍສັນຍານ"</string> </resources> diff --git a/packages/Tethering/res/values-lt/strings.xml b/packages/Tethering/res/values-lt/strings.xml index ebff8ac9d1f1..dc4fdf592d7b 100644 --- a/packages/Tethering/res/values-lt/strings.xml +++ b/packages/Tethering/res/values-lt/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Susietas ar aktyvus"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Palieskite, kad nustatytumėte."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Įrenginio kaip modemo naudojimas išjungtas"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Įrenginys naudojamas kaip modemas arba įjungtas viešosios interneto prieigos taškas"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Palieskite, kad nustatytumėte."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Įrenginio kaip modemo naudojimas išjungtas"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Viešosios interneto prieigos taško ir įrenginio kaip modemo naudojimo būsena"</string> </resources> diff --git a/packages/Tethering/res/values-lv/strings.xml b/packages/Tethering/res/values-lv/strings.xml index 54d0048b526a..db0401aa429a 100644 --- a/packages/Tethering/res/values-lv/strings.xml +++ b/packages/Tethering/res/values-lv/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Piesaiste vai tīklājs ir aktīvs."</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Pieskarieties, lai iestatītu."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Piesaiste ir atspējota"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Piesaiste vai tīklājs ir aktīvs."</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Pieskarieties, lai to iestatītu."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Piesaiste ir atspējota"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Tīklāja un piesaistes statuss"</string> </resources> diff --git a/packages/Tethering/res/values-mcc204-mnc04/strings.xml b/packages/Tethering/res/values-mcc204-mnc04/strings.xml new file mode 100644 index 000000000000..a996b4247a0e --- /dev/null +++ b/packages/Tethering/res/values-mcc204-mnc04/strings.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <!-- String for no upstream notification title [CHAR LIMIT=200] --> + <string name="no_upstream_notification_title">Hotspot has no internet</string> + <!-- String for no upstream notification title [CHAR LIMIT=200] --> + <string name="no_upstream_notification_message">Devices can\u2019t connect to internet</string> + <!-- String for cellular roaming notification disable button [CHAR LIMIT=200] --> + <string name="no_upstream_notification_disable_button">Turn off hotspot</string> + + <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_title">Hotspot is on</string> + <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> + <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string> + <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_continue_button">Continue</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004/strings.xml b/packages/Tethering/res/values-mcc310-mnc004/strings.xml new file mode 100644 index 000000000000..a996b4247a0e --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004/strings.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <!-- String for no upstream notification title [CHAR LIMIT=200] --> + <string name="no_upstream_notification_title">Hotspot has no internet</string> + <!-- String for no upstream notification title [CHAR LIMIT=200] --> + <string name="no_upstream_notification_message">Devices can\u2019t connect to internet</string> + <!-- String for cellular roaming notification disable button [CHAR LIMIT=200] --> + <string name="no_upstream_notification_disable_button">Turn off hotspot</string> + + <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_title">Hotspot is on</string> + <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> + <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string> + <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_continue_button">Continue</string> +</resources> diff --git a/packages/Tethering/res/values-mcc310-mnc120/strings.xml b/packages/Tethering/res/values-mcc310-mnc120/strings.xml new file mode 100644 index 000000000000..618df90c7105 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc120/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- String for tethered notification title with client number info. --> + <plurals name="tethered_notification_title_with_client_number"> + <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item> + <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item> + </plurals> +</resources>
\ No newline at end of file diff --git a/packages/Tethering/res/values-mcc311-mnc480/strings.xml b/packages/Tethering/res/values-mcc311-mnc480/strings.xml new file mode 100644 index 000000000000..a996b4247a0e --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480/strings.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <!-- String for no upstream notification title [CHAR LIMIT=200] --> + <string name="no_upstream_notification_title">Hotspot has no internet</string> + <!-- String for no upstream notification title [CHAR LIMIT=200] --> + <string name="no_upstream_notification_message">Devices can\u2019t connect to internet</string> + <!-- String for cellular roaming notification disable button [CHAR LIMIT=200] --> + <string name="no_upstream_notification_disable_button">Turn off hotspot</string> + + <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_title">Hotspot is on</string> + <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> + <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string> + <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_continue_button">Continue</string> +</resources> diff --git a/packages/Tethering/res/values-mcc311-mnc490/strings.xml b/packages/Tethering/res/values-mcc311-mnc490/strings.xml new file mode 100644 index 000000000000..618df90c7105 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc490/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- String for tethered notification title with client number info. --> + <plurals name="tethered_notification_title_with_client_number"> + <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item> + <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item> + </plurals> +</resources>
\ No newline at end of file diff --git a/packages/Tethering/res/values-mcc312-mnc530/strings.xml b/packages/Tethering/res/values-mcc312-mnc530/strings.xml new file mode 100644 index 000000000000..618df90c7105 --- /dev/null +++ b/packages/Tethering/res/values-mcc312-mnc530/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- String for tethered notification title with client number info. --> + <plurals name="tethered_notification_title_with_client_number"> + <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item> + <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item> + </plurals> +</resources>
\ No newline at end of file diff --git a/packages/Tethering/res/values-mk/strings.xml b/packages/Tethering/res/values-mk/strings.xml index 0fab8aa4761f..ad255b620175 100644 --- a/packages/Tethering/res/values-mk/strings.xml +++ b/packages/Tethering/res/values-mk/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Поврзувањето или точката на пристап се активни"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Допрете за поставување."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Врзувањето е оневозможено"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Контактирајте со администраторот за детали"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Активно е врзување или точка на пристап"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Допрете за поставување."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Врзувањето е оневозможено"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Контактирајте со администраторот за детали"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус на точката на пристап и врзувањето"</string> </resources> diff --git a/packages/Tethering/res/values-ml/strings.xml b/packages/Tethering/res/values-ml/strings.xml deleted file mode 100644 index fd7e556e3899..000000000000 --- a/packages/Tethering/res/values-ml/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്പോട്ട് സജീവമാണ്"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"സജ്ജമാക്കാൻ ടാപ്പുചെയ്യുക."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"വിശദവിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string> -</resources> diff --git a/packages/Tethering/res/values-mn/strings.xml b/packages/Tethering/res/values-mn/strings.xml index 4596577c5d95..ed5b69bb2f59 100644 --- a/packages/Tethering/res/values-mn/strings.xml +++ b/packages/Tethering/res/values-mn/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Модем болгох эсвэл идэвхтэй цэг болгох"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Тохируулахын тулд товшино уу."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Модем болгох боломжгүй байна"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Модем болгох эсвэл сүлжээний цэг идэвхтэй байна"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Тохируулахын тулд товшино уу."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Модем болгохыг идэвхгүй болгосон"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Сүлжээний цэг болон модем болгох төлөв"</string> </resources> diff --git a/packages/Tethering/res/values-mr/strings.xml b/packages/Tethering/res/values-mr/strings.xml deleted file mode 100644 index 85c9ade4feee..000000000000 --- a/packages/Tethering/res/values-mr/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग किंवा हॉटस्पॉट सक्रिय"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करण्यासाठी टॅप करा."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग बंद आहे"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"तपशीलांसाठी तुमच्या प्रशासकाशी संपर्क साधा"</string> -</resources> diff --git a/packages/Tethering/res/values-ms/strings.xml b/packages/Tethering/res/values-ms/strings.xml index ec6bdbda08e7..09c5a0e0597b 100644 --- a/packages/Tethering/res/values-ms/strings.xml +++ b/packages/Tethering/res/values-ms/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Penambatan atau titik panas aktif"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Ketik untuk membuat persediaan."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Penambatan dilumpuhkan"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi pentadbir anda untuk maklumat lanjut"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Penambatan atau tempat liputan aktif"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ketik untuk membuat persediaan."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Penambatan dilumpuhkan"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi pentadbir anda untuk mendapatkan maklumat lanjut"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status tempat liputan & penambatan"</string> </resources> diff --git a/packages/Tethering/res/values-my/strings.xml b/packages/Tethering/res/values-my/strings.xml index 83978b67d433..ff960866002d 100644 --- a/packages/Tethering/res/values-my/strings.xml +++ b/packages/Tethering/res/values-my/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"တဆင့်ပြန်လည်လွှင့်ခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"မိုဘိုင်းဖုန်းကို မိုဒမ်အဖြစ်သုံးခြင်းအား ပိတ်ထားသည်"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"အသေးစိတ်အချက်အလက်များအတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းကို ပိတ်ထားသည်"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"အသေးစိတ်အတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ဟော့စပေါ့နှင့် မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း အခြေအနေ"</string> </resources> diff --git a/packages/Tethering/res/values-nb/strings.xml b/packages/Tethering/res/values-nb/strings.xml index 9abf32dd7bf1..d6e1fee1039b 100644 --- a/packages/Tethering/res/values-nb/strings.xml +++ b/packages/Tethering/res/values-nb/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Internettdeling eller trådløs sone er aktiv"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Trykk for å konfigurere."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internettdeling er slått av"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ta kontakt med administratoren din for å få mer informasjon"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Internettdeling eller Wi-Fi-sone er aktiv"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Trykk for å konfigurere."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internettdeling er slått av"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ta kontakt med administratoren din for å få mer informasjon"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for Wi-Fi-sone og internettdeling"</string> </resources> diff --git a/packages/Tethering/res/values-ne/strings.xml b/packages/Tethering/res/values-ne/strings.xml deleted file mode 100644 index c8869298a546..000000000000 --- a/packages/Tethering/res/values-ne/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"सेटअप गर्न ट्याप गर्नुहोस्।"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिङलाई असक्षम पारिएको छ"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string> -</resources> diff --git a/packages/Tethering/res/values-nl/strings.xml b/packages/Tethering/res/values-nl/strings.xml index 0ec4bff62154..49f8fd6ee726 100644 --- a/packages/Tethering/res/values-nl/strings.xml +++ b/packages/Tethering/res/values-nl/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering of hotspot actief"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om in te stellen."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is uitgeschakeld"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Neem contact op met je beheerder voor meer informatie"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering of hotspot actief"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tik om in te stellen."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is uitgeschakeld"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Neem contact op met je beheerder voor meer informatie"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status van hotspot en tethering"</string> </resources> diff --git a/packages/Tethering/res/values-or/strings.xml b/packages/Tethering/res/values-or/strings.xml deleted file mode 100644 index 457685795a16..000000000000 --- a/packages/Tethering/res/values-or/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ଟିଥରିଙ୍ଗ କିମ୍ୱା ହଟସ୍ପଟ୍ ସକ୍ରିୟ ଅଛି"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ସେଟଅପ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ଟିଥରିଙ୍ଗ ଅକ୍ଷମ କରାଯାଇଛି"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ବିବରଣୀ ପାଇଁ ନିଜ ଆଡମିନ୍ଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ"</string> -</resources> diff --git a/packages/Tethering/res/values-pa/strings.xml b/packages/Tethering/res/values-pa/strings.xml deleted file mode 100644 index deddf2ea27f7..000000000000 --- a/packages/Tethering/res/values-pa/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ਟੈਦਰਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ"</string> -</resources> diff --git a/packages/Tethering/res/values-pl/strings.xml b/packages/Tethering/res/values-pl/strings.xml index 48d8468935a1..98cfbbbddbd1 100644 --- a/packages/Tethering/res/values-pl/strings.xml +++ b/packages/Tethering/res/values-pl/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Aktywny tethering lub punkt dostępu"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Kliknij, by skonfigurować."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering został wyłączony"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Aktywny tethering lub punkt dostępu"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Kliknij, by skonfigurować"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering został wyłączony"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot i tethering – stan"</string> </resources> diff --git a/packages/Tethering/res/values-pt-rBR/strings.xml b/packages/Tethering/res/values-pt-rBR/strings.xml index 32c22b8713b5..338f8fcc1b6b 100644 --- a/packages/Tethering/res/values-pt-rBR/strings.xml +++ b/packages/Tethering/res/values-pt-rBR/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string> </resources> diff --git a/packages/Tethering/res/values-pt-rPT/strings.xml b/packages/Tethering/res/values-pt-rPT/strings.xml index 641e22f44f25..a06f033f5a90 100644 --- a/packages/Tethering/res/values-pt-rPT/strings.xml +++ b/packages/Tethering/res/values-pt-rPT/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ligação ponto a ponto ou hotspot activos"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"A ligação (à Internet) via telemóvel está desativada."</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacte o gestor para obter detalhes."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ligação (à Internet) via telemóvel ou zona Wi-Fi ativos"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"A ligação (à Internet) via telemóvel está desativada."</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacte o administrador para obter detalhes."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona Wi-Fi e da ligação (à Internet) via telemóvel"</string> </resources> diff --git a/packages/Tethering/res/values-pt/strings.xml b/packages/Tethering/res/values-pt/strings.xml index 32c22b8713b5..338f8fcc1b6b 100644 --- a/packages/Tethering/res/values-pt/strings.xml +++ b/packages/Tethering/res/values-pt/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string> </resources> diff --git a/packages/Tethering/res/values-ro/strings.xml b/packages/Tethering/res/values-ro/strings.xml index f861f733b4a1..7480ec559efa 100644 --- a/packages/Tethering/res/values-ro/strings.xml +++ b/packages/Tethering/res/values-ro/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot activ"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Atingeți ca să configurați."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tetheringul este dezactivat"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contactați administratorul pentru detalii"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering sau hotspot activ"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Atingeți ca să configurați."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tetheringul este dezactivat"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contactați administratorul pentru detalii"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Starea hotspotului și a tetheringului"</string> </resources> diff --git a/packages/Tethering/res/values-ru/strings.xml b/packages/Tethering/res/values-ru/strings.xml index 027cb410c54c..3153e0b9a00e 100644 --- a/packages/Tethering/res/values-ru/strings.xml +++ b/packages/Tethering/res/values-ru/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Включен режим модема"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Нажмите, чтобы настроить."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Включить режим модема нельзя"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Обратитесь к администратору, чтобы узнать подробности."</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Включен режим модема или хот-спот"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Нажмите, чтобы настроить."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Использование телефона в качестве модема запрещено"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Чтобы узнать подробности, обратитесь к администратору."</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хот-спота и режима модема"</string> </resources> diff --git a/packages/Tethering/res/values-si/strings.xml b/packages/Tethering/res/values-si/strings.xml index 7d8599f2c2d9..2b117bc227de 100644 --- a/packages/Tethering/res/values-si/strings.xml +++ b/packages/Tethering/res/values-si/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ටෙදරින් හෝ හොට්ස්පොට් සක්රීයයි"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"පිහිටුවීමට තට්ටු කරන්න."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ටෙදරින් අබල කර ඇත"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"ටෙදරින් හෝ හොට්ස්පොට් සක්රීයයි"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"පිහිටුවීමට තට්ටු කරන්න."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ටෙදරින් අබල කර ඇත"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"හොට්ස්පොට් & ටෙදරින් තත්ත්වය"</string> </resources> diff --git a/packages/Tethering/res/values-sk/strings.xml b/packages/Tethering/res/values-sk/strings.xml index a8fe297c0088..e1db50a41bc2 100644 --- a/packages/Tethering/res/values-sk/strings.xml +++ b/packages/Tethering/res/values-sk/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering alebo prístupový bod je aktívny"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím prejdete na nastavenie."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je deaktivovaný"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požiadajte svojho správcu"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering alebo prístupový bod je aktívny"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím prejdete na nastavenie."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je deaktivovaný"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požiadajte svojho správcu"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string> </resources> diff --git a/packages/Tethering/res/values-sl/strings.xml b/packages/Tethering/res/values-sl/strings.xml index b5e5e3856f7b..bcfe487050ad 100644 --- a/packages/Tethering/res/values-sl/strings.xml +++ b/packages/Tethering/res/values-sl/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivna povezava z internetom ali dostopna točka sta aktivni"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Dotaknite se, če želite nastaviti."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezava z internetom prek mobilnega telefona je onemogočena"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Za podrobnosti se obrnite na skrbnika"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Povezava z internetom prek mobilnega telefona ali dostopna točka je aktivna"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Dotaknite se, če želite nastaviti."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezava z internetom prek mobilnega telefona je onemogočena"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Za podrobnosti se obrnite na skrbnika"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stanje dostopne točke in povezave z internetom prek mobilnega telefona"</string> </resources> diff --git a/packages/Tethering/res/values-sq/strings.xml b/packages/Tethering/res/values-sq/strings.xml index fdd4906cc51e..2e5602076823 100644 --- a/packages/Tethering/res/values-sq/strings.xml +++ b/packages/Tethering/res/values-sq/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Lidhja e çiftimit ose ajo e qasjes në zona publike interneti është aktive"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Trokit për ta konfiguruar."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Lidhja e çiftimit është çaktivizuar"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakto me administratorin për detaje"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ndarja e internetit ose zona e qasjes së internetit është aktive"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Trokit për ta konfiguruar."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ndarja e internetit është çaktivizuar"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakto me administratorin për detaje"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Statusi i zonës së qasjes dhe ndarjes së internetit"</string> </resources> diff --git a/packages/Tethering/res/values-sr/strings.xml b/packages/Tethering/res/values-sr/strings.xml index 9fab34589724..09c7c16739c7 100644 --- a/packages/Tethering/res/values-sr/strings.xml +++ b/packages/Tethering/res/values-sr/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Активно повезивање са интернетом преко мобилног уређаја или хотспот"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Додирните да бисте подесили."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Привезивање је онемогућено"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Потражите детаље од администратора"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Привезивање или хотспот је активан"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Додирните да бисте подесили."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Привезивање је онемогућено"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Потражите детаље од администратора"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хотспота и привезивања"</string> </resources> diff --git a/packages/Tethering/res/values-sv/strings.xml b/packages/Tethering/res/values-sv/strings.xml index 10eeb0fe12e1..adb6b8184c08 100644 --- a/packages/Tethering/res/values-sv/strings.xml +++ b/packages/Tethering/res/values-sv/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Internetdelning eller surfzon aktiverad"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Tryck om du vill konfigurera."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internetdelning har inaktiverats"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakta administratören om du vill veta mer"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Internetdelning eller surfzon har aktiverats"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Tryck om du vill konfigurera."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internetdelning har inaktiverats"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakta administratören om du vill veta mer"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trådlös surfzon och internetdelning har inaktiverats"</string> </resources> diff --git a/packages/Tethering/res/values-sw/strings.xml b/packages/Tethering/res/values-sw/strings.xml index 335396307730..3f10e47901f2 100644 --- a/packages/Tethering/res/values-sw/strings.xml +++ b/packages/Tethering/res/values-sw/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Kushiriki au kusambaza intaneti kumewashwa"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Gusa ili uweke mipangilio."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Umezima kipengele cha kusambaza mtandao"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Kusambaza mtandao au mtandaopepe umewashwa"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Gusa ili uweke mipangilio."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Umezima kipengele cha kusambaza mtandao"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Mtandaopepe na hali ya kusambaza mtandao"</string> </resources> diff --git a/packages/Tethering/res/values-ta/strings.xml b/packages/Tethering/res/values-ta/strings.xml deleted file mode 100644 index b1e5cc241376..000000000000 --- a/packages/Tethering/res/values-ta/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"டெதெரிங்/ஹாட்ஸ்பாட் இயங்குகிறது"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"அமைக்க, தட்டவும்."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"இணைப்பு முறை முடக்கப்பட்டுள்ளது"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"விவரங்களுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string> -</resources> diff --git a/packages/Tethering/res/values-te/strings.xml b/packages/Tethering/res/values-te/strings.xml deleted file mode 100644 index aae40dee40db..000000000000 --- a/packages/Tethering/res/values-te/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"టీథర్ చేయబడినది లేదా హాట్స్పాట్ సక్రియంగా ఉండేది"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"సెటప్ చేయడానికి నొక్కండి."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"టెథెరింగ్ నిలిపివేయబడింది"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"వివరాల కోసం మీ నిర్వాహకులను సంప్రదించండి"</string> -</resources> diff --git a/packages/Tethering/res/values-th/strings.xml b/packages/Tethering/res/values-th/strings.xml index 1b800565ad1f..33a8b0c59278 100644 --- a/packages/Tethering/res/values-th/strings.xml +++ b/packages/Tethering/res/values-th/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"แตะเพื่อตั้งค่า"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือหรือฮอตสปอตทำงานอยู่"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"แตะเพื่อตั้งค่า"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"สถานะฮอตสปอตและการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string> </resources> diff --git a/packages/Tethering/res/values-tl/strings.xml b/packages/Tethering/res/values-tl/strings.xml index 12863f90e15a..0f31daf53ca2 100644 --- a/packages/Tethering/res/values-tl/strings.xml +++ b/packages/Tethering/res/values-tl/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Pagsasama o aktibong hotspot"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"I-tap upang i-set up."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Naka-disable ang pag-tether"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Aktibo ang pag-tether o hotspot"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"I-tap para i-set up."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Naka-disable ang pag-tether"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status ng hotspot at pag-tether"</string> </resources> diff --git a/packages/Tethering/res/values-tr/strings.xml b/packages/Tethering/res/values-tr/strings.xml index bfcf1ace2cf7..aaa264f04d31 100644 --- a/packages/Tethering/res/values-tr/strings.xml +++ b/packages/Tethering/res/values-tr/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering veya hotspot etkin"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Ayarlamak için dokunun."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering devre dışı bırakıldı"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ayrıntılı bilgi için yöneticinize başvurun"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering veya hotspot etkin"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamak için dokunun."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering devre dışı bırakıldı"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ayrıntılı bilgi için yöneticinize başvurun"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot ve tethering durumu"</string> </resources> diff --git a/packages/Tethering/res/values-uk/strings.xml b/packages/Tethering/res/values-uk/strings.xml index 8e159c072350..875ba84b4e37 100644 --- a/packages/Tethering/res/values-uk/strings.xml +++ b/packages/Tethering/res/values-uk/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Прив\'язка чи точка дост. активна"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Торкніться, щоб налаштувати."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Використання телефона в режимі модема вимкнено"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Щоб дізнатися більше, зв’яжіться з адміністратором"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Модем чи точка доступу активні"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Натисніть, щоб налаштувати."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Використання телефона як модема вимкнено"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Щоб дізнатися більше, зв\'яжіться з адміністратором"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус точки доступу та модема"</string> </resources> diff --git a/packages/Tethering/res/values-ur/strings.xml b/packages/Tethering/res/values-ur/strings.xml deleted file mode 100644 index 89195d4aae29..000000000000 --- a/packages/Tethering/res/values-ur/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"ٹیدرنگ غیر فعال ہے"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string> -</resources> diff --git a/packages/Tethering/res/values-uz/strings.xml b/packages/Tethering/res/values-uz/strings.xml index 0ac4d4a7410a..50b39983391b 100644 --- a/packages/Tethering/res/values-uz/strings.xml +++ b/packages/Tethering/res/values-uz/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Modem rejimi yoniq"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Sozlash uchun bosing."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modem rejimi faolsizlantirildi"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Tafsilotlari uchun administratoringizga murojaat qiling"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Modem rejimi yoki hotspot yoniq"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Sozlash uchun bosing."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modem rejimi faolsizlantirildi"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Tafsilotlari uchun administratoringizga murojaat qiling"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot va modem rejimi holati"</string> </resources> diff --git a/packages/Tethering/res/values-vi/strings.xml b/packages/Tethering/res/values-vi/strings.xml index 85a4db8aa5da..b6e294221c09 100644 --- a/packages/Tethering/res/values-vi/strings.xml +++ b/packages/Tethering/res/values-vi/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Chức năng điểm truy cập Internet hoặc điểm phát sóng đang hoạt động"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Nhấn để thiết lập."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Đã tắt tính năng chia sẻ kết nối"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Tính năng chia sẻ kết nối hoặc điểm phát sóng đang hoạt động"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Hãy nhấn để thiết lập."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Đã tắt tính năng chia sẻ kết nối"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trạng thái điểm phát sóng và trạng thái chia sẻ kết nối"</string> </resources> diff --git a/packages/Tethering/res/values-zh-rCN/strings.xml b/packages/Tethering/res/values-zh-rCN/strings.xml index ff1fe039531c..55e2f1a76b91 100644 --- a/packages/Tethering/res/values-zh-rCN/strings.xml +++ b/packages/Tethering/res/values-zh-rCN/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"网络共享或热点已启用"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"点按即可进行设置。"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"网络共享已停用"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"请与您的管理员联系以了解详情"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"网络共享或热点已启用"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"点按即可设置。"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"网络共享已停用"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"如需了解详情,请与您的管理员联系"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"热点和网络共享状态"</string> </resources> diff --git a/packages/Tethering/res/values-zh-rHK/strings.xml b/packages/Tethering/res/values-zh-rHK/strings.xml index 0de39fac97f8..5d4c4e86ff7d 100644 --- a/packages/Tethering/res/values-zh-rHK/strings.xml +++ b/packages/Tethering/res/values-zh-rHK/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"已啟用網絡共享或熱點"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"輕按即可設定。"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"網絡共享已停用"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"請聯絡您的管理員以瞭解詳情"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"網絡共享或熱點已啟用"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"輕按即可設定。"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"網絡共享已停用"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"請聯絡您的管理員以瞭解詳情"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"熱點和網絡共享狀態"</string> </resources> diff --git a/packages/Tethering/res/values-zh-rTW/strings.xml b/packages/Tethering/res/values-zh-rTW/strings.xml index 9a117bbca43f..a6561a2dfe16 100644 --- a/packages/Tethering/res/values-zh-rTW/strings.xml +++ b/packages/Tethering/res/values-zh-rTW/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"網路共用或無線基地台已啟用"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"輕觸即可進行設定。"</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"數據連線已停用"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳情請洽你的管理員"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"數據連線或無線基地台已啟用"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"輕觸即可進行設定。"</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"數據連線已停用"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳情請洽你的管理員"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與數據連線狀態"</string> </resources> diff --git a/packages/Tethering/res/values-zu/strings.xml b/packages/Tethering/res/values-zu/strings.xml index 8fe10d86cb03..aa65c80df5cd 100644 --- a/packages/Tethering/res/values-zu/strings.xml +++ b/packages/Tethering/res/values-zu/strings.xml @@ -1,8 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="tethered_notification_title" msgid="3146694234398202601">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string> - <string name="tethered_notification_message" msgid="2113628520792055377">"Thepha ukuze usethe."</string> - <string name="disable_tether_notification_title" msgid="7526977944111313195">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string> - <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string> + <string name="tethered_notification_title" msgid="6426563586025792944">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string> + <string name="tethered_notification_message" msgid="64800879503420696">"Thepha ukuze usethe."</string> + <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string> + <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string> + <string name="notification_channel_tethering_status" msgid="2663463891530932727">"I-Hotspot nesimo sokusebenzisa ifoni njengemodemu"</string> </resources> diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml index ba98a66ff7e0..52a16545c22f 100644 --- a/packages/Tethering/res/values/strings.xml +++ b/packages/Tethering/res/values/strings.xml @@ -13,12 +13,15 @@ See the License for the specific language governing permissions and limitations under the License. --> -<resources> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Shown when the device is tethered --> <!-- String for tethered notification title [CHAR LIMIT=200] --> <string name="tethered_notification_title">Tethering or hotspot active</string> <!-- String for tethered notification message [CHAR LIMIT=200] --> <string name="tethered_notification_message">Tap to set up.</string> + <!-- String for tethered notification title with client number info. --> + <plurals name="tethered_notification_title_with_client_number"> + </plurals> <!-- This notification is shown when tethering has been disabled on a user's device. The device is managed by the user's employer. Tethering can't be turned on unless the @@ -32,4 +35,18 @@ Internet" settings page. That is currently the tether_settings_title_all string. --> <!-- String for tether notification channel name [CHAR LIMIT=200] --> <string name="notification_channel_tethering_status">Hotspot & tethering status</string> -</resources>
\ No newline at end of file + + <!-- String for no upstream notification title [CHAR LIMIT=200] --> + <string name="no_upstream_notification_title"></string> + <!-- String for no upstream notification message [CHAR LIMIT=200] --> + <string name="no_upstream_notification_message"></string> + <!-- String for cellular roaming notification disable button [CHAR LIMIT=200] --> + <string name="no_upstream_notification_disable_button"></string> + + <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_title"></string> + <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> + <string name="upstream_roaming_notification_message"></string> + <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_continue_button"></string> +</resources> 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 38f8609e217f..82b17acae592 100644 --- a/packages/Tethering/src/android/net/ip/IpServer.java +++ b/packages/Tethering/src/android/net/ip/IpServer.java @@ -18,12 +18,14 @@ 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; import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH; import static android.net.util.NetworkConstants.asByte; import static android.net.util.TetheringMessageBase.BASE_IPSERVER; +import static android.system.OsConstants.RT_SCOPE_UNIVERSE; import android.net.INetd; import android.net.INetworkStackStatusCallback; @@ -34,6 +36,7 @@ import android.net.MacAddress; import android.net.RouteInfo; import android.net.TetheredClient; import android.net.TetheringManager; +import android.net.TetheringRequestParcel; import android.net.dhcp.DhcpLeaseParcelable; import android.net.dhcp.DhcpServerCallbacks; import android.net.dhcp.DhcpServingParamsParcel; @@ -242,6 +245,10 @@ public class IpServer extends StateMachine { private IDhcpServer mDhcpServer; private RaParams mLastRaParams; private LinkAddress mIpv4Address; + + private LinkAddress mStaticIpv4ServerAddr; + private LinkAddress mStaticIpv4ClientAddr; + @NonNull private List<TetheredClient> mDhcpLeases = Collections.emptyList(); @@ -448,7 +455,9 @@ public class IpServer extends StateMachine { final ArrayList<TetheredClient> leases = new ArrayList<>(); for (DhcpLeaseParcelable lease : leaseParcelables) { final LinkAddress address = new LinkAddress( - intToInet4AddressHTH(lease.netAddr), lease.prefixLength); + intToInet4AddressHTH(lease.netAddr), lease.prefixLength, + 0 /* flags */, RT_SCOPE_UNIVERSE /* as per RFC6724#3.2 */, + lease.expTime /* deprecationTime */, lease.expTime /* expirationTime */); final MacAddress macAddress; try { @@ -460,7 +469,7 @@ public class IpServer extends StateMachine { } final TetheredClient.AddressInfo addressInfo = new TetheredClient.AddressInfo( - address, lease.hostname, lease.expTime); + address, lease.hostname); leases.add(new TetheredClient( macAddress, Collections.singletonList(addressInfo), @@ -484,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++; @@ -529,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; @@ -544,6 +561,8 @@ public class IpServer extends StateMachine { // into calls to InterfaceController, shared with startIPv4(). mInterfaceCtrl.clearIPv4Address(); mIpv4Address = null; + mStaticIpv4ServerAddr = null; + mStaticIpv4ClientAddr = null; } private boolean configureIPv4(boolean enabled) { @@ -554,7 +573,10 @@ public class IpServer extends StateMachine { final Inet4Address srvAddr; int prefixLen = 0; try { - if (mInterfaceType == TetheringManager.TETHERING_USB + if (mStaticIpv4ServerAddr != null) { + srvAddr = (Inet4Address) mStaticIpv4ServerAddr.getAddress(); + prefixLen = mStaticIpv4ServerAddr.getPrefixLength(); + } else if (mInterfaceType == TetheringManager.TETHERING_USB || mInterfaceType == TetheringManager.TETHERING_NCM) { srvAddr = (Inet4Address) parseNumericAddress(USB_NEAR_IFACE_ADDR); prefixLen = USB_PREFIX_LENGTH; @@ -574,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) { @@ -599,10 +621,6 @@ public class IpServer extends StateMachine { return false; } - if (!configureDhcp(enabled, srvAddr, prefixLen)) { - return false; - } - // Directly-connected route. final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(), mIpv4Address.getPrefixLength()); @@ -614,7 +632,8 @@ public class IpServer extends StateMachine { mLinkProperties.removeLinkAddress(mIpv4Address); mLinkProperties.removeRoute(route); } - return true; + + return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr); } private String getRandomWifiIPv4Address() { @@ -934,6 +953,20 @@ public class IpServer extends StateMachine { mLinkProperties.setInterfaceName(mIfaceName); } + private void maybeConfigureStaticIp(final TetheringRequestParcel request) { + // 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; + } + class InitialState extends State { @Override public void enter() { @@ -948,9 +981,11 @@ public class IpServer extends StateMachine { mLastError = TetheringManager.TETHER_ERROR_NO_ERROR; switch (message.arg1) { case STATE_LOCAL_ONLY: + maybeConfigureStaticIp((TetheringRequestParcel) message.obj); transitionTo(mLocalHotspotState); break; case STATE_TETHERED: + maybeConfigureStaticIp((TetheringRequestParcel) message.obj); transitionTo(mTetheredState); break; default: @@ -1035,7 +1070,7 @@ public class IpServer extends StateMachine { case CMD_START_TETHERING_ERROR: case CMD_STOP_TETHERING_ERROR: case CMD_SET_DNS_FORWARDERS_ERROR: - mLastError = TetheringManager.TETHER_ERROR_MASTER_ERROR; + mLastError = TetheringManager.TETHER_ERROR_INTERNAL_ERROR; transitionTo(mInitialState); break; default: @@ -1166,7 +1201,7 @@ public class IpServer extends StateMachine { } catch (RemoteException | ServiceSpecificException e) { mLog.e("Exception enabling NAT: " + e.toString()); cleanupUpstream(); - mLastError = TetheringManager.TETHER_ERROR_ENABLE_NAT_ERROR; + mLastError = TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR; transitionTo(mInitialState); return true; } diff --git a/packages/Tethering/src/android/net/util/TetheringUtils.java b/packages/Tethering/src/android/net/util/TetheringUtils.java index 5a6d5c1cbfb0..dd67dddae1cd 100644 --- a/packages/Tethering/src/android/net/util/TetheringUtils.java +++ b/packages/Tethering/src/android/net/util/TetheringUtils.java @@ -15,8 +15,11 @@ */ package android.net.util; +import android.net.TetheringRequestParcel; + import java.io.FileDescriptor; import java.net.SocketException; +import java.util.Objects; /** * Native methods for tethering utilization. @@ -38,4 +41,17 @@ public class TetheringUtils { public static int uint16(short s) { return s & 0xffff; } + + /** Check whether two TetheringRequestParcels are the same. */ + public static boolean isTetheringRequestEquals(final TetheringRequestParcel request, + final TetheringRequestParcel otherRequest) { + if (request == otherRequest) return true; + + return request != null && otherRequest != null + && request.tetheringType == otherRequest.tetheringType + && Objects.equals(request.localIPv4Address, otherRequest.localIPv4Address) + && Objects.equals(request.staticClientAddress, otherRequest.staticClientAddress) + && request.exemptFromEntitlementCheck == otherRequest.exemptFromEntitlementCheck + && request.showProvisioningUi == otherRequest.showProvisioningUi; + } } diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java index e81d6ac7a588..bd60594f27bc 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java @@ -25,7 +25,7 @@ import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN; import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; -import static android.net.TetheringManager.TETHER_ERROR_PROVISION_FAILED; +import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED; import android.app.AlarmManager; import android.app.PendingIntent; @@ -579,7 +579,7 @@ public class EntitlementManager { switch (value) { case TETHER_ERROR_ENTITLEMENT_UNKNOWN: return "TETHER_ERROR_ENTITLEMENT_UNKONWN"; case TETHER_ERROR_NO_ERROR: return "TETHER_ERROR_NO_ERROR"; - case TETHER_ERROR_PROVISION_FAILED: return "TETHER_ERROR_PROVISION_FAILED"; + case TETHER_ERROR_PROVISIONING_FAILED: return "TETHER_ERROR_PROVISIONING_FAILED"; default: return String.format("UNKNOWN ERROR (%d)", value); } @@ -592,7 +592,7 @@ public class EntitlementManager { protected void onReceiveResult(int resultCode, Bundle resultData) { int updatedCacheValue = updateEntitlementCacheValue(type, resultCode); addDownstreamMapping(type, updatedCacheValue); - if (updatedCacheValue == TETHER_ERROR_PROVISION_FAILED && notifyFail) { + if (updatedCacheValue == TETHER_ERROR_PROVISIONING_FAILED && notifyFail) { mListener.onUiEntitlementFailed(type); } if (receiver != null) receiver.send(updatedCacheValue, null); @@ -635,8 +635,8 @@ public class EntitlementManager { mEntitlementCacheValue.put(type, resultCode); return resultCode; } else { - mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISION_FAILED); - return TETHER_ERROR_PROVISION_FAILED; + mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISIONING_FAILED); + return TETHER_ERROR_PROVISIONING_FAILED; } } diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java index a402ffa47355..15cdb6ad7a8e 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java @@ -39,8 +39,7 @@ import android.net.RouteInfo; import android.net.netlink.ConntrackMessage; import android.net.netlink.NetlinkConstants; import android.net.netlink.NetlinkSocket; -import android.net.netstats.provider.AbstractNetworkStatsProvider; -import android.net.netstats.provider.NetworkStatsProviderCallback; +import android.net.netstats.provider.NetworkStatsProvider; import android.net.util.SharedLog; import android.os.Handler; import android.provider.Settings; @@ -89,8 +88,8 @@ public class OffloadController { private final Handler mHandler; private final OffloadHardwareInterface mHwInterface; private final ContentResolver mContentResolver; - private final @NonNull OffloadTetheringStatsProvider mStatsProvider; - private final @Nullable NetworkStatsProviderCallback mStatsProviderCb; + @Nullable + private final OffloadTetheringStatsProvider mStatsProvider; private final SharedLog mLog; private final HashMap<String, LinkProperties> mDownstreams; private boolean mConfigInitialized; @@ -124,19 +123,18 @@ public class OffloadController { mHandler = h; mHwInterface = hwi; mContentResolver = contentResolver; - mStatsProvider = new OffloadTetheringStatsProvider(); mLog = log.forSubComponent(TAG); mDownstreams = new HashMap<>(); mExemptPrefixes = new HashSet<>(); mLastLocalPrefixStrs = new HashSet<>(); - NetworkStatsProviderCallback providerCallback = null; + OffloadTetheringStatsProvider provider = new OffloadTetheringStatsProvider(); try { - providerCallback = nsm.registerNetworkStatsProvider( - getClass().getSimpleName(), mStatsProvider); + nsm.registerNetworkStatsProvider(getClass().getSimpleName(), provider); } catch (RuntimeException e) { Log.wtf(TAG, "Cannot register offload stats provider: " + e); + provider = null; } - mStatsProviderCb = providerCallback; + mStatsProvider = provider; } /** Start hardware offload. */ @@ -185,7 +183,7 @@ public class OffloadController { // and we need to synchronize stats and limits between // software and hardware forwarding. updateStatsForAllUpstreams(); - mStatsProvider.pushTetherStats(); + if (mStatsProvider != null) mStatsProvider.pushTetherStats(); } @Override @@ -198,7 +196,7 @@ public class OffloadController { // limits set take into account any software tethering // traffic that has been happening in the meantime. updateStatsForAllUpstreams(); - mStatsProvider.pushTetherStats(); + if (mStatsProvider != null) mStatsProvider.pushTetherStats(); // [2] (Re)Push all state. computeAndPushLocalPrefixes(UpdateType.FORCE); pushAllDownstreamState(); @@ -217,10 +215,12 @@ public class OffloadController { // TODO: rev the HAL so that it provides an interface name. updateStatsForCurrentUpstream(); - mStatsProvider.pushTetherStats(); - // Push stats to service does not cause the service react to it immediately. - // Inform the service about limit reached. - if (mStatsProviderCb != null) mStatsProviderCb.onLimitReached(); + if (mStatsProvider != null) { + mStatsProvider.pushTetherStats(); + // Push stats to service does not cause the service react to it + // immediately. Inform the service about limit reached. + mStatsProvider.notifyLimitReached(); + } } @Override @@ -263,13 +263,17 @@ public class OffloadController { } @VisibleForTesting - class OffloadTetheringStatsProvider extends AbstractNetworkStatsProvider { + class OffloadTetheringStatsProvider extends NetworkStatsProvider { // These stats must only ever be touched on the handler thread. @NonNull private NetworkStats mIfaceStats = new NetworkStats(0L, 0); @NonNull private NetworkStats mUidStats = new NetworkStats(0L, 0); + /** + * A helper function that collect tether stats from local hashmap. Note that this does not + * invoke binder call. + */ @VisibleForTesting @NonNull NetworkStats getTetherStats(@NonNull StatsType how) { @@ -280,14 +284,14 @@ public class OffloadController { final ForwardedStats value = kv.getValue(); final Entry entry = new Entry(kv.getKey(), uid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, value.rxBytes, 0L, value.txBytes, 0L, 0L); - stats = stats.addValues(entry); + stats = stats.addEntry(entry); } return stats; } @Override - public void setLimit(String iface, long quotaBytes) { + public void onSetLimit(String iface, long quotaBytes) { // Listen for all iface is necessary since upstream might be changed after limit // is set. mHandler.post(() -> { @@ -315,13 +319,12 @@ public class OffloadController { */ public void pushTetherStats() { // TODO: remove the accumulated stats and report the diff from HAL directly. - if (null == mStatsProviderCb) return; final NetworkStats ifaceDiff = getTetherStats(StatsType.STATS_PER_IFACE).subtract(mIfaceStats); final NetworkStats uidDiff = getTetherStats(StatsType.STATS_PER_UID).subtract(mUidStats); try { - mStatsProviderCb.onStatsUpdated(0 /* token */, ifaceDiff, uidDiff); + notifyStatsUpdated(0 /* token */, ifaceDiff, uidDiff); mIfaceStats = mIfaceStats.add(ifaceDiff); mUidStats = mUidStats.add(uidDiff); } catch (RuntimeException e) { @@ -330,7 +333,7 @@ public class OffloadController { } @Override - public void requestStatsUpdate(int token) { + public void onRequestStatsUpdate(int token) { // Do not attempt to update stats by querying the offload HAL // synchronously from a different thread than the Handler thread. http://b/64771555. mHandler.post(() -> { @@ -340,7 +343,7 @@ public class OffloadController { } @Override - public void setAlert(long quotaBytes) { + public void onSetAlert(long quotaBytes) { // TODO: Ask offload HAL to notify alert without stopping traffic. } } 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 553901757397..343ed4b16cd6 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java @@ -39,11 +39,12 @@ import static android.net.TetheringManager.TETHERING_NCM; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHERING_WIFI_P2P; -import static android.net.TetheringManager.TETHER_ERROR_MASTER_ERROR; +import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR; import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL; import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE; import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; +import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE; 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; @@ -92,6 +93,7 @@ import android.net.util.BaseNetdUnsolicitedEventListener; import android.net.util.InterfaceSet; import android.net.util.PrefixUtils; import android.net.util.SharedLog; +import android.net.util.TetheringUtils; import android.net.util.VersionedBroadcastListener; import android.net.wifi.WifiClient; import android.net.wifi.WifiManager; @@ -196,6 +198,11 @@ public class Tethering { private final SharedLog mLog = new SharedLog(TAG); private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks = new RemoteCallbackList<>(); + // Currently active tethering requests per tethering type. Only one of each type can be + // requested at a time. After a tethering type is requested, the map keeps tethering parameters + // to be used after the interface comes up asynchronously. + private final SparseArray<TetheringRequestParcel> mActiveTetheringRequests = + new SparseArray<>(); // used to synchronize public access to members private final Object mPublicSync; @@ -296,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); @@ -333,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 { @@ -362,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 { @@ -424,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); } } @@ -487,14 +495,31 @@ public class Tethering { } void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) { - mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType, - request.showProvisioningUi); - enableTetheringInternal(request.tetheringType, true /* enabled */, listener); + mHandler.post(() -> { + final TetheringRequestParcel unfinishedRequest = mActiveTetheringRequests.get( + request.tetheringType); + // If tethering is already enabled with a different request, + // disable before re-enabling. + if (unfinishedRequest != null + && !TetheringUtils.isTetheringRequestEquals(unfinishedRequest, request)) { + enableTetheringInternal(request.tetheringType, false /* disabled */, null); + mEntitlementMgr.stopProvisioningIfNeeded(request.tetheringType); + } + mActiveTetheringRequests.put(request.tetheringType, request); + + mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType, + request.showProvisioningUi); + enableTetheringInternal(request.tetheringType, true /* enabled */, listener); + }); } void stopTethering(int type) { - enableTetheringInternal(type, false /* disabled */, null); - mEntitlementMgr.stopProvisioningIfNeeded(type); + mHandler.post(() -> { + mActiveTetheringRequests.remove(type); + + enableTetheringInternal(type, false /* disabled */, null); + mEntitlementMgr.stopProvisioningIfNeeded(type); + }); } /** @@ -503,39 +528,45 @@ public class Tethering { */ private void enableTetheringInternal(int type, boolean enable, final IIntResultListener listener) { - int result; + int result = TETHER_ERROR_NO_ERROR; switch (type) { case TETHERING_WIFI: result = setWifiTethering(enable); - sendTetherResult(listener, result); break; case TETHERING_USB: result = setUsbTethering(enable); - sendTetherResult(listener, result); break; case TETHERING_BLUETOOTH: setBluetoothTethering(enable, listener); break; case TETHERING_NCM: result = setNcmTethering(enable); - sendTetherResult(listener, result); break; case TETHERING_ETHERNET: result = setEthernetTethering(enable); - sendTetherResult(listener, result); break; default: Log.w(TAG, "Invalid tether type."); - sendTetherResult(listener, TETHER_ERROR_UNKNOWN_IFACE); + result = TETHER_ERROR_UNKNOWN_TYPE; + } + + // The result of Bluetooth tethering will be sent by #setBluetoothTethering. + if (type != TETHERING_BLUETOOTH) { + sendTetherResult(listener, result, type); } } - private void sendTetherResult(final IIntResultListener listener, int result) { + private void sendTetherResult(final IIntResultListener listener, final int result, + final int type) { if (listener != null) { try { listener.onResult(result); } catch (RemoteException e) { } } + + // If changing tethering fail, remove corresponding request + // no matter who trigger the start/stop. + if (result != TETHER_ERROR_NO_ERROR) mActiveTetheringRequests.remove(type); } private int setWifiTethering(final boolean enable) { @@ -557,7 +588,7 @@ public class Tethering { Binder.restoreCallingIdentity(ident); } - return TETHER_ERROR_MASTER_ERROR; + return TETHER_ERROR_INTERNAL_ERROR; } private void setBluetoothTethering(final boolean enable, final IIntResultListener listener) { @@ -565,7 +596,7 @@ public class Tethering { if (adapter == null || !adapter.isEnabled()) { Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " + (adapter == null)); - sendTetherResult(listener, TETHER_ERROR_SERVICE_UNAVAIL); + sendTetherResult(listener, TETHER_ERROR_SERVICE_UNAVAIL, TETHERING_BLUETOOTH); return; } @@ -593,8 +624,8 @@ public class Tethering { // We should figure out a way to bubble up that failure instead of sending success. final int result = (((BluetoothPan) proxy).isTetheringOn() == enable) ? TETHER_ERROR_NO_ERROR - : TETHER_ERROR_MASTER_ERROR; - sendTetherResult(listener, result); + : TETHER_ERROR_INTERNAL_ERROR; + sendTetherResult(listener, result, TETHERING_BLUETOOTH); adapter.closeProfileProxy(BluetoothProfile.PAN, proxy); } }, BluetoothProfile.PAN); @@ -605,27 +636,30 @@ 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); } else { stopEthernetTetheringLocked(); - if (mEthernetCallback != null) { - mEthernetIfaceRequest.release(); - mEthernetCallback = null; - mEthernetIfaceRequest = null; - } } } return TETHER_ERROR_NO_ERROR; } private void stopEthernetTetheringLocked() { - if (mConfiguredEthernetIface == null) return; - changeInterfaceState(mConfiguredEthernetIface, IpServer.STATE_AVAILABLE); - stopTrackingInterfaceLocked(mConfiguredEthernetIface); - mConfiguredEthernetIface = null; + if (mConfiguredEthernetIface != null) { + stopTrackingInterfaceLocked(mConfiguredEthernetIface); + mConfiguredEthernetIface = null; + } + if (mEthernetCallback != null) { + mEthernetIfaceRequest.release(); + mEthernetCallback = null; + mEthernetIfaceRequest = null; + } } private class EthernetCallback implements EthernetManager.TetheredInterfaceCallback { @@ -672,12 +706,18 @@ public class Tethering { Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring"); return TETHER_ERROR_UNAVAIL_IFACE; } - // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's - // queue but not yet processed, this will be a no-op and it will not - // return an error. + // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's queue but not yet + // processed, this will be a no-op and it will not return an error. // - // TODO: reexamine the threading and messaging model. - tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState); + // This code cannot race with untether() because they both synchronize on mPublicSync. + // TODO: reexamine the threading and messaging model to totally remove mPublicSync. + final int type = tetherState.ipServer.interfaceType(); + final TetheringRequestParcel request = mActiveTetheringRequests.get(type, null); + if (request != null) { + mActiveTetheringRequests.delete(type); + } + tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState, 0, + request); return TETHER_ERROR_NO_ERROR; } } @@ -960,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; } @@ -983,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 } } @@ -1458,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( @@ -1523,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. @@ -2105,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 @@ -2119,10 +2177,7 @@ public class Tethering { @Override public void dhcpLeasesChanged() { - if (mConnectedClientsTracker.updateConnectedClients( - mForwardedDownstreams, null /* wifiClients */)) { - reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients()); - } + updateConnectedClients(null /* wifiClients */); } }; } @@ -2145,7 +2200,7 @@ public class Tethering { // If TetherMasterSM is in ErrorState, TetherMasterSM stays there. // Thus we give a chance for TetherMasterSM to recover to InitialState // by sending CMD_CLEAR_ERROR - if (error == TETHER_ERROR_MASTER_ERROR) { + if (error == TETHER_ERROR_INTERNAL_ERROR) { mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who); } int which; 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 020b32adcfd7..c30be25dbd22 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java @@ -33,6 +33,7 @@ import android.net.ITetheringConnector; import android.net.ITetheringEventCallback; import android.net.NetworkCapabilities; import android.net.NetworkRequest; +import android.net.NetworkStack; import android.net.TetheringRequestParcel; import android.net.dhcp.DhcpServerCallbacks; import android.net.dhcp.DhcpServingParamsParcel; @@ -79,6 +80,7 @@ public class TetheringService extends Service { mContext = mDeps.getContext(); mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mTethering = makeTethering(mDeps); + mTethering.startStateMachineUpdaters(); } /** @@ -364,8 +366,7 @@ public class TetheringService extends Service { IBinder connector; try { final long before = System.currentTimeMillis(); - while ((connector = (IBinder) mContext.getSystemService( - Context.NETWORK_STACK_SERVICE)) == null) { + while ((connector = NetworkStack.getService()) == null) { if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) { Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector"); return null; 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 2875f71e5ed2..45bb4ab6e5f7 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java @@ -244,7 +244,8 @@ public class UpstreamNetworkMonitor { // Additionally, we log a message to aid in any subsequent debugging. mLog.i("requesting mobile upstream network: " + mobileUpstreamRequest); - cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType, mHandler); + cm().requestNetwork(mobileUpstreamRequest, 0, legacyType, mHandler, + mMobileNetworkCallback); } /** Release mobile network request. */ @@ -585,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/TetheredClientTest.kt b/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt index d85389aeb625..a20a0dfd9c89 100644 --- a/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt +++ b/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt @@ -20,6 +20,7 @@ import android.net.InetAddresses.parseNumericAddress import android.net.TetheredClient.AddressInfo import android.net.TetheringManager.TETHERING_BLUETOOTH import android.net.TetheringManager.TETHERING_USB +import android.system.OsConstants.RT_SCOPE_UNIVERSE import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 import com.android.testutils.assertParcelSane @@ -30,11 +31,19 @@ import kotlin.test.assertNotEquals private val TEST_MACADDR = MacAddress.fromBytes(byteArrayOf(12, 23, 34, 45, 56, 67)) private val TEST_OTHER_MACADDR = MacAddress.fromBytes(byteArrayOf(23, 34, 45, 56, 67, 78)) -private val TEST_ADDR1 = LinkAddress(parseNumericAddress("192.168.113.3"), 24) -private val TEST_ADDR2 = LinkAddress(parseNumericAddress("fe80::1:2:3"), 64) +private val TEST_ADDR1 = makeLinkAddress("192.168.113.3", prefixLength = 24, expTime = 123L) +private val TEST_ADDR2 = makeLinkAddress("fe80::1:2:3", prefixLength = 64, expTime = 456L) private val TEST_ADDRINFO1 = AddressInfo(TEST_ADDR1, "test_hostname") private val TEST_ADDRINFO2 = AddressInfo(TEST_ADDR2, null) +private fun makeLinkAddress(addr: String, prefixLength: Int, expTime: Long) = LinkAddress( + parseNumericAddress(addr), + prefixLength, + 0 /* flags */, + RT_SCOPE_UNIVERSE, + expTime /* deprecationTime */, + expTime /* expirationTime */) + @RunWith(AndroidJUnit4::class) @SmallTest class TetheredClientTest { 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/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java index 948266d3cf50..3106e0e5e1c6 100644 --- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java +++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java @@ -21,7 +21,7 @@ import static android.net.TetheringManager.TETHERING_BLUETOOTH; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHERING_WIFI_P2P; -import static android.net.TetheringManager.TETHER_ERROR_ENABLE_NAT_ERROR; +import static android.net.TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR; import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; import static android.net.TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR; import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; @@ -448,7 +448,7 @@ public class IpServerTest { usbTeardownOrder.verify(mNetd, times(2)).interfaceSetCfg( argThat(cfg -> IFACE_NAME.equals(cfg.ifName))); usbTeardownOrder.verify(mCallback).updateInterfaceState( - mIpServer, STATE_AVAILABLE, TETHER_ERROR_ENABLE_NAT_ERROR); + mIpServer, STATE_AVAILABLE, TETHER_ERROR_ENABLE_FORWARDING_ERROR); usbTeardownOrder.verify(mCallback).updateLinkProperties( eq(mIpServer), mLinkPropertiesCaptor.capture()); assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue()); diff --git a/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java b/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java new file mode 100644 index 000000000000..1499f3be224e --- /dev/null +++ b/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.net.util; + +import static android.net.TetheringManager.TETHERING_USB; +import static android.net.TetheringManager.TETHERING_WIFI; + +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +import android.net.LinkAddress; +import android.net.TetheringRequestParcel; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.testutils.MiscAssertsKt; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class TetheringUtilsTest { + private static final LinkAddress TEST_SERVER_ADDR = new LinkAddress("192.168.43.1/24"); + private static final LinkAddress TEST_CLIENT_ADDR = new LinkAddress("192.168.43.5/24"); + private TetheringRequestParcel mTetheringRequest; + + @Before + public void setUp() { + mTetheringRequest = makeTetheringRequestParcel(); + } + + public TetheringRequestParcel makeTetheringRequestParcel() { + final TetheringRequestParcel request = new TetheringRequestParcel(); + request.tetheringType = TETHERING_WIFI; + request.localIPv4Address = TEST_SERVER_ADDR; + request.staticClientAddress = TEST_CLIENT_ADDR; + request.exemptFromEntitlementCheck = false; + request.showProvisioningUi = true; + return request; + } + + @Test + public void testIsTetheringRequestEquals() throws Exception { + TetheringRequestParcel request = makeTetheringRequestParcel(); + + assertTrue(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, mTetheringRequest)); + assertTrue(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request)); + assertTrue(TetheringUtils.isTetheringRequestEquals(null, null)); + assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, null)); + assertFalse(TetheringUtils.isTetheringRequestEquals(null, mTetheringRequest)); + + request = makeTetheringRequestParcel(); + request.tetheringType = TETHERING_USB; + assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request)); + + request = makeTetheringRequestParcel(); + request.localIPv4Address = null; + request.staticClientAddress = null; + assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request)); + + request = makeTetheringRequestParcel(); + request.exemptFromEntitlementCheck = true; + assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request)); + + request = makeTetheringRequestParcel(); + request.showProvisioningUi = false; + assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request)); + + MiscAssertsKt.assertFieldCountEquals(5, TetheringRequestParcel.class); + } +} diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt index 56f3e21cbffe..1cdc3bbb9933 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt @@ -46,23 +46,28 @@ class ConnectedClientsTrackerTest { private val client1Addr = MacAddress.fromString("01:23:45:67:89:0A") private val client1 = TetheredClient(client1Addr, listOf( - AddressInfo(LinkAddress("192.168.43.44/32"), null /* hostname */, clock.time + 20)), + makeAddrInfo("192.168.43.44/32", null /* hostname */, clock.time + 20)), TETHERING_WIFI) private val wifiClient1 = makeWifiClient(client1Addr) private val client2Addr = MacAddress.fromString("02:34:56:78:90:AB") - private val client2Exp30AddrInfo = AddressInfo( - LinkAddress("192.168.43.45/32"), "my_hostname", clock.time + 30) + private val client2Exp30AddrInfo = makeAddrInfo( + "192.168.43.45/32", "my_hostname", clock.time + 30) private val client2 = TetheredClient(client2Addr, listOf( client2Exp30AddrInfo, - AddressInfo(LinkAddress("2001:db8:12::34/72"), "other_hostname", clock.time + 10)), + makeAddrInfo("2001:db8:12::34/72", "other_hostname", clock.time + 10)), TETHERING_WIFI) private val wifiClient2 = makeWifiClient(client2Addr) private val client3Addr = MacAddress.fromString("03:45:67:89:0A:BC") private val client3 = TetheredClient(client3Addr, - listOf(AddressInfo(LinkAddress("2001:db8:34::34/72"), "other_other_hostname", - clock.time + 10)), + listOf(makeAddrInfo("2001:db8:34::34/72", "other_other_hostname", clock.time + 10)), TETHERING_USB) + private fun makeAddrInfo(addr: String, hostname: String?, expTime: Long) = + LinkAddress(addr).let { + AddressInfo(LinkAddress(it.address, it.prefixLength, it.flags, it.scope, + expTime /* deprecationTime */, expTime /* expirationTime */), hostname) + } + @Test fun testUpdateConnectedClients() { doReturn(emptyList<TetheredClient>()).`when`(server1).allLeases diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java index 3a1d4a61a39e..0a7850b68014 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java @@ -21,7 +21,7 @@ import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN; import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; -import static android.net.TetheringManager.TETHER_ERROR_PROVISION_FAILED; +import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED; import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; @@ -284,11 +284,11 @@ public final class EntitlementManagerTest { assertEquals(0, mEnMgr.uiProvisionCount); mEnMgr.reset(); // 3. No cache value and ui entitlement check is needed. - mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED; receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - assertEquals(TETHER_ERROR_PROVISION_FAILED, resultCode); + assertEquals(TETHER_ERROR_PROVISIONING_FAILED, resultCode); mCallbacklatch.countDown(); } }; @@ -297,12 +297,13 @@ public final class EntitlementManagerTest { callbackTimeoutHelper(mCallbacklatch); assertEquals(1, mEnMgr.uiProvisionCount); mEnMgr.reset(); - // 4. Cache value is TETHER_ERROR_PROVISION_FAILED and don't need to run entitlement check. + // 4. Cache value is TETHER_ERROR_PROVISIONING_FAILED and don't need to run entitlement + // check. mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - assertEquals(TETHER_ERROR_PROVISION_FAILED, resultCode); + assertEquals(TETHER_ERROR_PROVISIONING_FAILED, resultCode); mCallbacklatch.countDown(); } }; @@ -311,7 +312,7 @@ public final class EntitlementManagerTest { callbackTimeoutHelper(mCallbacklatch); assertEquals(0, mEnMgr.uiProvisionCount); mEnMgr.reset(); - // 5. Cache value is TETHER_ERROR_PROVISION_FAILED and ui entitlement check is needed. + // 5. Cache value is TETHER_ERROR_PROVISIONING_FAILED and ui entitlement check is needed. mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; receiver = new ResultReceiver(null) { @Override @@ -364,7 +365,7 @@ public final class EntitlementManagerTest { public void verifyPermissionResult() { setupForRequiredProvisioning(); mEnMgr.notifyUpstream(true); - mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED; mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); mLooper.dispatchAll(); assertFalse(mEnMgr.isCellularUpstreamPermitted()); @@ -380,15 +381,15 @@ public final class EntitlementManagerTest { public void verifyPermissionIfAllNotApproved() { setupForRequiredProvisioning(); mEnMgr.notifyUpstream(true); - mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED; mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); mLooper.dispatchAll(); assertFalse(mEnMgr.isCellularUpstreamPermitted()); - mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED; mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true); mLooper.dispatchAll(); assertFalse(mEnMgr.isCellularUpstreamPermitted()); - mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED; mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true); mLooper.dispatchAll(); assertFalse(mEnMgr.isCellularUpstreamPermitted()); @@ -403,7 +404,7 @@ public final class EntitlementManagerTest { mLooper.dispatchAll(); assertTrue(mEnMgr.isCellularUpstreamPermitted()); mLooper.dispatchAll(); - mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED; mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true); mLooper.dispatchAll(); assertTrue(mEnMgr.isCellularUpstreamPermitted()); @@ -465,7 +466,7 @@ public final class EntitlementManagerTest { assertEquals(0, mEnMgr.silentProvisionCount); mEnMgr.reset(); // 6. switch upstream back to mobile again - mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED; mEnMgr.notifyUpstream(true); mLooper.dispatchAll(); assertEquals(0, mEnMgr.uiProvisionCount); @@ -477,7 +478,7 @@ public final class EntitlementManagerTest { public void testCallStopTetheringWhenUiProvisioningFail() { setupForRequiredProvisioning(); verify(mEntitlementFailedListener, times(0)).onUiEntitlementFailed(TETHERING_WIFI); - mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED; mEnMgr.notifyUpstream(true); mLooper.dispatchAll(); mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java index 7e62e5aca993..fe840864fb99 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java @@ -33,6 +33,8 @@ import static com.android.testutils.MiscAssertsKt.assertContainsAll; import static com.android.testutils.MiscAssertsKt.assertThrows; import static com.android.testutils.NetworkStatsUtilsKt.orderInsensitiveEquals; +import static junit.framework.Assert.assertNotNull; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; @@ -61,8 +63,7 @@ import android.net.LinkProperties; import android.net.NetworkStats; import android.net.NetworkStats.Entry; import android.net.RouteInfo; -import android.net.netstats.provider.AbstractNetworkStatsProvider; -import android.net.netstats.provider.NetworkStatsProviderCallback; +import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.util.SharedLog; import android.os.Handler; import android.os.Looper; @@ -108,12 +109,10 @@ public class OffloadControllerTest { @Mock private ApplicationInfo mApplicationInfo; @Mock private Context mContext; @Mock private NetworkStatsManager mStatsManager; - @Mock private NetworkStatsProviderCallback mTetherStatsProviderCb; + @Mock private INetworkStatsProviderCallback mTetherStatsProviderCb; + private OffloadController.OffloadTetheringStatsProvider mTetherStatsProvider; private final ArgumentCaptor<ArrayList> mStringArrayCaptor = ArgumentCaptor.forClass(ArrayList.class); - private final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider> - mTetherStatsProviderCaptor = - ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class); private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor = ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class); private MockContentResolver mContentResolver; @@ -126,8 +125,6 @@ public class OffloadControllerTest { mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); when(mContext.getContentResolver()).thenReturn(mContentResolver); FakeSettingsProvider.clearSettingsProvider(); - when(mStatsManager.registerNetworkStatsProvider(anyString(), any())) - .thenReturn(mTetherStatsProviderCb); } @After public void tearDown() throws Exception { @@ -154,8 +151,14 @@ public class OffloadControllerTest { private OffloadController makeOffloadController() throws Exception { OffloadController offload = new OffloadController(new Handler(Looper.getMainLooper()), mHardware, mContentResolver, mStatsManager, new SharedLog("test")); + final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider> + tetherStatsProviderCaptor = + ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class); verify(mStatsManager).registerNetworkStatsProvider(anyString(), - mTetherStatsProviderCaptor.capture()); + tetherStatsProviderCaptor.capture()); + mTetherStatsProvider = tetherStatsProviderCaptor.getValue(); + assertNotNull(mTetherStatsProvider); + mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb); return offload; } @@ -413,9 +416,6 @@ public class OffloadControllerTest { final OffloadController offload = makeOffloadController(); offload.start(); - final OffloadController.OffloadTetheringStatsProvider provider = - mTetherStatsProviderCaptor.getValue(); - final String ethernetIface = "eth1"; final String mobileIface = "rmnet_data0"; @@ -443,15 +443,15 @@ public class OffloadControllerTest { inOrder.verify(mHardware, times(1)).getForwardedStats(eq(mobileIface)); // Verify that the fetched stats are stored. - final NetworkStats ifaceStats = provider.getTetherStats(STATS_PER_IFACE); - final NetworkStats uidStats = provider.getTetherStats(STATS_PER_UID); + final NetworkStats ifaceStats = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE); + final NetworkStats uidStats = mTetherStatsProvider.getTetherStats(STATS_PER_UID); final NetworkStats expectedIfaceStats = new NetworkStats(0L, 2) - .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999)) - .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321)); + .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999)) + .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321)); final NetworkStats expectedUidStats = new NetworkStats(0L, 2) - .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999)) - .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321)); + .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999)) + .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321)); assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStats)); assertTrue(orderInsensitiveEquals(expectedUidStats, uidStats)); @@ -462,13 +462,12 @@ public class OffloadControllerTest { NetworkStats.class); // Force pushing stats update to verify the stats reported. - provider.pushTetherStats(); - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), - ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); + mTetherStatsProvider.pushTetherStats(); + verify(mTetherStatsProviderCb, times(1)) + .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStatsCaptor.getValue())); assertTrue(orderInsensitiveEquals(expectedUidStats, uidStatsCaptor.getValue())); - when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn( new ForwardedStats(100000, 100000)); offload.setUpstreamLinkProperties(null); @@ -483,31 +482,31 @@ public class OffloadControllerTest { inOrder.verifyNoMoreInteractions(); // Verify that the stored stats is accumulated. - final NetworkStats ifaceStatsAccu = provider.getTetherStats(STATS_PER_IFACE); - final NetworkStats uidStatsAccu = provider.getTetherStats(STATS_PER_UID); + final NetworkStats ifaceStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE); + final NetworkStats uidStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_UID); final NetworkStats expectedIfaceStatsAccu = new NetworkStats(0L, 2) - .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999)) - .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321)); + .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999)) + .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321)); final NetworkStats expectedUidStatsAccu = new NetworkStats(0L, 2) - .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999)) - .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321)); + .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999)) + .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321)); assertTrue(orderInsensitiveEquals(expectedIfaceStatsAccu, ifaceStatsAccu)); assertTrue(orderInsensitiveEquals(expectedUidStatsAccu, uidStatsAccu)); // Verify that only diff of stats is reported. reset(mTetherStatsProviderCb); - provider.pushTetherStats(); + mTetherStatsProvider.pushTetherStats(); final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2) - .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0)) - .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000)); + .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0)) + .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000)); final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2) - .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0)) - .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000)); - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), - ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); + .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0)) + .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000)); + verify(mTetherStatsProviderCb, times(1)) + .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); assertTrue(orderInsensitiveEquals(expectedIfaceStatsDiff, ifaceStatsCaptor.getValue())); assertTrue(orderInsensitiveEquals(expectedUidStatsDiff, uidStatsCaptor.getValue())); } @@ -529,19 +528,18 @@ public class OffloadControllerTest { lp.setInterfaceName(ethernetIface); offload.setUpstreamLinkProperties(lp); - AbstractNetworkStatsProvider provider = mTetherStatsProviderCaptor.getValue(); final InOrder inOrder = inOrder(mHardware); when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(true); when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(true); // Applying an interface quota to the current upstream immediately sends it to the hardware. - provider.setLimit(ethernetIface, ethernetLimit); + mTetherStatsProvider.onSetLimit(ethernetIface, ethernetLimit); waitForIdle(); inOrder.verify(mHardware).setDataLimit(ethernetIface, ethernetLimit); inOrder.verifyNoMoreInteractions(); // Applying an interface quota to another upstream does not take any immediate action. - provider.setLimit(mobileIface, mobileLimit); + mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit); waitForIdle(); inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong()); @@ -554,7 +552,7 @@ public class OffloadControllerTest { // Setting a limit of ITetheringStatsProvider.QUOTA_UNLIMITED causes the limit to be set // to Long.MAX_VALUE. - provider.setLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED); + mTetherStatsProvider.onSetLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED); waitForIdle(); inOrder.verify(mHardware).setDataLimit(mobileIface, Long.MAX_VALUE); @@ -562,7 +560,7 @@ public class OffloadControllerTest { when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(false); lp.setInterfaceName(ethernetIface); offload.setUpstreamLinkProperties(lp); - provider.setLimit(mobileIface, mobileLimit); + mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit); waitForIdle(); inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong()); @@ -571,7 +569,7 @@ public class OffloadControllerTest { when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(false); lp.setInterfaceName(mobileIface); offload.setUpstreamLinkProperties(lp); - provider.setLimit(mobileIface, mobileLimit); + mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit); waitForIdle(); inOrder.verify(mHardware).getForwardedStats(ethernetIface); inOrder.verify(mHardware).stopOffloadControl(); @@ -587,7 +585,7 @@ public class OffloadControllerTest { OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue(); callback.onStoppedLimitReached(); - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any()); + verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any()); } @Test @@ -691,7 +689,7 @@ public class OffloadControllerTest { verify(mHardware, times(1)).getForwardedStats(eq(RMNET0)); verify(mHardware, times(1)).getForwardedStats(eq(WLAN0)); // TODO: verify the exact stats reported. - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any()); + verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any()); verifyNoMoreInteractions(mTetherStatsProviderCb); verifyNoMoreInteractions(mHardware); } @@ -756,7 +754,7 @@ public class OffloadControllerTest { // Verify forwarded stats behaviour. verify(mHardware, times(1)).getForwardedStats(eq(RMNET0)); verify(mHardware, times(1)).getForwardedStats(eq(WLAN0)); - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any()); + verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any()); verifyNoMoreInteractions(mTetherStatsProviderCb); // TODO: verify local prefixes and downstreams are also pushed to the HAL. 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 2f7c88aec787..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; @@ -82,6 +83,7 @@ import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import android.net.EthernetManager; import android.net.EthernetManager.TetheredInterfaceRequest; +import android.net.IIntResultListener; import android.net.INetd; import android.net.ITetheringEventCallback; import android.net.InetAddresses; @@ -209,7 +211,6 @@ public class TetheringTest { private PhoneStateListener mPhoneStateListener; private InterfaceConfigurationParcel mInterfaceConfiguration; - private class TestContext extends BroadcastInterceptingContext { TestContext(Context base) { super(base); @@ -484,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 = @@ -499,10 +501,16 @@ public class TetheringTest { return new Tethering(mTetheringDependencies); } - private TetheringRequestParcel createTetheringRquestParcel(final int type) { + private TetheringRequestParcel createTetheringRequestParcel(final int type) { + return createTetheringRequestParcel(type, null, null); + } + + private TetheringRequestParcel createTetheringRequestParcel(final int type, + final LinkAddress serverAddr, final LinkAddress clientAddr) { final TetheringRequestParcel request = new TetheringRequestParcel(); request.tetheringType = type; - request.localIPv4Address = null; + request.localIPv4Address = serverAddr; + request.staticClientAddress = clientAddr; request.exemptFromEntitlementCheck = false; request.showProvisioningUi = false; @@ -616,7 +624,7 @@ public class TetheringTest { private void prepareNcmTethering() { // Emulate startTethering(TETHERING_NCM) called - mTethering.startTethering(createTetheringRquestParcel(TETHERING_NCM), null); + mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), null); mLooper.dispatchAll(); verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM); @@ -629,7 +637,7 @@ public class TetheringTest { .thenReturn(upstreamState); // Emulate pressing the USB tethering button in Settings UI. - mTethering.startTethering(createTetheringRquestParcel(TETHERING_USB), null); + mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null); mLooper.dispatchAll(); verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); @@ -903,7 +911,7 @@ public class TetheringTest { when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); // Emulate pressing the WiFi tethering button. - mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null); + mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); mLooper.dispatchAll(); verify(mWifiManager, times(1)).startSoftAp(null); verifyNoMoreInteractions(mWifiManager); @@ -931,7 +939,7 @@ public class TetheringTest { when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); // Emulate pressing the WiFi tethering button. - mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null); + mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); mLooper.dispatchAll(); verify(mWifiManager, times(1)).startSoftAp(null); verifyNoMoreInteractions(mWifiManager); @@ -1008,7 +1016,7 @@ public class TetheringTest { doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME); // Emulate pressing the WiFi tethering button. - mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null); + mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); mLooper.dispatchAll(); verify(mWifiManager, times(1)).startSoftAp(null); verifyNoMoreInteractions(mWifiManager); @@ -1066,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 @@ -1080,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); @@ -1303,7 +1313,7 @@ public class TetheringTest { tetherState = callback.pollTetherStatesChanged(); assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME}); - mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null); + mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); mLooper.dispatchAll(); tetherState = callback.pollTetherStatesChanged(); @@ -1392,16 +1402,17 @@ public class TetheringTest { mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration(); assertEquals(fakeSubId, newConfig.activeDataSubId); + verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId)); } @Test public void testNoDuplicatedEthernetRequest() throws Exception { final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class); when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest); - mTethering.startTethering(createTetheringRquestParcel(TETHERING_ETHERNET), null); + mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null); mLooper.dispatchAll(); verify(mEm, times(1)).requestTetheredInterface(any(), any()); - mTethering.startTethering(createTetheringRquestParcel(TETHERING_ETHERNET), null); + mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null); mLooper.dispatchAll(); verifyNoMoreInteractions(mEm); mTethering.stopTethering(TETHERING_ETHERNET); @@ -1580,6 +1591,93 @@ public class TetheringTest { assertTrue(element + " not found in " + collection, collection.contains(element)); } + private class ResultListener extends IIntResultListener.Stub { + private final int mExpectedResult; + private boolean mHasResult = false; + ResultListener(final int expectedResult) { + mExpectedResult = expectedResult; + } + + @Override + public void onResult(final int resultCode) { + mHasResult = true; + if (resultCode != mExpectedResult) { + fail("expected result: " + mExpectedResult + " but actual result: " + resultCode); + } + } + + public void assertHasResult() { + if (!mHasResult) fail("No callback result"); + } + } + + @Test + public void testMultipleStartTethering() 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"; + final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR); + final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR); + final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR); + + // Enable USB tethering and check that Tethering starts USB. + mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, + null, null), firstResult); + mLooper.dispatchAll(); + firstResult.assertHasResult(); + verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); + verifyNoMoreInteractions(mUsbManager); + + // Enable USB tethering again with the same request and expect no change to USB. + mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, + null, null), secondResult); + mLooper.dispatchAll(); + secondResult.assertHasResult(); + verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE); + reset(mUsbManager); + + // Enable USB tethering with a different request and expect that USB is stopped and + // started. + mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, + serverLinkAddr, clientLinkAddr), thirdResult); + mLooper.dispatchAll(); + thirdResult.assertHasResult(); + verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); + verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); + + // Expect that when USB comes up, the DHCP server is configured with the requested address. + mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true); + sendUsbBroadcast(true, true, true, TETHERING_USB); + mLooper.dispatchAll(); + verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( + any(), any()); + verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); + } + + @Test + 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(); + verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); + mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true); + sendUsbBroadcast(true, true, true, TETHERING_USB); + mLooper.dispatchAll(); + verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); + 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 // already operating tethering mode interface. } diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java index 5ed75bf26f8b..7c98f626a4d2 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java @@ -212,8 +212,8 @@ public class UpstreamNetworkMonitorTest { mUNM.updateMobileRequiresDun(true); mUNM.registerMobileNetworkRequest(); verify(mCM, times(1)).requestNetwork( - any(NetworkRequest.class), any(NetworkCallback.class), anyInt(), anyInt(), - any(Handler.class)); + any(NetworkRequest.class), anyInt(), anyInt(), any(Handler.class), + any(NetworkCallback.class)); assertTrue(mUNM.mobileNetworkRequested()); assertUpstreamTypeRequested(TYPE_MOBILE_DUN); @@ -649,8 +649,8 @@ public class UpstreamNetworkMonitorTest { } @Override - public void requestNetwork(NetworkRequest req, NetworkCallback cb, - int timeoutMs, int legacyType, Handler h) { + public void requestNetwork(NetworkRequest req, + int timeoutMs, int legacyType, Handler h, NetworkCallback cb) { assertFalse(allCallbacks.containsKey(cb)); allCallbacks.put(cb, h); assertFalse(requested.containsKey(cb)); diff --git a/services/Android.bp b/services/Android.bp index 5019bb173cd5..90f98e2bd7a6 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -72,11 +72,7 @@ java_library { libs: [ "android.hidl.manager-V1.0-java", - "framework-tethering-stubs", - ], - - plugins: [ - "compat-changeid-annotation-processor", + "framework-tethering-stubs-module_libs_api", ], // Uncomment to enable output of certain warnings (deprecated, unchecked) @@ -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 123c5d5622cd..7a3a910c0447 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -28,9 +28,9 @@ java_library_static { "android.hardware.power-V1.0-java", "android.hardware.tv.cec-V1.0-java", "android.hardware.vibrator-java", + "android.net.ipsec.ike.stubs.module_libs_api", "app-compat-annotations", - "framework-tethering-stubs", - "ike-stubs", + "framework-tethering-stubs-module_libs_api", ], required: [ @@ -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 fae14fe707e0..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; @@ -112,6 +113,7 @@ import android.net.NetworkWatchlistManager; import android.net.PrivateDnsConfigParcel; import android.net.ProxyInfo; import android.net.RouteInfo; +import android.net.RouteInfoParcel; import android.net.SocketKeepalive; import android.net.TetheringManager; import android.net.UidRange; @@ -122,6 +124,7 @@ import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; import android.net.shared.PrivateDnsConfig; +import android.net.util.LinkPropertiesUtils.CompareOrUpdateResult; import android.net.util.LinkPropertiesUtils.CompareResult; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; @@ -275,9 +278,6 @@ public class ConnectivityService extends IConnectivityManager.Stub // connect anyway?" dialog after the user selects a network that doesn't validate. private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000; - // How long to dismiss network notification. - private static final int TIMEOUT_NOTIFICATION_DELAY_MS = 20 * 1000; - // Default to 30s linger time-out. Modifiable only for testing. private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger"; private static final int DEFAULT_LINGER_DELAY_MS = 30_000; @@ -525,18 +525,13 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final int EVENT_PROVISIONING_NOTIFICATION = 43; /** - * This event can handle dismissing notification by given network id. - */ - private static final int EVENT_TIMEOUT_NOTIFICATION = 44; - - /** * Used to specify whether a network should be used even if connectivity is partial. * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for * false) * arg2 = whether to remember this choice in the future (1 for true or 0 for false) * obj = network */ - private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 45; + private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44; /** * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed. @@ -545,7 +540,7 @@ public class ConnectivityService extends IConnectivityManager.Stub * arg1 = A bitmask to describe which probes are completed. * arg2 = A bitmask to describe which probes are successful. */ - public static final int EVENT_PROBE_STATUS_CHANGED = 46; + public static final int EVENT_PROBE_STATUS_CHANGED = 45; /** * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed. @@ -553,7 +548,7 @@ public class ConnectivityService extends IConnectivityManager.Stub * arg2 = netId * obj = captive portal data */ - private static final int EVENT_CAPPORT_DATA_CHANGED = 47; + private static final int EVENT_CAPPORT_DATA_CHANGED = 46; /** * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification @@ -933,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"); } @@ -962,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); @@ -995,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; @@ -1676,7 +1671,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (newNc.getNetworkSpecifier() != null) { newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact()); } - newNc.setAdministratorUids(Collections.EMPTY_LIST); + newNc.setAdministratorUids(new int[0]); return newNc; } @@ -1720,7 +1715,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } if (checkSettingsPermission(callerPid, callerUid)) { - return lp.makeSensitiveFieldsParcelingCopy(); + return new LinkProperties(lp, true /* parcelSensitiveFields */); } final LinkProperties newLp = new LinkProperties(lp); @@ -1737,7 +1732,7 @@ public class ConnectivityService extends IConnectivityManager.Stub nc.setSingleUid(callerUid); } nc.setRequestorUidAndPackageName(callerUid, callerPackageName); - nc.setAdministratorUids(Collections.EMPTY_LIST); + nc.setAdministratorUids(new int[0]); // Clear owner UID; this can never come from an app. nc.setOwnerUid(INVALID_UID); @@ -2238,14 +2233,9 @@ public class ConnectivityService extends IConnectivityManager.Stub if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { final NetworkInfo ni = intent.getParcelableExtra( ConnectivityManager.EXTRA_NETWORK_INFO); - if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) { - intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - } else { - BroadcastOptions opts = BroadcastOptions.makeBasic(); - opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); - options = opts.toBundle(); - } + final BroadcastOptions opts = BroadcastOptions.makeBasic(); + opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M); + options = opts.toBundle(); final IBatteryStats bs = mDeps.getBatteryStatsService(); try { bs.noteConnectivityChanged(intent.getIntExtra( @@ -2706,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; } @@ -2870,13 +2868,6 @@ public class ConnectivityService extends IConnectivityManager.Stub final boolean valid = ((testResult & NETWORK_VALIDATION_RESULT_VALID) != 0); final boolean wasValidated = nai.lastValidated; final boolean wasDefault = isDefaultNetwork(nai); - // Only show a connected notification if the network is pending validation - // after the captive portal app was open, and it has now validated. - if (nai.captivePortalValidationPending && valid) { - // User is now logged in, network validated. - nai.captivePortalValidationPending = false; - showNetworkNotification(nai, NotificationType.LOGGED_IN); - } if (DBG) { final String logMsg = !TextUtils.isEmpty(redirectUrl) @@ -3757,12 +3748,6 @@ public class ConnectivityService extends IConnectivityManager.Stub new CaptivePortal(new CaptivePortalImpl(network).asBinder())); appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); - // This runs on a random binder thread, but getNetworkAgentInfoForNetwork is thread-safe, - // and captivePortalValidationPending is volatile. - final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); - if (nai != null) { - nai.captivePortalValidationPending = true; - } Binder.withCleanCallingIdentity(() -> mContext.startActivityAsUser(appIntent, UserHandle.CURRENT)); } @@ -3881,14 +3866,6 @@ public class ConnectivityService extends IConnectivityManager.Stub final String action; final boolean highPriority; switch (type) { - case LOGGED_IN: - action = Settings.ACTION_WIFI_SETTINGS; - mHandler.removeMessages(EVENT_TIMEOUT_NOTIFICATION); - mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NOTIFICATION, - nai.network.netId, 0), TIMEOUT_NOTIFICATION_DELAY_MS); - // High priority because it is a direct result of the user logging in to a portal. - highPriority = true; - break; case NO_INTERNET: action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED; // High priority because it is only displayed for explicitly selected networks. @@ -3916,7 +3893,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } Intent intent = new Intent(action); - if (type != NotificationType.LOGGED_IN && type != NotificationType.PRIVATE_DNS_BROKEN) { + if (type != NotificationType.PRIVATE_DNS_BROKEN) { intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClassName("com.android.settings", @@ -4132,9 +4109,6 @@ public class ConnectivityService extends IConnectivityManager.Stub case EVENT_DATA_SAVER_CHANGED: handleRestrictBackgroundChanged(toBool(msg.arg1)); break; - case EVENT_TIMEOUT_NOTIFICATION: - mNotifier.clearNotification(msg.arg1, NotificationType.LOGGED_IN); - break; } } } @@ -5358,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"); } @@ -5423,10 +5397,26 @@ 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()) { + 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) ? NetworkRequest.Type.TRACK_DEFAULT @@ -5530,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); @@ -5559,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)); } @@ -5618,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(); @@ -5803,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(); @@ -5818,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 { @@ -5976,15 +5975,49 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + // TODO: move to frameworks/libs/net. + private RouteInfoParcel convertRouteInfo(RouteInfo route) { + final String nextHop; + + switch (route.getType()) { + case RouteInfo.RTN_UNICAST: + if (route.hasGateway()) { + nextHop = route.getGateway().getHostAddress(); + } else { + nextHop = INetd.NEXTHOP_NONE; + } + break; + case RouteInfo.RTN_UNREACHABLE: + nextHop = INetd.NEXTHOP_UNREACHABLE; + break; + case RouteInfo.RTN_THROW: + nextHop = INetd.NEXTHOP_THROW; + break; + default: + nextHop = INetd.NEXTHOP_NONE; + break; + } + + final RouteInfoParcel rip = new RouteInfoParcel(); + rip.ifName = route.getInterface(); + rip.destination = route.getDestination().toString(); + rip.nextHop = nextHop; + rip.mtu = route.getMtu(); + + return rip; + } + /** * Have netd update routes from oldLp to newLp. * @return true if routes changed between oldLp and newLp */ private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) { - // Compare the route diff to determine which routes should be added and removed. - CompareResult<RouteInfo> routeDiff = new CompareResult<>( - oldLp != null ? oldLp.getAllRoutes() : null, - newLp != null ? newLp.getAllRoutes() : null); + // compare the route diff to determine which routes have been updated + 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 @@ -5993,10 +6026,10 @@ public class ConnectivityService extends IConnectivityManager.Stub if (route.hasGateway()) continue; if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); try { - mNMS.addRoute(netId, route); + mNetd.networkAddRouteParcel(netId, convertRouteInfo(route)); } catch (Exception e) { if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) { - loge("Exception in addRoute for non-gateway: " + e); + loge("Exception in networkAddRouteParcel for non-gateway: " + e); } } } @@ -6004,10 +6037,10 @@ public class ConnectivityService extends IConnectivityManager.Stub if (!route.hasGateway()) continue; if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId); try { - mNMS.addRoute(netId, route); + mNetd.networkAddRouteParcel(netId, convertRouteInfo(route)); } catch (Exception e) { if ((route.getGateway() instanceof Inet4Address) || VDBG) { - loge("Exception in addRoute for gateway: " + e); + loge("Exception in networkAddRouteParcel for gateway: " + e); } } } @@ -6015,12 +6048,22 @@ public class ConnectivityService extends IConnectivityManager.Stub for (RouteInfo route : routeDiff.removed) { if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId); try { - mNMS.removeRoute(netId, route); + mNetd.networkRemoveRouteParcel(netId, convertRouteInfo(route)); } catch (Exception e) { - loge("Exception in removeRoute: " + e); + loge("Exception in networkRemoveRouteParcel: " + e); } } - return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty(); + + for (RouteInfo route : routeDiff.updated) { + if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId); + try { + mNetd.networkUpdateRouteParcel(netId, convertRouteInfo(route)); + } catch (Exception e) { + loge("Exception in networkUpdateRouteParcel: " + e); + } + } + return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty() + || !routeDiff.updated.isEmpty(); } private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) { @@ -7842,7 +7885,7 @@ public class ConnectivityService extends IConnectivityManager.Stub getMatchingPermissionedCallbacks(nai); for (final IConnectivityDiagnosticsCallback cb : results) { try { - cb.onConnectivityReport(report); + cb.onConnectivityReportAvailable(report); } catch (RemoteException ex) { loge("Error invoking onConnectivityReport", ex); } @@ -7889,7 +7932,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private void clearNetworkCapabilitiesUids(@NonNull NetworkCapabilities nc) { nc.setUids(null); - nc.setAdministratorUids(Collections.EMPTY_LIST); + nc.setAdministratorUids(new int[0]); nc.setOwnerUid(Process.INVALID_UID); } @@ -7917,20 +7960,31 @@ public class ConnectivityService extends IConnectivityManager.Stub return true; } - if (!mLocationPermissionChecker.checkLocationPermission( - callbackPackageName, null /* featureId */, callbackUid, null /* message */)) { + // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid + // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the + // call in a try-catch. + try { + if (!mLocationPermissionChecker.checkLocationPermission( + callbackPackageName, null /* featureId */, callbackUid, null /* message */)) { + return false; + } + } catch (SecurityException e) { return false; } + final Network[] underlyingNetworks; synchronized (mVpns) { - if (getVpnIfOwner(callbackUid) != null) { - return true; - } + final Vpn vpn = getVpnIfOwner(callbackUid); + underlyingNetworks = (vpn == null) ? null : vpn.getUnderlyingNetworks(); + } + if (underlyingNetworks != null) { + if (Arrays.asList(underlyingNetworks).contains(nai.network)) return true; } // Administrator UIDs also contains the Owner UID - if (nai.networkCapabilities.getAdministratorUids().contains(callbackUid)) { - return true; + final int[] administratorUids = nai.networkCapabilities.getAdministratorUids(); + for (final int uid : administratorUids) { + if (uid == callbackUid) return true; } return false; 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/OWNERS b/services/core/java/com/android/server/OWNERS index 76e0c137d2f5..8099f8f37bc7 100644 --- a/services/core/java/com/android/server/OWNERS +++ b/services/core/java/com/android/server/OWNERS @@ -1,5 +1,5 @@ # Connectivity / Networking -per-file ConnectivityService.java,NetworkManagementService.java,NsdService.java = codewiz@google.com, ek@google.com, jchalard@google.com, lorenzo@google.com, reminv@google.com, satk@google.com +per-file ConnectivityService.java,NetworkManagementService.java,NsdService.java = codewiz@google.com, ek@google.com, jchalard@google.com, junyulai@google.com, lorenzo@google.com, reminv@google.com, satk@google.com # Vibrator / Threads per-file VibratorService.java, DisplayThread.java = michaelwr@google.com 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 f45d54dda620..ac897e464659 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -45,6 +45,7 @@ import android.telephony.Annotation; import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SrvccState; +import android.telephony.BarringInfo; import android.telephony.CallAttributes; import android.telephony.CallQuality; import android.telephony.CellIdentity; @@ -167,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) + "}"; } } @@ -258,6 +258,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private int[] mCallPreciseDisconnectCause; + private List<BarringInfo> mBarringInfo = null; + private boolean mCarrierNetworkChangeState = false; private PhoneCapability mPhoneCapability = null; @@ -451,6 +453,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { cutListToSize(mCellInfo, mNumPhones); cutListToSize(mImsReasonInfo, mNumPhones); cutListToSize(mPreciseDataConnectionStates, mNumPhones); + cutListToSize(mBarringInfo, mNumPhones); return; } @@ -483,6 +486,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>()); mDisplayInfos[i] = null; + mBarringInfo.add(i, new BarringInfo()); } } @@ -541,6 +545,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mOutgoingCallEmergencyNumber = new EmergencyNumber[numPhones]; mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones]; mDisplayInfos = new DisplayInfo[numPhones]; + mBarringInfo = new ArrayList<>(); for (int i = 0; i < numPhones; i++) { mCallState[i] = TelephonyManager.CALL_STATE_IDLE; mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; @@ -569,6 +574,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>()); mDisplayInfos[i] = null; + mBarringInfo.add(i, new BarringInfo()); } mAppOps = mContext.getSystemService(AppOpsManager.class); @@ -591,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) { @@ -645,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) { @@ -762,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); @@ -1031,6 +1037,19 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } + if ((events & PhoneStateListener.LISTEN_BARRING_INFO) != 0) { + BarringInfo barringInfo = mBarringInfo.get(phoneId); + BarringInfo biNoLocation = barringInfo != null + ? barringInfo.createLocationInfoSanitizedCopy() : null; + if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo); + try { + r.callback.onBarringInfoChanged( + checkFineLocationAccess(r, Build.VERSION_CODES.R) + ? barringInfo : biNoLocation); + } catch (RemoteException ex) { + remove(r.binder); + } + } } } } else { @@ -1518,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); } } } @@ -2207,6 +2224,52 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + /** + * Send a notification of changes to barring status to PhoneStateListener registrants. + * + * @param phoneId the phoneId + * @param subId the subId + * @param barringInfo a structure containing the complete updated barring info. + */ + public void notifyBarringInfoChanged(int phoneId, int subId, @NonNull BarringInfo barringInfo) { + if (!checkNotifyPermission("notifyBarringInfo()")) { + return; + } + if (barringInfo == null) { + log("Received null BarringInfo for subId=" + subId + ", phoneId=" + phoneId); + mBarringInfo.set(phoneId, new BarringInfo()); + return; + } + + synchronized (mRecords) { + if (validatePhoneId(phoneId)) { + mBarringInfo.set(phoneId, barringInfo); + // Barring info is non-null + BarringInfo biNoLocation = barringInfo.createLocationInfoSanitizedCopy(); + if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo); + for (Record r : mRecords) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_BARRING_INFO) + && idMatch(r.subId, subId, phoneId)) { + try { + if (DBG_LOC) { + log("notifyBarringInfo: mBarringInfo=" + + barringInfo + " r=" + r); + } + r.callback.onBarringInfoChanged( + checkFineLocationAccess(r, Build.VERSION_CODES.R) + ? barringInfo : biNoLocation); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } + } + handleRemoveListLocked(); + } + } + + @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); @@ -2247,6 +2310,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i)); pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]); pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]); + pw.println("mBarringInfo=" + mBarringInfo.get(i)); pw.decreaseIndent(); } pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState); @@ -2870,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/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java index 95ac900d0535..0ea73460e105 100644 --- a/services/core/java/com/android/server/TestNetworkService.java +++ b/services/core/java/com/android/server/TestNetworkService.java @@ -16,7 +16,8 @@ package com.android.server; -import static com.android.internal.util.Preconditions.checkNotNull; +import static android.net.TestNetworkManager.TEST_TAP_PREFIX; +import static android.net.TestNetworkManager.TEST_TUN_PREFIX; import android.annotation.NonNull; import android.annotation.Nullable; @@ -55,14 +56,13 @@ import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.ArrayList; +import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; /** @hide */ class TestNetworkService extends ITestNetworkManager.Stub { @NonNull private static final String TAG = TestNetworkService.class.getSimpleName(); @NonNull private static final String TEST_NETWORK_TYPE = "TEST_NETWORK"; - @NonNull private static final String TEST_TUN_PREFIX = "testtun"; - @NonNull private static final String TEST_TAP_PREFIX = "testtap"; @NonNull private static final AtomicInteger sTestTunIndex = new AtomicInteger(); @NonNull private final Context mContext; @@ -82,9 +82,9 @@ class TestNetworkService extends ITestNetworkManager.Stub { mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); - mContext = checkNotNull(context, "missing Context"); - mNMS = checkNotNull(netManager, "missing INetworkManagementService"); - mNetd = checkNotNull(NetdService.getInstance(), "could not get netd instance"); + mContext = Objects.requireNonNull(context, "missing Context"); + mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService"); + mNetd = Objects.requireNonNull(NetdService.getInstance(), "could not get netd instance"); } /** @@ -96,7 +96,7 @@ class TestNetworkService extends ITestNetworkManager.Stub { private TestNetworkInterface createInterface(boolean isTun, LinkAddress[] linkAddrs) { enforceTestNetworkPermissions(mContext); - checkNotNull(linkAddrs, "missing linkAddrs"); + Objects.requireNonNull(linkAddrs, "missing linkAddrs"); String ifacePrefix = isTun ? TEST_TUN_PREFIX : TEST_TAP_PREFIX; String iface = ifacePrefix + sTestTunIndex.getAndIncrement(); @@ -231,10 +231,11 @@ class TestNetworkService extends ITestNetworkManager.Stub { @Nullable LinkProperties lp, boolean isMetered, int callingUid, + @NonNull int[] administratorUids, @NonNull IBinder binder) throws RemoteException, SocketException { - checkNotNull(looper, "missing Looper"); - checkNotNull(context, "missing Context"); + Objects.requireNonNull(looper, "missing Looper"); + Objects.requireNonNull(context, "missing Context"); // iface and binder validity checked by caller // Build network info with special testing type @@ -249,6 +250,7 @@ class TestNetworkService extends ITestNetworkManager.Stub { nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED); nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); nc.setNetworkSpecifier(new StringNetworkSpecifier(iface)); + nc.setAdministratorUids(administratorUids); if (!isMetered) { nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); } @@ -267,7 +269,7 @@ class TestNetworkService extends ITestNetworkManager.Stub { // Find the currently assigned addresses, and add them to LinkProperties boolean allowIPv4 = false, allowIPv6 = false; NetworkInterface netIntf = NetworkInterface.getByName(iface); - checkNotNull(netIntf, "No such network interface found: " + netIntf); + Objects.requireNonNull(netIntf, "No such network interface found: " + netIntf); for (InterfaceAddress intfAddr : netIntf.getInterfaceAddresses()) { lp.addLinkAddress( @@ -302,11 +304,12 @@ class TestNetworkService extends ITestNetworkManager.Stub { @NonNull String iface, @Nullable LinkProperties lp, boolean isMetered, + @NonNull int[] administratorUids, @NonNull IBinder binder) { enforceTestNetworkPermissions(mContext); - checkNotNull(iface, "missing Iface"); - checkNotNull(binder, "missing IBinder"); + Objects.requireNonNull(iface, "missing Iface"); + Objects.requireNonNull(binder, "missing IBinder"); if (!(iface.startsWith(INetd.IPSEC_INTERFACE_PREFIX) || iface.startsWith(TEST_TUN_PREFIX))) { @@ -336,6 +339,7 @@ class TestNetworkService extends ITestNetworkManager.Stub { lp, isMetered, callingUid, + administratorUids, binder); mTestNetworkTracker.put(agent.getNetwork().netId, agent); 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 068d6fc9dbf0..fc6d9f7b7849 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -672,7 +672,7 @@ public class AudioService extends IAudioService.Stub AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume; } else { AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = - (maxCallVolume * 3) / 4; + (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4; } int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1); @@ -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/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java index 7bdeb5969f1f..2e9818d15963 100644 --- a/services/core/java/com/android/server/compat/CompatChange.java +++ b/services/core/java/com/android/server/compat/CompatChange.java @@ -151,6 +151,15 @@ public final class CompatChange extends CompatibilityChangeInfo { return true; } + /** + * Checks whether a change has an override for a package. + * @param packageName name of the package + * @return true if there is such override + */ + boolean hasOverride(String packageName) { + return mPackageOverrides != null && mPackageOverrides.containsKey(packageName); + } + @Override public String toString() { StringBuilder sb = new StringBuilder("ChangeId(") diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index 33eeb8affaca..d3f4eb483aa2 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -242,11 +242,13 @@ final class CompatConfig { CompatChange c = mChanges.get(changeId); try { if (c != null) { - OverrideAllowedState allowedState = - mOverrideValidator.getOverrideAllowedState(changeId, packageName); - allowedState.enforce(changeId, packageName); - overrideExists = true; - c.removePackageOverride(packageName); + overrideExists = c.hasOverride(packageName); + if (overrideExists) { + OverrideAllowedState allowedState = + mOverrideValidator.getOverrideAllowedState(changeId, packageName); + allowedState.enforce(changeId, packageName); + c.removePackageOverride(packageName); + } } } catch (RemoteException e) { // Should never occur, since validator is in the same process. @@ -291,12 +293,14 @@ final class CompatConfig { for (int i = 0; i < mChanges.size(); ++i) { try { CompatChange change = mChanges.valueAt(i); - OverrideAllowedState allowedState = - mOverrideValidator.getOverrideAllowedState(change.getId(), - packageName); - allowedState.enforce(change.getId(), packageName); - if (change != null) { - mChanges.valueAt(i).removePackageOverride(packageName); + if (change.hasOverride(packageName)) { + OverrideAllowedState allowedState = + mOverrideValidator.getOverrideAllowedState(change.getId(), + packageName); + allowedState.enforce(change.getId(), packageName); + if (change != null) { + mChanges.valueAt(i).removePackageOverride(packageName); + } } } catch (RemoteException e) { // Should never occur, since validator is in the same process. diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 3e51ee71349d..470e1b18aaf5 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -28,6 +28,7 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Binder; +import android.os.Build; import android.os.RemoteException; import android.os.UserHandle; import android.util.Slog; @@ -43,6 +44,7 @@ import com.android.internal.util.DumpUtils; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Arrays; /** * System server internal API for gating and reporting compatibility changes. @@ -55,6 +57,9 @@ public class PlatformCompat extends IPlatformCompat.Stub { private final ChangeReporter mChangeReporter; private final CompatConfig mCompatConfig; + private static int sMinTargetSdk = Build.VERSION_CODES.P; + private static int sMaxTargetSdk = Build.VERSION_CODES.Q; + public PlatformCompat(Context context) { mContext = context; mChangeReporter = new ChangeReporter( @@ -219,6 +224,12 @@ public class PlatformCompat extends IPlatformCompat.Stub { return mCompatConfig.dumpChanges(); } + @Override + public CompatibilityChangeInfo[] listUIChanges() { + return Arrays.stream(listAllChanges()).filter( + x -> isShownInUI(x)).toArray(CompatibilityChangeInfo[]::new); + } + /** * Check whether the change is known to the compat config. * @@ -342,4 +353,17 @@ public class PlatformCompat extends IPlatformCompat.Stub { checkCompatChangeReadPermission(); checkCompatChangeLogPermission(); } + + private boolean isShownInUI(CompatibilityChangeInfo change) { + if (change.getLoggingOnly()) { + return false; + } + if (change.getEnableAfterTargetSdk() > 0) { + if (change.getEnableAfterTargetSdk() < sMinTargetSdk + || change.getEnableAfterTargetSdk() > sMaxTargetSdk) { + return false; + } + } + return true; + } } 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/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java index 04c792ae482b..d5488712aa34 100644 --- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java +++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java @@ -25,6 +25,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.WARNING_DISABLED; +import static android.net.NetworkTemplate.NETWORK_TYPE_ALL; import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; @@ -220,7 +221,7 @@ public class MultipathPolicyTracker { mNetworkTemplate = new NetworkTemplate( NetworkTemplate.MATCH_MOBILE, subscriberId, new String[] { subscriberId }, null, NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL, - NetworkStats.DEFAULT_NETWORK_NO); + NetworkStats.DEFAULT_NETWORK_NO, NETWORK_TYPE_ALL); mUsageCallback = new UsageCallback() { @Override public void onThresholdReached(int networkType, String subscriberId) { diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 23b954c03cf3..f844844cb15b 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -160,10 +160,6 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // Whether a captive portal was found during the last network validation attempt. public boolean lastCaptivePortalDetected; - // Indicates the captive portal app was opened to show a login UI to the user, but the network - // has not validated yet. - public volatile boolean captivePortalValidationPending; - // Set to true when partial connectivity was detected. public boolean partialConnectivity; @@ -625,23 +621,23 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { for (LingerTimer timer : mLingerTimers) { pw.println(timer); } } - // TODO: Print shorter members first and only print the boolean variable which value is true - // to improve readability. public String toString() { - return "NetworkAgentInfo{ ni{" + networkInfo + "} " - + "network{" + network + "} nethandle{" + network.getNetworkHandle() + "} " - + "lp{" + linkProperties + "} " - + "nc{" + networkCapabilities + "} Score{" + getCurrentScore() + "} " - + "everValidated{" + everValidated + "} lastValidated{" + lastValidated + "} " - + "created{" + created + "} lingering{" + isLingering() + "} " - + "explicitlySelected{" + networkAgentConfig.explicitlySelected + "} " - + "acceptUnvalidated{" + networkAgentConfig.acceptUnvalidated + "} " - + "everCaptivePortalDetected{" + everCaptivePortalDetected + "} " - + "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} " - + "captivePortalValidationPending{" + captivePortalValidationPending + "} " - + "partialConnectivity{" + partialConnectivity + "} " - + "acceptPartialConnectivity{" + networkAgentConfig.acceptPartialConnectivity + "} " - + "clat{" + clatd + "} " + return "NetworkAgentInfo{" + + "network{" + network + "} handle{" + network.getNetworkHandle() + "} ni{" + + networkInfo.toShortString() + "} " + + " Score{" + getCurrentScore() + "} " + + (isLingering() ? " lingering" : "") + + (everValidated ? " everValidated" : "") + + (lastValidated ? " lastValidated" : "") + + (partialConnectivity ? " partialConnectivity" : "") + + (everCaptivePortalDetected ? " everCaptivePortal" : "") + + (lastCaptivePortalDetected ? " isCaptivePortal" : "") + + (networkAgentConfig.explicitlySelected ? " explicitlySelected" : "") + + (networkAgentConfig.acceptUnvalidated ? " acceptUnvalidated" : "") + + (networkAgentConfig.acceptPartialConnectivity ? " acceptPartialConnectivity" : "") + + (clatd.isStarted() ? " clat{" + clatd + "} " : "") + + " lp{" + linkProperties + "}" + + " nc{" + networkCapabilities + "}" + "}"; } diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java index 25c761ab80ec..34b0aa246433 100644 --- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java +++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java @@ -51,7 +51,6 @@ public class NetworkNotificationManager { LOST_INTERNET(SystemMessage.NOTE_NETWORK_LOST_INTERNET), NETWORK_SWITCH(SystemMessage.NOTE_NETWORK_SWITCH), NO_INTERNET(SystemMessage.NOTE_NETWORK_NO_INTERNET), - LOGGED_IN(SystemMessage.NOTE_NETWORK_LOGGED_IN), PARTIAL_CONNECTIVITY(SystemMessage.NOTE_NETWORK_PARTIAL_CONNECTIVITY), SIGN_IN(SystemMessage.NOTE_NETWORK_SIGN_IN), PRIVATE_DNS_BROKEN(SystemMessage.NOTE_NETWORK_PRIVATE_DNS_BROKEN); @@ -114,14 +113,10 @@ public class NetworkNotificationManager { } } - private static int getIcon(int transportType, NotificationType notifyType) { - if (transportType != TRANSPORT_WIFI) { - return R.drawable.stat_notify_rssi_in_range; - } - - return notifyType == NotificationType.LOGGED_IN - ? R.drawable.ic_wifi_signal_4 - : R.drawable.stat_notify_wifi_in_range; // TODO: Distinguish ! from ?. + private static int getIcon(int transportType) { + return (transportType == TRANSPORT_WIFI) + ? R.drawable.stat_notify_wifi_in_range : // TODO: Distinguish ! from ?. + R.drawable.stat_notify_rssi_in_range; } /** @@ -155,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 { @@ -185,17 +180,17 @@ public class NetworkNotificationManager { Resources r = mContext.getResources(); final CharSequence title; final CharSequence details; - int icon = getIcon(transportType, notifyType); + 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); } @@ -203,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); @@ -235,9 +230,6 @@ public class NetworkNotificationManager { details = r.getString(R.string.network_available_sign_in_detailed, name); break; } - } else if (notifyType == NotificationType.LOGGED_IN) { - title = WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()); - details = r.getString(R.string.captive_portal_logged_in_detailed); } else if (notifyType == NotificationType.NETWORK_SWITCH) { String fromTransport = getTransportName(transportType); String toTransport = getTransportName(approximateTransportType(switchToNai)); @@ -379,7 +371,6 @@ public class NetworkNotificationManager { case NETWORK_SWITCH: return 2; case LOST_INTERNET: - case LOGGED_IN: return 1; default: return 0; diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 7c42cc2465e0..3006ef41931f 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -306,10 +306,6 @@ final class Constants { static final String PROPERTY_PREFERRED_ADDRESS_PLAYBACK = "persist.sys.hdmi.addr.playback"; static final String PROPERTY_PREFERRED_ADDRESS_TV = "persist.sys.hdmi.addr.tv"; - // Property name for the local device configurations. - // TODO(OEM): OEM should provide this property, and the value is the comma separated integer - // values which denotes the device type in HDMI Spec 1.4. - static final String PROPERTY_DEVICE_TYPE = "ro.hdmi.device_type"; // TODO(OEM): Set this to false to keep the playback device in sleep upon hotplug event. // True by default. diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index a83dd215593f..d489c395cb8a 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -67,6 +67,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings.Global; +import android.sysprop.HdmiProperties; import android.text.TextUtils; import android.util.ArraySet; import android.util.Slog; @@ -94,6 +95,8 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; /** * Provides a service for sending and processing HDMI control messages, @@ -435,7 +438,14 @@ public class HdmiControlService extends SystemService { public HdmiControlService(Context context) { super(context); - mLocalDevices = getIntList(SystemProperties.get(Constants.PROPERTY_DEVICE_TYPE)); + List<Integer> deviceTypes = HdmiProperties.device_type(); + if (deviceTypes.contains(null)) { + Slog.w(TAG, "Error parsing ro.hdmi.device.type: " + SystemProperties.get( + "ro.hdmi.device_type")); + deviceTypes = deviceTypes.stream().filter(Objects::nonNull).collect( + Collectors.toList()); + } + mLocalDevices = deviceTypes; mSettingsObserver = new SettingsObserver(mHandler); } diff --git a/services/core/java/com/android/server/inputmethod/OWNERS b/services/core/java/com/android/server/inputmethod/OWNERS new file mode 100644 index 000000000000..25ef9facb216 --- /dev/null +++ b/services/core/java/com/android/server/inputmethod/OWNERS @@ -0,0 +1,6 @@ +set noparent + +ogunwale@google.com +yukawa@google.com +tarandeep@google.com +lumark@google.com diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java index 563dcf7e1156..48f1ddb023fd 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java @@ -21,7 +21,7 @@ import static com.android.server.net.NetworkPolicyManagerService.isUidNetworking import android.annotation.NonNull; import android.net.Network; import android.net.NetworkTemplate; -import android.net.netstats.provider.AbstractNetworkStatsProvider; +import android.net.netstats.provider.NetworkStatsProvider; import android.telephony.SubscriptionPlan; import java.util.Set; @@ -130,8 +130,8 @@ public abstract class NetworkPolicyManagerInternal { Set<String> packageNames, int userId); /** - * Notifies that the specified {@link AbstractNetworkStatsProvider} has reached its quota - * which was set through {@link AbstractNetworkStatsProvider#setLimit(String, long)}. + * Notifies that the specified {@link NetworkStatsProvider} has reached its quota + * which was set through {@link NetworkStatsProvider#onSetLimit(String, long)}. * * @param tag the human readable identifier of the custom network stats provider. */ diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 10cf250acb14..22ed661b03c0 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -75,7 +75,7 @@ import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.TrafficStats.MB_IN_BYTES; -import static android.net.netstats.provider.AbstractNetworkStatsProvider.QUOTA_UNLIMITED; +import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED; import static android.os.Trace.TRACE_TAG_NETWORK; import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED; import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED; @@ -1869,8 +1869,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mNetIdToSubId.put(state.network.netId, parseSubId(state)); } if (state.networkInfo != null && state.networkInfo.isConnected()) { + // Policies matched by NPMS only match by subscriber ID or by ssid. Thus subtype + // in the object created here is never used and its value doesn't matter, so use + // NETWORK_TYPE_UNKNOWN. final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state, - true); + true, TelephonyManager.NETWORK_TYPE_UNKNOWN /* subType */); identified.put(state, ident); } } @@ -3088,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/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java index 22b01bee6c6a..75ffe35674d1 100644 --- a/services/core/java/com/android/server/net/NetworkStatsFactory.java +++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java @@ -229,7 +229,7 @@ public class NetworkStatsFactory { entry.txPackets += reader.nextLong(); } - stats.addEntry(entry); + stats.insertEntry(entry); reader.finishLine(); } } catch (NullPointerException|NumberFormatException e) { @@ -279,7 +279,7 @@ public class NetworkStatsFactory { entry.txBytes = reader.nextLong(); entry.txPackets = reader.nextLong(); - stats.addEntry(entry); + stats.insertEntry(entry); reader.finishLine(); } } catch (NullPointerException|NumberFormatException e) { @@ -439,7 +439,7 @@ public class NetworkStatsFactory { if ((limitIfaces == null || ArrayUtils.contains(limitIfaces, entry.iface)) && (limitUid == UID_ALL || limitUid == entry.uid) && (limitTag == TAG_ALL || limitTag == entry.tag)) { - stats.addEntry(entry); + stats.insertEntry(entry); } reader.finishLine(); diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 66e691a79f97..26808587437c 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -17,14 +17,17 @@ package com.android.server.net; import static android.Manifest.permission.ACCESS_NETWORK_STATE; +import static android.Manifest.permission.NETWORK_STATS_PROVIDER; import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; import static android.Manifest.permission.UPDATE_DEVICE_STATS; import static android.content.Intent.ACTION_SHUTDOWN; import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_UID; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; import static android.net.ConnectivityManager.isNetworkTypeMobile; +import static android.net.NetworkIdentity.SUBTYPE_COMBINED; import static android.net.NetworkStack.checkNetworkStackPermission; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; import static android.net.NetworkStats.IFACE_ALL; @@ -43,10 +46,12 @@ import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL; import static android.net.NetworkTemplate.buildTemplateMobileWildcard; import static android.net.NetworkTemplate.buildTemplateWifiWildcard; +import static android.net.NetworkTemplate.getCollapsedRatType; import static android.net.TrafficStats.KB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES; import static android.os.Trace.TRACE_TAG_NETWORK; import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED; +import static android.provider.Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED; import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES; @@ -62,6 +67,9 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES; import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE; +import static android.telephony.PhoneStateListener.LISTEN_NONE; +import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE; +import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; @@ -101,12 +109,13 @@ import android.net.NetworkTemplate; import android.net.TrafficStats; import android.net.netstats.provider.INetworkStatsProvider; import android.net.netstats.provider.INetworkStatsProviderCallback; -import android.net.netstats.provider.NetworkStatsProviderCallback; +import android.net.netstats.provider.NetworkStatsProvider; import android.os.BestClock; import android.os.Binder; import android.os.DropBoxManager; import android.os.Environment; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.HandlerThread; import android.os.IBinder; import android.os.INetworkManagementService; @@ -123,6 +132,8 @@ import android.provider.Settings; import android.provider.Settings.Global; import android.service.NetworkInterfaceProto; import android.service.NetworkStatsServiceDumpProto; +import android.telephony.PhoneStateListener; +import android.telephony.ServiceState; import android.telephony.SubscriptionPlan; import android.telephony.TelephonyManager; import android.text.format.DateUtils; @@ -155,6 +166,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.concurrent.Executor; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -171,6 +183,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static final int MSG_PERFORM_POLL = 1; // Perform polling, persist network, and register the global alert again. private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2; + private static final int MSG_UPDATE_IFACES = 3; /** Flags to control detail level of poll event. */ private static final int FLAG_PERSIST_NETWORK = 0x1; @@ -227,12 +240,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * Settings that can be changed externally. */ public interface NetworkStatsSettings { - public long getPollInterval(); - public long getPollDelay(); - public boolean getSampleEnabled(); - public boolean getAugmentEnabled(); + long getPollInterval(); + long getPollDelay(); + boolean getSampleEnabled(); + boolean getAugmentEnabled(); + /** + * When enabled, all mobile data is reported under {@link NetworkIdentity#SUBTYPE_COMBINED}. + * When disabled, mobile data is broken down by a granular subtype representative of the + * actual subtype. {@see NetworkTemplate#getCollapsedRatType}. + * Enabling this decreases the level of detail but saves performance, disk space and + * amount of data logged. + */ + boolean getCombineSubtypeEnabled(); - public static class Config { + class Config { public final long bucketDuration; public final long rotateAgeMillis; public final long deleteAgeMillis; @@ -244,16 +265,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - public Config getDevConfig(); - public Config getXtConfig(); - public Config getUidConfig(); - public Config getUidTagConfig(); + Config getDevConfig(); + Config getXtConfig(); + Config getUidConfig(); + Config getUidTagConfig(); - public long getGlobalAlertBytes(long def); - public long getDevPersistBytes(long def); - public long getXtPersistBytes(long def); - public long getUidPersistBytes(long def); - public long getUidTagPersistBytes(long def); + long getGlobalAlertBytes(long def); + long getDevPersistBytes(long def); + long getXtPersistBytes(long def); + long getUidPersistBytes(long def); + long getUidTagPersistBytes(long def); } private final Object mStatsLock = new Object(); @@ -278,6 +299,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @GuardedBy("mStatsLock") private Network[] mDefaultNetworks = new Network[0]; + /** Last states of all networks sent from ConnectivityService. */ + @GuardedBy("mStatsLock") + @Nullable + private NetworkState[] mLastNetworkStates = null; + private final DropBoxNonMonotonicObserver mNonMonotonicObserver = new DropBoxNonMonotonicObserver(); @@ -353,6 +379,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { performPoll(FLAG_PERSIST_ALL); break; } + case MSG_UPDATE_IFACES: { + // If no cached states, ignore. + if (mLastNetworkStates == null) break; + updateIfaces(mDefaultNetworks, mLastNetworkStates, mActiveIface); + break; + } case MSG_PERFORM_POLL_REGISTER_ALERT: { performPoll(FLAG_PERSIST_NETWORK); registerGlobalAlert(); @@ -405,6 +437,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final HandlerThread handlerThread = mDeps.makeHandlerThread(); handlerThread.start(); mHandler = new NetworkStatsHandler(handlerThread.getLooper()); + mPhoneListener = new NetworkTypeListener(new HandlerExecutor(mHandler)); } /** @@ -484,6 +517,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, mSettings.getPollInterval(), pollIntent); + // TODO: 1. listen to changes from all subscriptions. + // 2. listen to settings changed to support dynamically enable/disable. + // watch for networkType changes + if (!mSettings.getCombineSubtypeEnabled()) { + mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE); + } + registerGlobalAlert(); } @@ -504,6 +544,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mContext.unregisterReceiver(mUserReceiver); mContext.unregisterReceiver(mShutdownReceiver); + mTeleManager.listen(mPhoneListener, LISTEN_NONE); + final long currentTime = mClock.millis(); // persist any pending stats @@ -556,7 +598,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (RemoteException e) { // ignored; service lives in system_server } - invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setAlert(mGlobalAlertBytes)); + invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes)); } @Override @@ -757,7 +799,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null); final NetworkStats stats = new NetworkStats(end - start, 1); - stats.addEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, + stats.insertEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets, entry.txBytes, entry.txPackets, entry.operations)); return stats; @@ -1154,6 +1196,38 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } }; + /** + * Receiver that watches for {@link TelephonyManager} changes, such as + * transitioning between Radio Access Technology(RAT) types. + */ + @NonNull + private final NetworkTypeListener mPhoneListener; + + class NetworkTypeListener extends PhoneStateListener { + private volatile int mLastCollapsedRatType = NETWORK_TYPE_UNKNOWN; + + NetworkTypeListener(@NonNull Executor executor) { + super(executor); + } + + @Override + public void onServiceStateChanged(@NonNull ServiceState ss) { + final int networkType = ss.getDataNetworkType(); + final int collapsedRatType = getCollapsedRatType(networkType); + if (collapsedRatType == mLastCollapsedRatType) return; + + if (LOGD) { + Log.d(TAG, "subtype changed for mobile: " + + mLastCollapsedRatType + " -> " + collapsedRatType); + } + // Protect service from frequently updating. Remove pending messages if any. + mHandler.removeMessages(MSG_UPDATE_IFACES); + mLastCollapsedRatType = collapsedRatType; + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay()); + } + } + private void updateIfaces( Network[] defaultNetworks, NetworkState[] networkStates, @@ -1175,7 +1249,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * they are combined under a single {@link NetworkIdentitySet}. */ @GuardedBy("mStatsLock") - private void updateIfacesLocked(Network[] defaultNetworks, NetworkState[] states) { + private void updateIfacesLocked(@Nullable Network[] defaultNetworks, + @NonNull NetworkState[] states) { if (!mSystemReady) return; if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); @@ -1195,13 +1270,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mDefaultNetworks = defaultNetworks; } + mLastNetworkStates = states; + + final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled(); final ArraySet<String> mobileIfaces = new ArraySet<>(); for (NetworkState state : states) { if (state.networkInfo.isConnected()) { final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType()); final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network); + final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED + : getSubTypeForState(state); final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state, - isDefault); + isDefault, subType); // Traffic occurring on the base interface is always counted for // both total usage and UID details. @@ -1262,6 +1342,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]); } + /** + * For networks with {@code TRANSPORT_CELLULAR}, get subType that was obtained through + * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different + * transport types do not actually fill this value. + */ + private int getSubTypeForState(@NonNull NetworkState state) { + if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { + return 0; + } + + // TODO: return different subType for different subscriptions. + return mPhoneListener.mLastCollapsedRatType; + } + private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet( ArrayMap<K, NetworkIdentitySet> map, K key) { NetworkIdentitySet ident = map.get(key); @@ -1374,7 +1468,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate"); final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount(); mStatsProviderSem.drainPermits(); - invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */)); + invokeForAllStatsProviderCallbacks( + (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */)); try { mStatsProviderSem.tryAcquire(registeredCallbackCount, MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS); @@ -1549,7 +1644,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public void setStatsProviderLimitAsync(@NonNull String iface, long quota) { Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")"); - invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota)); + invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota)); } } @@ -1614,6 +1709,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return; } + pw.println("Configs:"); + pw.increaseIndent(); + pw.printPair(NETSTATS_COMBINE_SUBTYPE_ENABLED, mSettings.getCombineSubtypeEnabled()); + pw.println(); + pw.decreaseIndent(); + pw.println("Active interfaces:"); pw.increaseIndent(); for (int i = 0; i < mActiveIfaces.size(); i++) { @@ -1793,6 +1894,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } + // TODO: It is copied from ConnectivityService, consider refactor these check permission + // functions to a proper util. + private boolean checkAnyPermissionOf(String... permissions) { + for (String permission : permissions) { + if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) { + return true; + } + } + return false; + } + + private void enforceAnyPermissionOf(String... permissions) { + if (!checkAnyPermissionOf(permissions)) { + throw new SecurityException("Requires one of the following permissions: " + + String.join(", ", permissions) + "."); + } + } + /** * Registers a custom provider of {@link android.net.NetworkStats} to combine the network * statistics that cannot be seen by the kernel to system. To unregister, invoke the @@ -1800,16 +1919,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * * @param tag a human readable identifier of the custom network stats provider. * @param provider the {@link INetworkStatsProvider} binder corresponding to the - * {@link android.net.netstats.provider.AbstractNetworkStatsProvider} to be - * registered. + * {@link NetworkStatsProvider} to be registered. * - * @return a binder interface of - * {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be - * used to report events to the system. + * @return a {@link INetworkStatsProviderCallback} binder + * interface, which can be used to report events to the system. */ public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider( @NonNull String tag, @NonNull INetworkStatsProvider provider) { - mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG); + enforceAnyPermissionOf(NETWORK_STATS_PROVIDER, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); Objects.requireNonNull(provider, "provider is null"); Objects.requireNonNull(tag, "tag is null"); try { @@ -1910,7 +2028,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public void onStatsUpdated(int token, @Nullable NetworkStats ifaceStats, + public void notifyStatsUpdated(int token, @Nullable NetworkStats ifaceStats, @Nullable NetworkStats uidStats) { // TODO: 1. Use token to map ifaces to correct NetworkIdentity. // 2. Store the difference and store it directly to the recorder. @@ -1922,12 +2040,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public void onAlertReached() throws RemoteException { + public void notifyAlertReached() throws RemoteException { mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */); } @Override - public void onLimitReached() { + public void notifyLimitReached() { Log.d(TAG, mTag + ": onLimitReached"); LocalServices.getService(NetworkPolicyManagerInternal.class) .onStatsProviderLimitReached(mTag); @@ -2025,6 +2143,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true); } @Override + public boolean getCombineSubtypeEnabled() { + return getGlobalBoolean(NETSTATS_COMBINE_SUBTYPE_ENABLED, false); + } + @Override public Config getDevConfig() { return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS), getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS), 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/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index fd8db4b99be8..b217dce885d9 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -26,7 +26,6 @@ import android.app.AppOpsManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PackageDeleteObserver; -import android.app.PackageInstallObserver; import android.app.admin.DevicePolicyEventLogger; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; @@ -994,74 +993,57 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } } - static class PackageInstallObserverAdapter extends PackageInstallObserver { - private final Context mContext; - private final IntentSender mTarget; - private final int mSessionId; - private final boolean mShowNotification; - private final int mUserId; - - public PackageInstallObserverAdapter(Context context, IntentSender target, int sessionId, - boolean showNotification, int userId) { - mContext = context; - mTarget = target; - mSessionId = sessionId; - mShowNotification = showNotification; - mUserId = userId; + static void sendOnUserActionRequired(Context context, IntentSender target, int sessionId, + Intent intent) { + final Intent fillIn = new Intent(); + fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId); + fillIn.putExtra(PackageInstaller.EXTRA_STATUS, + PackageInstaller.STATUS_PENDING_USER_ACTION); + fillIn.putExtra(Intent.EXTRA_INTENT, intent); + try { + target.sendIntent(context, 0, fillIn, null, null); + } catch (SendIntentException ignored) { } + } - @Override - public void onUserActionRequired(Intent intent) { - final Intent fillIn = new Intent(); - fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId); - fillIn.putExtra(PackageInstaller.EXTRA_STATUS, - PackageInstaller.STATUS_PENDING_USER_ACTION); - fillIn.putExtra(Intent.EXTRA_INTENT, intent); - try { - mTarget.sendIntent(mContext, 0, fillIn, null, null); - } catch (SendIntentException ignored) { + static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId, + boolean showNotification, int userId, String basePackageName, int returnCode, + String msg, Bundle extras) { + if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) { + boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING); + Notification notification = buildSuccessNotification(context, + context.getResources() + .getString(update ? R.string.package_updated_device_owner : + R.string.package_installed_device_owner), + basePackageName, + userId); + if (notification != null) { + NotificationManager notificationManager = (NotificationManager) + context.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.notify(basePackageName, + SystemMessage.NOTE_PACKAGE_STATE, + notification); } } - - @Override - public void onPackageInstalled(String basePackageName, int returnCode, String msg, - Bundle extras) { - if (PackageManager.INSTALL_SUCCEEDED == returnCode && mShowNotification) { - boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING); - Notification notification = buildSuccessNotification(mContext, - mContext.getResources() - .getString(update ? R.string.package_updated_device_owner : - R.string.package_installed_device_owner), - basePackageName, - mUserId); - if (notification != null) { - NotificationManager notificationManager = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.notify(basePackageName, - SystemMessage.NOTE_PACKAGE_STATE, - notification); - } - } - final Intent fillIn = new Intent(); - fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName); - fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId); - fillIn.putExtra(PackageInstaller.EXTRA_STATUS, - PackageManager.installStatusToPublicStatus(returnCode)); - fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, - PackageManager.installStatusToString(returnCode, msg)); - fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode); - if (extras != null) { - final String existing = extras.getString( - PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE); - if (!TextUtils.isEmpty(existing)) { - fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing); - } - } - try { - mTarget.sendIntent(mContext, 0, fillIn, null, null); - } catch (SendIntentException ignored) { + final Intent fillIn = new Intent(); + fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName); + fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId); + fillIn.putExtra(PackageInstaller.EXTRA_STATUS, + PackageManager.installStatusToPublicStatus(returnCode)); + fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, + PackageManager.installStatusToString(returnCode, msg)); + fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode); + if (extras != null) { + final String existing = extras.getString( + PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE); + if (!TextUtils.isEmpty(existing)) { + fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing); } } + try { + target.sendIntent(context, 0, fillIn, null, null); + } catch (SendIntentException ignored) { + } } /** diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 7091c7ca7316..6f6c3152fb9d 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -18,7 +18,6 @@ package com.android.server.pm; import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED; import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_SIGNATURE; -import static android.content.pm.PackageManager.INSTALL_FAILED_CONTAINER_ERROR; import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; @@ -79,7 +78,6 @@ import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.ParcelableException; import android.os.Process; -import android.os.RemoteException; import android.os.RevocableFileDescriptor; import android.os.SystemProperties; import android.os.UserHandle; @@ -107,7 +105,6 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.pm.Installer.InstallerException; -import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter; import com.android.server.pm.dex.DexManager; import com.android.server.security.VerityUtils; @@ -131,7 +128,7 @@ import java.util.concurrent.atomic.AtomicInteger; public class PackageInstallerSession extends IPackageInstallerSession.Stub { private static final String TAG = "PackageInstallerSession"; private static final boolean LOGD = true; - private static final String REMOVE_SPLIT_MARKER_EXTENSION = ".removed"; + private static final String REMOVE_MARKER_EXTENSION = ".removed"; private static final int MSG_COMMIT = 1; private static final int MSG_ON_PACKAGE_INSTALLED = 2; @@ -257,7 +254,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private final ArrayList<FileBridge> mBridges = new ArrayList<>(); @GuardedBy("mLock") - private IPackageInstallObserver2 mRemoteObserver; + private IntentSender mRemoteStatusReceiver; /** Fields derived from commit parsing */ @GuardedBy("mLock") @@ -294,9 +291,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private File mResolvedBaseFile; @GuardedBy("mLock") - private File mResolvedStageDir; - - @GuardedBy("mLock") private final List<File> mResolvedStagedFiles = new ArrayList<>(); @GuardedBy("mLock") private final List<File> mResolvedInheritedFiles = new ArrayList<>(); @@ -315,7 +309,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Installers can't stage directories, so it's fine to ignore // entries like "lost+found". if (file.isDirectory()) return false; - if (file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false; + if (file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false; if (DexMetadataHelper.isDexMetadataFile(file)) return false; if (VerityUtils.isFsveritySignatureFile(file)) return false; return true; @@ -325,7 +319,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public boolean accept(File file) { if (file.isDirectory()) return false; - if (!file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false; + if (!file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false; return true; } }; @@ -342,14 +336,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final String packageName = (String) args.arg1; final String message = (String) args.arg2; final Bundle extras = (Bundle) args.arg3; - final IPackageInstallObserver2 observer = (IPackageInstallObserver2) args.arg4; + final IntentSender statusReceiver = (IntentSender) args.arg4; final int returnCode = args.argi1; args.recycle(); - try { - observer.onPackageInstalled(packageName, returnCode, message, extras); - } catch (RemoteException ignored) { - } + PackageInstallerService.sendOnPackageInstalled(mContext, + statusReceiver, sessionId, + isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId, + packageName, returnCode, message, extras); break; } @@ -559,23 +553,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } - /** - * Resolve the actual location where staged data should be written. This - * might point at an ASEC mount point, which is why we delay path resolution - * until someone actively works with the session. - */ - @GuardedBy("mLock") - private File resolveStageDirLocked() throws IOException { - if (mResolvedStageDir == null) { - if (stageDir != null) { - mResolvedStageDir = stageDir; - } else { - throw new IOException("Missing stageDir"); - } - } - return mResolvedStageDir; - } - @Override public void setClientProgress(float progress) { synchronized (mLock) { @@ -615,14 +592,32 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { assertCallerIsOwnerOrRootLocked(); assertPreparedAndNotCommittedOrDestroyedLocked("getNames"); - try { - return resolveStageDirLocked().list(); - } catch (IOException e) { - throw ExceptionUtils.wrap(e); - } + return getNamesLocked(); } } + @GuardedBy("mLock") + private String[] getNamesLocked() { + return stageDir.list(); + } + + private static File[] filterFiles(File parent, String[] names, FileFilter filter) { + return Arrays.stream(names).map(name -> new File(parent, name)).filter( + file -> filter.accept(file)).toArray(File[]::new); + } + + @GuardedBy("mLock") + private File[] getAddedFilesLocked() { + String[] names = getNamesLocked(); + return filterFiles(stageDir, names, sAddedFilter); + } + + @GuardedBy("mLock") + private File[] getRemovedFilesLocked() { + String[] names = getNamesLocked(); + return filterFiles(stageDir, names, sRemovedFilter); + } + @Override public void removeSplit(String splitName) { if (TextUtils.isEmpty(params.appPackageName)) { @@ -641,13 +636,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } + private static String getRemoveMarkerName(String name) { + final String markerName = name + REMOVE_MARKER_EXTENSION; + if (!FileUtils.isValidExtFilename(markerName)) { + throw new IllegalArgumentException("Invalid marker: " + markerName); + } + return markerName; + } + private void createRemoveSplitMarkerLocked(String splitName) throws IOException { try { - final String markerName = splitName + REMOVE_SPLIT_MARKER_EXTENSION; - if (!FileUtils.isValidExtFilename(markerName)) { - throw new IllegalArgumentException("Invalid marker: " + markerName); - } - final File target = new File(resolveStageDirLocked(), markerName); + final File target = new File(stageDir, getRemoveMarkerName(splitName)); target.createNewFile(); Os.chmod(target.getAbsolutePath(), 0 /*mode*/); } catch (ErrnoException e) { @@ -681,7 +680,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // will block any attempted install transitions. final RevocableFileDescriptor fd; final FileBridge bridge; - final File stageDir; synchronized (mLock) { assertCallerIsOwnerOrRootLocked(); assertPreparedAndNotSealedLocked("openWrite"); @@ -695,8 +693,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { bridge = new FileBridge(); mBridges.add(bridge); } - - stageDir = resolveStageDirLocked(); } try { @@ -802,7 +798,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (!FileUtils.isValidExtFilename(name)) { throw new IllegalArgumentException("Invalid name: " + name); } - final File target = new File(resolveStageDirLocked(), name); + final File target = new File(stageDir, name); final FileDescriptor targetFd = Os.open(target.getAbsolutePath(), O_RDONLY, 0); return new ParcelFileDescriptor(targetFd); } catch (ErrnoException e) { @@ -948,7 +944,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { * This method may be called multiple times to update the status receiver validate caller * permissions. */ - public boolean markAsCommitted( + private boolean markAsCommitted( @NonNull IntentSender statusReceiver, boolean forTransfer) { Preconditions.checkNotNull(statusReceiver); @@ -959,10 +955,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { assertCallerIsOwnerOrRootLocked(); assertPreparedAndNotDestroyedLocked("commit"); - final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter( - mContext, statusReceiver, sessionId, - isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId); - mRemoteObserver = adapter.getBinder(); + mRemoteStatusReceiver = statusReceiver; if (forTransfer) { mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null); @@ -986,12 +979,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (!mSealed) { try { sealAndValidateLocked(childSessions); - } catch (IOException e) { - throw new IllegalArgumentException(e); } catch (PackageManagerException e) { - // Do now throw an exception here to stay compatible with O and older - destroyInternal(); - dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null); return false; } } @@ -1091,52 +1079,50 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { */ @GuardedBy("mLock") private void sealAndValidateLocked(List<PackageInstallerSession> childSessions) - throws PackageManagerException, IOException { - assertNoWriteFileTransfersOpenLocked(); - assertPreparedAndNotDestroyedLocked("sealing of session"); - - mSealed = true; + throws PackageManagerException { + try { + assertNoWriteFileTransfersOpenLocked(); + assertPreparedAndNotDestroyedLocked("sealing of session"); - if (childSessions != null) { - assertMultiPackageConsistencyLocked(childSessions); - } + mSealed = true; - 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); + if (childSessions != null) { + assertMultiPackageConsistencyLocked(childSessions); } - } - // 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. - if (!params.isMultiPackage) { - final PackageInfo pkgInfo = mPm.getPackageInfo( - params.appPackageName, PackageManager.GET_SIGNATURES - | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId); - - resolveStageDirLocked(); + // 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. + if (!params.isMultiPackage) { + final PackageInfo pkgInfo = mPm.getPackageInfo( + params.appPackageName, PackageManager.GET_SIGNATURES + | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId); - try { - if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) { - validateApexInstallLocked(); - } else { - validateApkInstallLocked(pkgInfo); + try { + if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) { + validateApexInstallLocked(); + } else { + validateApkInstallLocked(pkgInfo); + } + } catch (PackageManagerException e) { + throw e; + } catch (Throwable e) { + // Convert all exceptions into package manager exceptions as only those are + // handled in the code above. + throw new PackageManagerException(e); } - } catch (PackageManagerException e) { - throw e; - } catch (Throwable e) { - // Convert all exceptions into package manager exceptions as only those are handled - // in the code above - 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(); + // Dispatch message to remove session from PackageInstallerService + dispatchSessionFinished( + e.error, ExceptionUtils.getCompleteMessage(e), null); + throw e; } } @@ -1159,15 +1145,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { synchronized (mLock) { try { sealAndValidateLocked(childSessions); - } catch (IOException e) { - throw new IllegalStateException(e); } catch (PackageManagerException e) { Slog.e(TAG, "Package not valid", e); - // Session is sealed but could not be verified, we need to destroy it. - destroyInternal(); - // Dispatch message to remove session from PackageInstallerService - dispatchSessionFinished( - e.error, ExceptionUtils.getCompleteMessage(e), null); } } } @@ -1208,13 +1187,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { try { sealAndValidateLocked(childSessions); - } catch (IOException e) { - throw new IllegalStateException(e); } catch (PackageManagerException e) { - // Session is sealed but could not be verified, we need to destroy it - destroyInternal(); - dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null); - throw new IllegalArgumentException("Package is not valid", e); } @@ -1299,11 +1272,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } if (!success) { - try { - mRemoteObserver.onPackageInstalled( - null, failure.error, failure.getLocalizedMessage(), null); - } catch (RemoteException ignored) { - } + PackageInstallerService.sendOnPackageInstalled(mContext, + mRemoteStatusReceiver, sessionId, + isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId, null, + failure.error, failure.getLocalizedMessage(), null); return; } mPm.installStage(activeChildSessions); @@ -1347,10 +1319,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL); intent.setPackage(mPm.getPackageInstallerPackageName()); intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId); - try { - mRemoteObserver.onUserActionRequired(intent); - } catch (RemoteException ignored) { - } + + PackageInstallerService.sendOnUserActionRequired(mContext, + mRemoteStatusReceiver, sessionId, intent); // Commit was keeping session marked as active until now; release // that extra refcount so session appears idle. @@ -1363,7 +1334,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (params.mode == SessionParams.MODE_INHERIT_EXISTING) { try { final List<File> fromFiles = mResolvedInheritedFiles; - final File toDir = resolveStageDirLocked(); + final File toDir = stageDir; if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles); if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) { @@ -1413,8 +1384,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { computeProgressLocked(true); // Unpack native libraries - extractNativeLibraries(mResolvedStageDir, params.abiOverride, - mayInheritNativeLibs()); + extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs()); } // We've reached point of no return; call into PMS to install the stage. @@ -1470,12 +1440,13 @@ 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() throws PackageManagerException { - final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter); + final File[] addedFiles = getAddedFilesLocked(); if (ArrayUtils.isEmpty(addedFiles)) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged"); } @@ -1485,13 +1456,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { "Too many files for apex install"); } - try { - resolveStageDirLocked(); - } catch (IOException e) { - throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR, - "Failed to resolve stage location", e); - } - File addedFile = addedFiles[0]; // there is only one file // Ensure file name has proper suffix @@ -1504,10 +1468,24 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { "Invalid filename: " + targetName); } - final File targetFile = new File(mResolvedStageDir, targetName); + 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(); + } } /** @@ -1545,25 +1523,18 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { && params.mode == SessionParams.MODE_INHERIT_EXISTING && VerityUtils.hasFsverity(pkgInfo.applicationInfo.getBaseCodePath()); - try { - resolveStageDirLocked(); - } catch (IOException e) { - throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR, - "Failed to resolve stage location", e); - } - - final File[] removedFiles = mResolvedStageDir.listFiles(sRemovedFilter); + final File[] removedFiles = getRemovedFilesLocked(); final List<String> removeSplitList = new ArrayList<>(); if (!ArrayUtils.isEmpty(removedFiles)) { for (File removedFile : removedFiles) { final String fileName = removedFile.getName(); final String splitName = fileName.substring( - 0, fileName.length() - REMOVE_SPLIT_MARKER_EXTENSION.length()); + 0, fileName.length() - REMOVE_MARKER_EXTENSION.length()); removeSplitList.add(splitName); } } - final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter); + final File[] addedFiles = getAddedFilesLocked(); if (ArrayUtils.isEmpty(addedFiles) && removeSplitList.size() == 0) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged"); } @@ -1607,7 +1578,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { "Invalid filename: " + targetName); } - final File targetFile = new File(mResolvedStageDir, targetName); + final File targetFile = new File(stageDir, targetName); resolveAndStageFile(addedFile, targetFile); // Base is coming from session @@ -1622,7 +1593,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Invalid filename: " + dexMetadataFile); } - final File targetDexMetadataFile = new File(mResolvedStageDir, + final File targetDexMetadataFile = new File(stageDir, DexMetadataHelper.buildDexMetadataPathForApk(targetName)); resolveAndStageFile(dexMetadataFile, targetDexMetadataFile); } @@ -1883,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() { @@ -2182,17 +2162,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) { - final IPackageInstallObserver2 observer; + final IntentSender statusReceiver; final String packageName; synchronized (mLock) { mFinalStatus = returnCode; mFinalMessage = msg; - observer = mRemoteObserver; + statusReceiver = mRemoteStatusReceiver; packageName = mPackageName; } - if (observer != null) { + if (statusReceiver != null) { // Execute observer.onPackageInstalled on different tread as we don't want callers // inside the system server have to worry about catching the callbacks while they are // calling into the session @@ -2200,7 +2180,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { args.arg1 = packageName; args.arg2 = msg; args.arg3 = extras; - args.arg4 = observer; + args.arg4 = statusReceiver; args.argi1 = returnCode; mHandler.obtainMessage(MSG_ON_PACKAGE_INSTALLED, args).sendToTarget(); diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 8cc66b20f84d..96ccba5b4d6f 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -39,6 +39,8 @@ import android.content.rollback.IRollbackManager; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.Looper; +import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.ParcelableException; import android.os.PowerManager; @@ -59,6 +61,7 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -73,7 +76,7 @@ public class StagingManager { private final PackageInstallerService mPi; private final ApexManager mApexManager; private final PowerManager mPowerManager; - private final Handler mBgHandler; + private final PreRebootVerificationHandler mPreRebootVerificationHandler; @GuardedBy("mStagedSessions") private final SparseArray<PackageInstallerSession> mStagedSessions = new SparseArray<>(); @@ -82,7 +85,8 @@ public class StagingManager { mPi = pi; mApexManager = am; mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - mBgHandler = BackgroundThread.getHandler(); + mPreRebootVerificationHandler = new PreRebootVerificationHandler( + BackgroundThread.get().getLooper()); } private void updateStoredSession(@NonNull PackageInstallerSession sessionInfo) { @@ -110,18 +114,17 @@ public class StagingManager { * Validates the signature used to sign the container of the new apex package * * @param newApexPkg The new apex package that is being installed - * @param installFlags flags related to the session * @throws PackageManagerException */ - private void validateApexSignature(PackageInfo newApexPkg, int installFlags) + private void validateApexSignature(PackageInfo newApexPkg) throws PackageManagerException { // Get signing details of the new package final String apexPath = newApexPkg.applicationInfo.sourceDir; final String packageName = newApexPkg.packageName; - final SigningDetails signingDetails; + final SigningDetails newSigningDetails; try { - signingDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR); + newSigningDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR); } catch (PackageParserException e) { throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, "Failed to parse APEX package " + apexPath, e); @@ -146,8 +149,10 @@ public class StagingManager { } // Verify signing details for upgrade - if (signingDetails.checkCapability(existingSigningDetails, - PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) { + if (newSigningDetails.checkCapability(existingSigningDetails, + SigningDetails.CertCapabilities.INSTALLED_DATA) + || existingSigningDetails.checkCapability(newSigningDetails, + SigningDetails.CertCapabilities.ROLLBACK)) { return; } @@ -242,75 +247,6 @@ public class StagingManager { return (session.params.installFlags & PackageManager.INSTALL_APEX) != 0; } - private void preRebootVerification(@NonNull PackageInstallerSession session) { - Slog.d(TAG, "Starting preRebootVerification for session " + session.sessionId); - final boolean hasApex = sessionContainsApex(session); - // APEX checks. For single-package sessions, check if they contain an APEX. For - // multi-package sessions, find all the child sessions that contain an APEX. - if (hasApex) { - try { - final List<PackageInfo> apexPackages = submitSessionToApexService(session); - for (PackageInfo apexPackage : apexPackages) { - validateApexSignature(apexPackage, session.params.installFlags); - } - } catch (PackageManagerException e) { - session.setStagedSessionFailed(e.error, e.getMessage()); - return; - } - } - - if (sessionContainsApk(session)) { - try { - Slog.d(TAG, "Running a pre-reboot verification for APKs in session " - + session.sessionId + " by performing a dry-run install"); - installApksInSession(session, /* preReboot */ true); - // TODO(b/118865310): abort the session on apexd. - } catch (PackageManagerException e) { - session.setStagedSessionFailed(e.error, e.getMessage()); - return; - } - } - - if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) { - // If rollback is enabled for this session, we call through to the RollbackManager - // with the list of sessions it must enable rollback for. Note that notifyStagedSession - // is a synchronous operation. - final IRollbackManager rm = IRollbackManager.Stub.asInterface( - ServiceManager.getService(Context.ROLLBACK_SERVICE)); - try { - // NOTE: To stay consistent with the non-staged install flow, we don't fail the - // entire install if rollbacks can't be enabled. - if (!rm.notifyStagedSession(session.sessionId)) { - Slog.e(TAG, "Unable to enable rollback for session: " + session.sessionId); - } - } catch (RemoteException re) { - // Cannot happen, the rollback manager is in the same process. - } - } - - // Proactively mark session as ready before calling apexd. Although this call order looks - // counter-intuitive, this is the easiest way to ensure that session won't end up in the - // inconsistent state: - // - If device gets rebooted right before call to apexd, then apexd will never activate - // apex files of this staged session. This will result in StagingManager failing the - // session. - // On the other hand, if the order of the calls was inverted (first call apexd, then mark - // session as ready), then if a device gets rebooted right after the call to apexd, only - // apex part of the train will be applied, leaving device in an inconsistent state. - Slog.d(TAG, "Marking session " + session.sessionId + " as ready"); - session.setStagedSessionReady(); - if (!hasApex) { - // Session doesn't contain apex, nothing to do. - return; - } - try { - mApexManager.markStagedSessionReady(session.sessionId); - } catch (PackageManagerException e) { - session.setStagedSessionFailed(e.error, e.getMessage()); - } - } - - private boolean sessionContains(@NonNull PackageInstallerSession session, Predicate<PackageInstallerSession> filter) { if (!session.isMultiPackage()) { @@ -359,7 +295,7 @@ public class StagingManager { // Greedily re-trigger the pre-reboot verification. Slog.d(TAG, "Found pending staged session " + session.sessionId + " still to be " + "verified, resuming pre-reboot verification"); - mBgHandler.post(() -> preRebootVerification(session)); + mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId); return; } if (!apexSessionInfo.isActivated && !apexSessionInfo.isSuccess) { @@ -376,7 +312,7 @@ public class StagingManager { // The APEX part of the session is activated, proceed with the installation of APKs. try { Slog.d(TAG, "Installing APK packages in session " + session.sessionId); - installApksInSession(session, /* preReboot */ false); + installApksInSession(session); } catch (PackageManagerException e) { session.setStagedSessionFailed(e.error, e.getMessage()); @@ -467,53 +403,23 @@ public class StagingManager { } } - private void commitApkSession(@NonNull PackageInstallerSession apkSession, - int originalSessionId, boolean preReboot) throws PackageManagerException { - final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED - : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED; - if (!preReboot) { - if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) { - // If rollback is available for this session, notify the rollback - // manager of the apk session so it can properly enable rollback. - final IRollbackManager rm = IRollbackManager.Stub.asInterface( - ServiceManager.getService(Context.ROLLBACK_SERVICE)); - try { - rm.notifyStagedApkSession(originalSessionId, apkSession.sessionId); - } catch (RemoteException re) { - // Cannot happen, the rollback manager is in the same process. - } - } - } - - final LocalIntentReceiver receiver = new LocalIntentReceiver(); - apkSession.commit(receiver.getIntentSender(), false); - final Intent result = receiver.getResult(); - final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, - PackageInstaller.STATUS_FAILURE); - if (status != PackageInstaller.STATUS_SUCCESS) { - - final String errorMessage = result.getStringExtra( - PackageInstaller.EXTRA_STATUS_MESSAGE); - Slog.e(TAG, "Failure to install APK staged session " + originalSessionId + " [" - + errorMessage + "]"); - throw new PackageManagerException(errorCode, errorMessage); - } - } - - private void installApksInSession(@NonNull PackageInstallerSession session, - boolean preReboot) throws PackageManagerException { + /** + * Extract apks in the given session into a new session. Returns {@code null} if there is no + * apks in the given session. Only parent session is returned for multi-package session. + */ + @Nullable + private PackageInstallerSession extractApksInSession(PackageInstallerSession session, + boolean preReboot) throws PackageManagerException { final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED; if (!session.isMultiPackage() && !isApexSession(session)) { - // APK single-packaged staged session. Do a regular install. - PackageInstallerSession apkSession = createAndWriteApkSession(session, preReboot); - commitApkSession(apkSession, session.sessionId, preReboot); + return createAndWriteApkSession(session, preReboot); } else if (session.isMultiPackage()) { // For multi-package staged sessions containing APKs, we identify which child sessions // contain an APK, and with those then create a new multi-package group of sessions, // carrying over all the session parameters and unmarking them as staged. On commit the // sessions will be installed atomically. - List<PackageInstallerSession> childSessions; + final List<PackageInstallerSession> childSessions; synchronized (mStagedSessions) { childSessions = Arrays.stream(session.getChildSessionIds()) @@ -525,18 +431,18 @@ public class StagingManager { } if (childSessions.isEmpty()) { // APEX-only multi-package staged session, nothing to do. - return; + return null; } - PackageInstaller.SessionParams params = session.params.copy(); + final PackageInstaller.SessionParams params = session.params.copy(); params.isStaged = false; if (preReboot) { params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK; } // TODO(b/129744602): use the userid from the original session. - int apkParentSessionId = mPi.createSession( + final int apkParentSessionId = mPi.createSession( params, session.getInstallerPackageName(), 0 /* UserHandle.SYSTEM */); - PackageInstallerSession apkParentSession = mPi.getSession(apkParentSessionId); + final PackageInstallerSession apkParentSession = mPi.getSession(apkParentSessionId); try { apkParentSession.open(); } catch (IOException e) { @@ -557,35 +463,171 @@ public class StagingManager { "Failed to add a child session " + apkChildSession.sessionId); } } - commitApkSession(apkParentSession, session.sessionId, preReboot); + return apkParentSession; + } + return null; + } + + private void verifyApksInSession(PackageInstallerSession session) + throws PackageManagerException { + + final PackageInstallerSession apksToVerify = extractApksInSession( + session, /* preReboot */ true); + if (apksToVerify == null) { + return; + } + + final LocalIntentReceiverAsync receiver = new LocalIntentReceiverAsync( + (Intent result) -> { + int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, + PackageInstaller.STATUS_FAILURE); + if (status != PackageInstaller.STATUS_SUCCESS) { + final String errorMessage = result.getStringExtra( + PackageInstaller.EXTRA_STATUS_MESSAGE); + Slog.e(TAG, "Failure to verify APK staged session " + + session.sessionId + " [" + errorMessage + "]"); + session.setStagedSessionFailed( + SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, errorMessage); + return; + } + mPreRebootVerificationHandler.notifyPreRebootVerification_Apk_Complete( + session.sessionId); + }); + + apksToVerify.commit(receiver.getIntentSender(), false); + } + + private void installApksInSession(@NonNull PackageInstallerSession session) + throws PackageManagerException { + + final PackageInstallerSession apksToInstall = extractApksInSession( + session, /* preReboot */ false); + if (apksToInstall == null) { + return; + } + + if ((apksToInstall.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) { + // If rollback is available for this session, notify the rollback + // manager of the apk session so it can properly enable rollback. + final IRollbackManager rm = IRollbackManager.Stub.asInterface( + ServiceManager.getService(Context.ROLLBACK_SERVICE)); + try { + rm.notifyStagedApkSession(session.sessionId, apksToInstall.sessionId); + } catch (RemoteException re) { + Slog.e(TAG, "Failed to notifyStagedApkSession for session: " + + session.sessionId, re); + } + } + + final LocalIntentReceiverSync receiver = new LocalIntentReceiverSync(); + apksToInstall.commit(receiver.getIntentSender(), false); + final Intent result = receiver.getResult(); + final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, + PackageInstaller.STATUS_FAILURE); + if (status != PackageInstaller.STATUS_SUCCESS) { + final String errorMessage = result.getStringExtra( + PackageInstaller.EXTRA_STATUS_MESSAGE); + Slog.e(TAG, "Failure to install APK staged session " + + session.sessionId + " [" + errorMessage + "]"); + throw new PackageManagerException( + SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMessage); } - // APEX single-package staged session, nothing to do. } void commitSession(@NonNull PackageInstallerSession session) { updateStoredSession(session); - mBgHandler.post(() -> preRebootVerification(session)); + 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; } - if (!session.isStagedSessionApplied() && !session.isStagedSessionFailed()) { - return session; + + // 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 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) { @@ -612,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(); @@ -691,7 +734,7 @@ public class StagingManager { if (!session.isStagedSessionReady()) { // The framework got restarted before the pre-reboot verification could complete, // restart the verification. - mBgHandler.post(() -> preRebootVerification(session)); + mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId); } else { // Session had already being marked ready. Start the checks to verify if there is any // follow-up work. @@ -699,14 +742,34 @@ public class StagingManager { } } - private static class LocalIntentReceiver { + private static class LocalIntentReceiverAsync { + final Consumer<Intent> mConsumer; + + LocalIntentReceiverAsync(Consumer<Intent> consumer) { + mConsumer = consumer; + } + + private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { + @Override + public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, + IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { + mConsumer.accept(intent); + } + }; + + public IntentSender getIntentSender() { + return new IntentSender((IIntentSender) mLocalSender); + } + } + + private static class LocalIntentReceiverSync { private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>(); private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { @Override public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, - IIntentReceiver finishedReceiver, String requiredPermission, - Bundle options) { + IIntentReceiver finishedReceiver, String requiredPermission, + Bundle options) { try { mResult.offer(intent, 5, TimeUnit.SECONDS); } catch (InterruptedException e) { @@ -727,4 +790,188 @@ public class StagingManager { } } } + + private final class PreRebootVerificationHandler extends Handler { + + PreRebootVerificationHandler(Looper looper) { + super(looper); + } + + /** + * Handler for states of pre reboot verification. The states are arranged linearly (shown + * below) with each state either calling the next state, or calling some other method that + * eventually calls the next state. + * + * <p><ul> + * <li>MSG_PRE_REBOOT_VERIFICATION_START</li> + * <li>MSG_PRE_REBOOT_VERIFICATION_APEX</li> + * <li>MSG_PRE_REBOOT_VERIFICATION_APK</li> + * <li>MSG_PRE_REBOOT_VERIFICATION_END</li> + * </ul></p> + * + * Details about each of state can be found in corresponding handler of node. + */ + private static final int MSG_PRE_REBOOT_VERIFICATION_START = 1; + private static final int MSG_PRE_REBOOT_VERIFICATION_APEX = 2; + private static final int MSG_PRE_REBOOT_VERIFICATION_APK = 3; + private static final int MSG_PRE_REBOOT_VERIFICATION_END = 4; + + @Override + public void handleMessage(Message msg) { + final int sessionId = msg.arg1; + final PackageInstallerSession session; + synchronized (mStagedSessions) { + session = mStagedSessions.get(sessionId); + } + // Maybe session was aborted before pre-reboot verification was complete + if (session == null) { + Slog.d(TAG, "Stopping pre-reboot verification for sessionId: " + sessionId); + return; + } + switch (msg.what) { + case MSG_PRE_REBOOT_VERIFICATION_START: + handlePreRebootVerification_Start(session); + break; + case MSG_PRE_REBOOT_VERIFICATION_APEX: + handlePreRebootVerification_Apex(session); + break; + case MSG_PRE_REBOOT_VERIFICATION_APK: + handlePreRebootVerification_Apk(session); + break; + case MSG_PRE_REBOOT_VERIFICATION_END: + handlePreRebootVerification_End(session); + break; + } + } + + // Method for starting the pre-reboot verification + private void startPreRebootVerification(int sessionId) { + obtainMessage(MSG_PRE_REBOOT_VERIFICATION_START, sessionId, 0).sendToTarget(); + } + + private void notifyPreRebootVerification_Start_Complete(int sessionId) { + obtainMessage(MSG_PRE_REBOOT_VERIFICATION_APEX, sessionId, 0).sendToTarget(); + } + + private void notifyPreRebootVerification_Apex_Complete(int sessionId) { + obtainMessage(MSG_PRE_REBOOT_VERIFICATION_APK, sessionId, 0).sendToTarget(); + } + + private void notifyPreRebootVerification_Apk_Complete(int sessionId) { + obtainMessage(MSG_PRE_REBOOT_VERIFICATION_END, sessionId, 0).sendToTarget(); + } + + /** + * A dummy state for starting the pre reboot verification. + * + * See {@link PreRebootVerificationHandler} to see all nodes of pre reboot verification + */ + private void handlePreRebootVerification_Start(@NonNull PackageInstallerSession session) { + Slog.d(TAG, "Starting preRebootVerification for session " + session.sessionId); + notifyPreRebootVerification_Start_Complete(session.sessionId); + } + + /** + * Pre-reboot verification state for apex files: + * + * <p><ul> + * <li>submits session to apex service</li> + * <li>validates signatures of apex files</li> + * </ul></p> + */ + private void handlePreRebootVerification_Apex(@NonNull PackageInstallerSession session) { + final boolean hasApex = sessionContainsApex(session); + + // APEX checks. For single-package sessions, check if they contain an APEX. For + // multi-package sessions, find all the child sessions that contain an APEX. + if (hasApex) { + try { + final List<PackageInfo> apexPackages = + submitSessionToApexService(session); + for (PackageInfo apexPackage : apexPackages) { + validateApexSignature(apexPackage); + } + } catch (PackageManagerException e) { + session.setStagedSessionFailed(e.error, e.getMessage()); + return; + } + } + + notifyPreRebootVerification_Apex_Complete(session.sessionId); + } + + /** + * Pre-reboot verification state for apk files: + * <p><ul> + * <li>performs a dry-run install of apk</li> + * </ul></p> + */ + private void handlePreRebootVerification_Apk(@NonNull PackageInstallerSession session) { + if (!sessionContainsApk(session)) { + notifyPreRebootVerification_Apk_Complete(session.sessionId); + return; + } + + try { + Slog.d(TAG, "Running a pre-reboot verification for APKs in session " + + session.sessionId + " by performing a dry-run install"); + + // verifyApksInSession will notify the handler when APK verification is complete + verifyApksInSession(session); + // TODO(b/118865310): abort the session on apexd. + } catch (PackageManagerException e) { + session.setStagedSessionFailed(e.error, e.getMessage()); + } + } + + /** + * Pre-reboot verification state for wrapping up: + * <p><ul> + * <li>enables rollback if required</li> + * <li>marks session as ready</li> + * </ul></p> + */ + private void handlePreRebootVerification_End(@NonNull PackageInstallerSession session) { + if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) { + // If rollback is enabled for this session, we call through to the RollbackManager + // with the list of sessions it must enable rollback for. Note that + // notifyStagedSession is a synchronous operation. + final IRollbackManager rm = IRollbackManager.Stub.asInterface( + ServiceManager.getService(Context.ROLLBACK_SERVICE)); + try { + // NOTE: To stay consistent with the non-staged install flow, we don't fail the + // entire install if rollbacks can't be enabled. + if (!rm.notifyStagedSession(session.sessionId)) { + Slog.e(TAG, "Unable to enable rollback for session: " + + session.sessionId); + } + } catch (RemoteException re) { + Slog.e(TAG, "Failed to notifyStagedSession for session: " + + session.sessionId, re); + } + } + + // Proactively mark session as ready before calling apexd. Although this call order + // looks counter-intuitive, this is the easiest way to ensure that session won't end up + // in the inconsistent state: + // - If device gets rebooted right before call to apexd, then apexd will never activate + // apex files of this staged session. This will result in StagingManager failing + // the session. + // On the other hand, if the order of the calls was inverted (first call apexd, then + // mark session as ready), then if a device gets rebooted right after the call to apexd, + // only apex part of the train will be applied, leaving device in an inconsistent state. + Slog.d(TAG, "Marking session " + session.sessionId + " as ready"); + session.setStagedSessionReady(); + final boolean hasApex = sessionContainsApex(session); + if (!hasApex) { + // Session doesn't contain apex, nothing to do. + return; + } + try { + mApexManager.markStagedSessionReady(session.sessionId); + } catch (PackageManagerException e) { + session.setStagedSessionFailed(e.error, e.getMessage()); + } + } + } } diff --git a/services/core/java/com/android/server/role/OWNERS b/services/core/java/com/android/server/role/OWNERS new file mode 100644 index 000000000000..b94d98827d71 --- /dev/null +++ b/services/core/java/com/android/server/role/OWNERS @@ -0,0 +1,6 @@ +svetoslavganov@google.com +moltmann@google.com +zhanghai@google.com +evanseverson@google.com +eugenesusla@google.com +ntmyren@google.com diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java index b051bab71f12..8ff2a1b6364b 100644 --- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java +++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java @@ -37,9 +37,9 @@ class TimeZoneDetectorShellCommand extends ShellCommand { } switch (cmd) { - case "suggestTelephonyTimeZone": + case "suggest_telephony_time_zone": return runSuggestTelephonyTimeZone(); - case "suggestManualTimeZone": + case "suggest_manual_time_zone": return runSuggestManualTimeZone(); default: { return handleDefaultCommands(cmd); @@ -105,9 +105,9 @@ class TimeZoneDetectorShellCommand extends ShellCommand { pw.println("Time Zone Detector (time_zone_detector) commands:"); pw.println(" help"); pw.println(" Print this help text."); - pw.println(" suggestTelephonyTimeZone"); + pw.println(" suggest_telephony_time_zone"); pw.println(" --suggestion <telephony suggestion opts>"); - pw.println(" suggestManualTimeZone"); + pw.println(" suggest_manual_time_zone"); pw.println(" --suggestion <manual suggestion opts>"); pw.println(); ManualTimeZoneSuggestion.printCommandLineOpts(pw); diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java index 0eb27cc5cff0..e0b3ad526f35 100644 --- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java +++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java @@ -22,9 +22,12 @@ import android.app.timezonedetector.TelephonyTimeZoneSuggestion; import java.io.PrintWriter; /** - * The interface for the class that implement the time detection algorithm used by the + * The interface for the class that implements the time detection algorithm used by the * {@link TimeZoneDetectorService}. * + * <p>The strategy uses suggestions to decide whether to modify the device's time zone setting + * and what to set it to. + * * <p>Most calls will be handled by a single thread but that is not true for all calls. For example * {@link #dump(PrintWriter, String[])}) may be called on a different thread so implementations must * handle thread safety. @@ -33,7 +36,9 @@ import java.io.PrintWriter; */ public interface TimeZoneDetectorStrategy { - /** Process the suggested manually-entered (i.e. user sourced) time zone. */ + /** + * Suggests a time zone for the device using manually-entered (i.e. user sourced) information. + */ void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion suggestion); /** @@ -41,8 +46,7 @@ public interface TimeZoneDetectorStrategy { * {@link TelephonyTimeZoneSuggestion#getZoneId()} is {@code null}. The suggestion is scoped to * a specific {@link TelephonyTimeZoneSuggestion#getSlotIndex() slotIndex}. * See {@link TelephonyTimeZoneSuggestion} for an explanation of the metadata associated with a - * suggestion. The strategy uses suggestions to decide whether to modify the device's time zone - * setting and what to set it to. + * suggestion. */ void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion suggestion); diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java index cc33fb0f5008..d318b1a4732c 100644 --- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java @@ -276,18 +276,6 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat return; } - // Special case handling for uninitialized devices. This should only happen once. - String newZoneId = bestTelephonySuggestion.suggestion.getZoneId(); - if (newZoneId != null && !mCallback.isDeviceTimeZoneInitialized()) { - String cause = "Device has no time zone set. Attempting to set the device to the best" - + " available suggestion." - + " bestTelephonySuggestion=" + bestTelephonySuggestion - + ", detectionReason=" + detectionReason; - Slog.i(LOG_TAG, cause); - setDeviceTimeZoneIfRequired(ORIGIN_TELEPHONY, newZoneId, cause); - return; - } - boolean suggestionGoodEnough = bestTelephonySuggestion.score >= TELEPHONY_SCORE_USAGE_THRESHOLD; if (!suggestionGoodEnough) { @@ -301,6 +289,7 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat // Paranoia: Every suggestion above the SCORE_USAGE_THRESHOLD should have a non-null time // zone ID. + String newZoneId = bestTelephonySuggestion.suggestion.getZoneId(); if (newZoneId == null) { Slog.w(LOG_TAG, "Empty zone suggestion scored higher than expected. This is an error:" + " bestTelephonySuggestion=" + bestTelephonySuggestion diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 54ab906e9924..ba4e11a3d8c5 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -343,7 +343,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics(); - /** @see #computeCompatSmallestWidth(boolean, int, int, int, DisplayCutout) */ + /** @see #computeCompatSmallestWidth(boolean, int, int, int) */ private final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics(); /** @@ -1715,7 +1715,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale); config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale); config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, config.uiMode, dw, - dh, displayInfo.displayCutout); + dh); config.densityDpi = displayInfo.logicalDensityDpi; config.colorMode = @@ -1800,8 +1800,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mWmService.mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence); } - private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh, - DisplayCutout displayCutout) { + private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh) { mTmpDisplayMetrics.setTo(mDisplayMetrics); final DisplayMetrics tmpDm = mTmpDisplayMetrics; final int unrotDw, unrotDh; @@ -1812,19 +1811,21 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo unrotDw = dw; unrotDh = dh; } - int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh, - displayCutout); - sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw, - displayCutout); - sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh, - displayCutout); - sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw, - displayCutout); + int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, + unrotDh); + sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, + unrotDw); + sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, + unrotDh); + sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, + unrotDw); return sw; } private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode, - DisplayMetrics dm, int dw, int dh, DisplayCutout displayCutout) { + DisplayMetrics dm, int dw, int dh) { + final DisplayCutout displayCutout = calculateDisplayCutoutForRotation( + rotation).getDisplayCutout(); dm.noncompatWidthPixels = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayCutout); dm.noncompatHeightPixels = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, @@ -1865,20 +1866,20 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return; } int sl = Configuration.resetScreenLayout(outConfig.screenLayout); - sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode, - displayInfo.displayCutout); - sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode, - displayInfo.displayCutout); - sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode, - displayInfo.displayCutout); - sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode, - displayInfo.displayCutout); + sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode); + sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode); + sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode); + sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode); outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density); outConfig.screenLayout = sl; } private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh, - int uiMode, DisplayCutout displayCutout) { + int uiMode) { + // Get the display cutout at this rotation. + final DisplayCutout displayCutout = calculateDisplayCutoutForRotation( + rotation).getDisplayCutout(); + // Get the app screen size at this rotation. int w = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayCutout); int h = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayCutout); diff --git a/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/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 03f64fca5591..cc8d2585ff6e 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -78,6 +78,7 @@ import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE; import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA; import static android.app.admin.DevicePolicyManager.WIPE_SILENTLY; import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; +import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.provider.Settings.Global.PRIVATE_DNS_MODE; import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER; import static android.provider.Telephony.Carriers.DPC_URI; @@ -133,10 +134,6 @@ import android.app.admin.StartInstallingUpdateCallback; import android.app.admin.SystemUpdateInfo; import android.app.admin.SystemUpdatePolicy; import android.app.backup.IBackupManager; -import android.app.timedetector.ManualTimeSuggestion; -import android.app.timedetector.TimeDetector; -import android.app.timezonedetector.ManualTimeZoneSuggestion; -import android.app.timezonedetector.TimeZoneDetector; import android.app.trust.TrustManager; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; @@ -1957,14 +1954,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return mContext.getSystemService(AlarmManager.class); } - TimeDetector getTimeDetector() { - return mContext.getSystemService(TimeDetector.class); - } - - TimeZoneDetector getTimeZoneDetector() { - return mContext.getSystemService(TimeZoneDetector.class); - } - ConnectivityManager getConnectivityManager() { return mContext.getSystemService(ConnectivityManager.class); } @@ -5558,6 +5547,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } + private void enforceNetworkStackOrProfileOrDeviceOwner(ComponentName who) { + if (mContext.checkCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK) + == PackageManager.PERMISSION_GRANTED) { + return; + } + enforceProfileOrDeviceOwner(who); + } + @Override public boolean approveCaCert(String alias, int userId, boolean approval) { enforceManageUsers(); @@ -6485,7 +6482,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isAlwaysOnVpnLockdownEnabled(ComponentName admin) throws SecurityException { - enforceProfileOrDeviceOwner(admin); + enforceNetworkStackOrProfileOrDeviceOwner(admin); final int userId = mInjector.userHandleGetCallingUserId(); final long token = mInjector.binderClearCallingIdentity(); @@ -10878,10 +10875,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (mInjector.settingsGlobalGetInt(Global.AUTO_TIME, 0) == 1) { return false; } - ManualTimeSuggestion manualTimeSuggestion = TimeDetector.createManualTimeSuggestion( - millis, "DevicePolicyManagerService: setTime"); - mInjector.binderWithCleanCallingIdentity( - () -> mInjector.getTimeDetector().suggestManualTime(manualTimeSuggestion)); + mInjector.binderWithCleanCallingIdentity(() -> mInjector.getAlarmManager().setTime(millis)); return true; } @@ -10893,11 +10887,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) == 1) { return false; } - ManualTimeZoneSuggestion manualTimeZoneSuggestion = - TimeZoneDetector.createManualTimeZoneSuggestion( - timeZone, "DevicePolicyManagerService: setTimeZone"); mInjector.binderWithCleanCallingIdentity(() -> - mInjector.getTimeZoneDetector().suggestManualTimeZone(manualTimeZoneSuggestion)); + mInjector.getAlarmManager().setTimeZone(timeZone)); return true; } 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/Android.bp b/services/net/Android.bp index dbc2df8369f8..c54102fb1d3d 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -20,6 +20,44 @@ java_library_static { ], } +// Version of services.net for usage by the wifi mainline module. +// Note: This is compiled against module_current. +// TODO(b/145825329): This should be moved to networkstack-client, +// with dependencies moved to frameworks/libs/net right. +java_library { + name: "services.net-module-wifi", + srcs: [ + ":framework-services-net-module-wifi-shared-srcs", + ":net-module-utils-srcs", + "java/android/net/ip/IpClientCallbacks.java", + "java/android/net/ip/IpClientManager.java", + "java/android/net/ip/IpClientUtil.java", + "java/android/net/util/KeepalivePacketDataUtil.java", + "java/android/net/util/NetworkConstants.java", + "java/android/net/IpMemoryStore.java", + "java/android/net/NetworkMonitorManager.java", + "java/android/net/TcpKeepalivePacketData.java", + ], + sdk_version: "module_current", + libs: [ + "unsupportedappusage", + ], + static_libs: [ + "dnsresolver_aidl_interface-V2-java", + "netd_aidl_interface-unstable-java", + "netlink-client", + "networkstack-client", + "net-utils-services-common", + ], + apex_available: [ + "com.android.wifi", + ], + visibility: [ + "//frameworks/opt/net/wifi/service", + "//frameworks/opt/net/wifi/tests/wifitests", + ], +} + filegroup { name: "services-tethering-shared-srcs", srcs: [ diff --git a/services/net/java/android/net/IpMemoryStore.java b/services/net/java/android/net/IpMemoryStore.java index dcefb537d0a0..8df2e0d08e0e 100644 --- a/services/net/java/android/net/IpMemoryStore.java +++ b/services/net/java/android/net/IpMemoryStore.java @@ -18,6 +18,7 @@ package android.net; import android.annotation.NonNull; import android.content.Context; +import android.net.networkstack.ModuleNetworkStackClient; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; @@ -41,7 +42,7 @@ public class IpMemoryStore extends IpMemoryStoreClient { super(context); mService = new CompletableFuture<>(); mTailNode = new AtomicReference<CompletableFuture<IIpMemoryStore>>(mService); - getNetworkStackClient().fetchIpMemoryStore( + getModuleNetworkStackClient(context).fetchIpMemoryStore( new IIpMemoryStoreCallbacks.Stub() { @Override public void onIpMemoryStoreFetched(@NonNull final IIpMemoryStore memoryStore) { @@ -85,8 +86,8 @@ public class IpMemoryStore extends IpMemoryStoreClient { } @VisibleForTesting - protected NetworkStackClient getNetworkStackClient() { - return NetworkStackClient.getInstance(); + protected ModuleNetworkStackClient getModuleNetworkStackClient(Context context) { + return ModuleNetworkStackClient.getInstance(context); } /** Gets an instance of the memory store */ diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java index aad75ae16aa9..c0c386b3046e 100644 --- a/services/net/java/android/net/TcpKeepalivePacketData.java +++ b/services/net/java/android/net/TcpKeepalivePacketData.java @@ -74,6 +74,19 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce ipTtl = tcpDetails.ttl; } + private TcpKeepalivePacketData(final InetAddress srcAddress, int srcPort, + final InetAddress dstAddress, int dstPort, final byte[] data, int tcpSeq, + int tcpAck, int tcpWnd, int tcpWndScale, int ipTos, int ipTtl) + throws InvalidPacketException { + super(srcAddress, srcPort, dstAddress, dstPort, data); + this.tcpSeq = tcpSeq; + this.tcpAck = tcpAck; + this.tcpWnd = tcpWnd; + this.tcpWndScale = tcpWndScale; + this.ipTos = ipTos; + this.ipTtl = ipTtl; + } + /** * Factory method to create tcp keepalive packet structure. */ @@ -139,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 @@ -153,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); } /** @@ -169,7 +184,11 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce /** Write to parcel. */ public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); + out.writeString(getSrcAddress().getHostAddress()); + out.writeString(getDstAddress().getHostAddress()); + out.writeInt(getSrcPort()); + out.writeInt(getDstPort()); + out.writeByteArray(getPacket()); out.writeInt(tcpSeq); out.writeInt(tcpAck); out.writeInt(tcpWnd); @@ -178,21 +197,32 @@ public class TcpKeepalivePacketData extends KeepalivePacketData implements Parce out.writeInt(ipTtl); } - private TcpKeepalivePacketData(Parcel in) { - super(in); - tcpSeq = in.readInt(); - tcpAck = in.readInt(); - tcpWnd = in.readInt(); - tcpWndScale = in.readInt(); - ipTos = in.readInt(); - ipTtl = in.readInt(); + private static TcpKeepalivePacketData readFromParcel(Parcel in) throws InvalidPacketException { + InetAddress srcAddress = InetAddresses.parseNumericAddress(in.readString()); + InetAddress dstAddress = InetAddresses.parseNumericAddress(in.readString()); + int srcPort = in.readInt(); + int dstPort = in.readInt(); + byte[] packet = in.createByteArray(); + int tcpSeq = in.readInt(); + int tcpAck = in.readInt(); + int tcpWnd = in.readInt(); + int tcpWndScale = in.readInt(); + int ipTos = in.readInt(); + int ipTtl = in.readInt(); + return new TcpKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, packet, tcpSeq, + tcpAck, tcpWnd, tcpWndScale, ipTos, ipTtl); } /** Parcelable Creator. */ public static final @NonNull Parcelable.Creator<TcpKeepalivePacketData> CREATOR = new Parcelable.Creator<TcpKeepalivePacketData>() { public TcpKeepalivePacketData createFromParcel(Parcel in) { - return new TcpKeepalivePacketData(in); + try { + return readFromParcel(in); + } catch (InvalidPacketException e) { + throw new IllegalArgumentException( + "Invalid NAT-T keepalive data: " + e.getError()); + } } public TcpKeepalivePacketData[] newArray(int size) { @@ -206,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; @@ -221,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/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java index a3618b47171a..b329aeec4853 100644 --- a/services/net/java/android/net/ip/IpClientUtil.java +++ b/services/net/java/android/net/ip/IpClientUtil.java @@ -22,7 +22,7 @@ import android.content.Context; import android.net.DhcpResultsParcelable; import android.net.Layer2PacketParcelable; import android.net.LinkProperties; -import android.net.NetworkStackClient; +import android.net.networkstack.ModuleNetworkStackClient; import android.os.ConditionVariable; import java.io.FileDescriptor; @@ -75,11 +75,11 @@ public class IpClientUtil { * * <p>This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of * {@link IIpClientCallbacks}. - * @see {@link NetworkStackClient#makeIpClient(String, IIpClientCallbacks)} + * @see {@link ModuleNetworkStackClient#makeIpClient(String, IIpClientCallbacks)} */ public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) { - // TODO: migrate clients and remove context argument - NetworkStackClient.getInstance().makeIpClient(ifName, new IpClientCallbacksProxy(callback)); + ModuleNetworkStackClient.getInstance(context) + .makeIpClient(ifName, new IpClientCallbacksProxy(callback)); } /** 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/services/robotests/Android.bp b/services/robotests/Android.bp index a08b3e74882a..17d0bbfad171 100644 --- a/services/robotests/Android.bp +++ b/services/robotests/Android.bp @@ -27,7 +27,7 @@ android_app { "services.net", ], - libs: ["ike-stubs"], + libs: ["android.net.ipsec.ike.stubs.system"], } //################################################################## diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp index 6fcc24252ed8..a3ccc6e9dd12 100644 --- a/services/robotests/backup/Android.bp +++ b/services/robotests/backup/Android.bp @@ -29,7 +29,7 @@ android_app { "services.net", ], - libs: ["ike-stubs"], + libs: ["android.net.ipsec.ike.stubs.system"], } //################################################################## diff --git a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java deleted file mode 100644 index d192748762fe..000000000000 --- a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2018 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; - -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; -import android.os.storage.StorageManagerInternal; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class StorageManagerServiceTest { - - private StorageManagerService mService; - - @Mock private Context mContext; - @Mock private PackageManager mPm; - @Mock private PackageManagerInternal mPmi; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - LocalServices.removeServiceForTest(StorageManagerInternal.class); - - LocalServices.removeServiceForTest(PackageManagerInternal.class); - LocalServices.addService(PackageManagerInternal.class, mPmi); - - when(mContext.getPackageManager()).thenReturn(mPm); - - mService = new StorageManagerService(mContext); - } -} diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java index 0e24793a6fab..85e93df7d3dd 100644 --- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java @@ -249,6 +249,28 @@ public class CompatConfigTest { } @Test + public void testAllowRemoveOverrideNoOverride() throws Exception { + CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addDisabledChangeWithId(1234L) + .addLoggingOnlyChangeWithId(2L) + .build(); + ApplicationInfo applicationInfo = ApplicationInfoBuilder.create() + .withPackageName("com.some.package") + .build(); + when(mPackageManager.getApplicationInfo(eq("com.some.package"), anyInt())) + .thenReturn(applicationInfo); + + // Reject all override attempts. + // Force the validator to prevent overriding the change by using a user build. + when(mBuildClassifier.isDebuggableBuild()).thenReturn(false); + when(mBuildClassifier.isFinalBuild()).thenReturn(true); + // Try to remove a non existing override, and it doesn't fail. + assertThat(compatConfig.removeOverride(1234L, "com.some.package")).isFalse(); + assertThat(compatConfig.removeOverride(2L, "com.some.package")).isFalse(); + compatConfig.removePackageOverrides("com.some.package"); + } + + @Test public void testRemovePackageOverride() throws Exception { CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) .addEnabledChangeWithId(1234L) diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java index ce5d6d9be770..e295feee8cf2 100644 --- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java @@ -28,10 +28,12 @@ import static org.testng.Assert.assertThrows; import android.content.Context; import android.content.pm.PackageManager; +import android.os.Build; import androidx.test.runner.AndroidJUnit4; import com.android.internal.compat.AndroidBuildClassifier; +import com.android.internal.compat.CompatibilityChangeInfo; import org.junit.Before; import org.junit.Test; @@ -68,6 +70,48 @@ public class PlatformCompatTest { } @Test + public void testListAllChanges() { + mCompatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addEnabledChangeWithId(1L) + .addDisabledChangeWithIdAndName(2L, "change2") + .addTargetSdkChangeWithIdAndDescription(Build.VERSION_CODES.O, 3L, "description") + .addTargetSdkChangeWithId(Build.VERSION_CODES.P, 4L) + .addTargetSdkChangeWithId(Build.VERSION_CODES.Q, 5L) + .addTargetSdkChangeWithId(Build.VERSION_CODES.R, 6L) + .addLoggingOnlyChangeWithId(7L) + .build(); + mPlatformCompat = new PlatformCompat(mContext, mCompatConfig); + assertThat(mPlatformCompat.listAllChanges()).asList().containsExactly( + new CompatibilityChangeInfo(1L, "", -1, false, false, ""), + new CompatibilityChangeInfo(2L, "change2", -1, true, false, ""), + new CompatibilityChangeInfo(3L, "", Build.VERSION_CODES.O, false, false, + "description"), + new CompatibilityChangeInfo(4L, "", Build.VERSION_CODES.P, false, false, ""), + new CompatibilityChangeInfo(5L, "", Build.VERSION_CODES.Q, false, false, ""), + new CompatibilityChangeInfo(6L, "", Build.VERSION_CODES.R, false, false, ""), + new CompatibilityChangeInfo(7L, "", -1, false, true, "")); + } + + @Test + public void testListUIChanges() { + mCompatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext) + .addEnabledChangeWithId(1L) + .addDisabledChangeWithIdAndName(2L, "change2") + .addTargetSdkChangeWithIdAndDescription(Build.VERSION_CODES.O, 3L, "description") + .addTargetSdkChangeWithId(Build.VERSION_CODES.P, 4L) + .addTargetSdkChangeWithId(Build.VERSION_CODES.Q, 5L) + .addTargetSdkChangeWithId(Build.VERSION_CODES.R, 6L) + .addLoggingOnlyChangeWithId(7L) + .build(); + mPlatformCompat = new PlatformCompat(mContext, mCompatConfig); + assertThat(mPlatformCompat.listUIChanges()).asList().containsExactly( + new CompatibilityChangeInfo(1L, "", -1, false, false, ""), + new CompatibilityChangeInfo(2L, "change2", -1, true, false, ""), + new CompatibilityChangeInfo(4L, "", Build.VERSION_CODES.P, false, false, ""), + new CompatibilityChangeInfo(5L, "", Build.VERSION_CODES.Q, false, false, "")); + } + + @Test public void testRegisterListenerToSameIdThrows() throws Exception { // Registering a listener to change 1 is successful. mPlatformCompat.registerListener(1, mListener1); diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java index 0763aa284b68..2ce4c54a932b 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java @@ -22,8 +22,6 @@ import android.app.IActivityTaskManager; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.backup.IBackupManager; -import android.app.timedetector.TimeDetector; -import android.app.timezonedetector.TimeZoneDetector; import android.app.usage.UsageStatsManagerInternal; import android.content.Context; import android.content.Intent; @@ -219,16 +217,6 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi AlarmManager getAlarmManager() {return services.alarmManager;} @Override - TimeDetector getTimeDetector() { - return services.timeDetector; - } - - @Override - TimeZoneDetector getTimeZoneDetector() { - return services.timeZoneDetector; - } - - @Override LockPatternUtils newLockPatternUtils() { return services.lockPatternUtils; } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 7c0afedc63f0..9ae9824da3e2 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -63,9 +63,6 @@ import android.app.admin.DeviceAdminReceiver; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.PasswordMetrics; -import android.app.timedetector.ManualTimeSuggestion; -import android.app.timezonedetector.ManualTimeZoneSuggestion; -import android.app.timezonedetector.TimeZoneDetector; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Intent; @@ -3476,19 +3473,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; setupDeviceOwner(); dpm.setTime(admin1, 0); - - BaseMatcher<ManualTimeSuggestion> hasZeroTime = new BaseMatcher<ManualTimeSuggestion>() { - @Override - public boolean matches(Object item) { - final ManualTimeSuggestion suggestion = (ManualTimeSuggestion) item; - return suggestion.getUtcTime().getValue() == 0; - } - @Override - public void describeTo(Description description) { - description.appendText("ManualTimeSuggestion{utcTime.value=0}"); - } - }; - verify(getServices().timeDetector).suggestManualTime(argThat(hasZeroTime)); + verify(getServices().alarmManager).setTime(0); } public void testSetTimeFailWithPO() throws Exception { @@ -3508,9 +3493,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; setupDeviceOwner(); dpm.setTimeZone(admin1, "Asia/Shanghai"); - ManualTimeZoneSuggestion suggestion = - TimeZoneDetector.createManualTimeZoneSuggestion("Asia/Shanghai", "Test debug info"); - verify(getServices().timeZoneDetector).suggestManualTimeZone(suggestion); + verify(getServices().alarmManager).setTimeZone("Asia/Shanghai"); } public void testSetTimeZoneFailWithPO() throws Exception { diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java index 960f670904d6..35c115007385 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java @@ -207,8 +207,6 @@ public class DpmMockContext extends MockContext { switch (name) { case Context.ALARM_SERVICE: return mMockSystemServices.alarmManager; - case Context.TIME_DETECTOR_SERVICE: - return mMockSystemServices.timeDetector; case Context.USER_SERVICE: return mMockSystemServices.userManager; case Context.POWER_SERVICE: diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java index 16d5db9b8b96..8f0aeea3dbf8 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java @@ -31,8 +31,6 @@ import android.app.IActivityManager; import android.app.IActivityTaskManager; import android.app.NotificationManager; import android.app.backup.IBackupManager; -import android.app.timedetector.TimeDetector; -import android.app.timezonedetector.TimeZoneDetector; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; import android.content.ContentValues; @@ -109,8 +107,6 @@ public class MockSystemServices { public final TelephonyManager telephonyManager; public final AccountManager accountManager; public final AlarmManager alarmManager; - public final TimeDetector timeDetector; - public final TimeZoneDetector timeZoneDetector; public final KeyChain.KeyChainConnection keyChainConnection; /** Note this is a partial mock, not a real mock. */ public final PackageManager packageManager; @@ -150,8 +146,6 @@ public class MockSystemServices { telephonyManager = mock(TelephonyManager.class); accountManager = mock(AccountManager.class); alarmManager = mock(AlarmManager.class); - timeDetector = mock(TimeDetector.class); - timeZoneDetector = mock(TimeZoneDetector.class); keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS); // Package manager is huge, so we use a partial mock instead. diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index ece937a57247..f1662ff952f2 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -1006,7 +1006,7 @@ public class NetworkPolicyManagerServiceTest { // pretend that 512 bytes total have happened stats = new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L); + .insertEntry(TEST_IFACE, 256L, 2L, 256L, 2L); when(mStatsService.getNetworkTotalBytes(sTemplateWifi, CYCLE_START, CYCLE_END)) .thenReturn(stats.getTotalBytes()); @@ -1198,11 +1198,11 @@ public class NetworkPolicyManagerServiceTest { history.recordData(start, end, new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0)); stats.clear(); - stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL, + stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0); - stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL, + stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0); - stats.addEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL, + stats.insertEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0); reset(mNotifManager); @@ -1226,9 +1226,9 @@ public class NetworkPolicyManagerServiceTest { history.recordData(start, end, new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0)); stats.clear(); - stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL, + stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0); - stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL, + stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL, DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0); reset(mNotifManager); @@ -1260,7 +1260,7 @@ public class NetworkPolicyManagerServiceTest { // bring up wifi network with metered policy state = new NetworkState[] { buildWifi() }; stats = new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); + .insertEntry(TEST_IFACE, 0L, 0L, 0L, 0L); { when(mConnManager.getAllNetworkState()).thenReturn(state); @@ -1692,7 +1692,7 @@ public class NetworkPolicyManagerServiceTest { final int CYCLE_DAY = 15; final NetworkStats stats = new NetworkStats(0L, 1); - stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE, + stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE, 2999, 1, 2000, 1, 0); when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong())) .thenReturn(stats.getTotalBytes()); @@ -1716,7 +1716,7 @@ public class NetworkPolicyManagerServiceTest { reset(mStatsService); // Increase the usage. - stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE, + stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE, 1000, 1, 999, 1, 0); when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong())) .thenReturn(stats.getTotalBytes()); diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java index 039c2b4933e9..da34e1b792c1 100644 --- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java @@ -76,67 +76,67 @@ public class TimeZoneDetectorServiceTest { } @Test(expected = SecurityException.class) - public void testSuggestTelephonyTime_withoutPermission() { + public void testSuggestManualTimeZone_withoutPermission() { doThrow(new SecurityException("Mock")) - .when(mMockContext).enforceCallingPermission(anyString(), any()); - TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion(); + .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any()); + ManualTimeZoneSuggestion timeZoneSuggestion = createManualTimeZoneSuggestion(); try { - mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion); + mTimeZoneDetectorService.suggestManualTimeZone(timeZoneSuggestion); fail(); } finally { - verify(mMockContext).enforceCallingPermission( - eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE), + verify(mMockContext).enforceCallingOrSelfPermission( + eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE), anyString()); } } @Test - public void testSuggestTelephonyTimeZone() throws Exception { - doNothing().when(mMockContext).enforceCallingPermission(anyString(), any()); + public void testSuggestManualTimeZone() throws Exception { + doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any()); - TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion(); - mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion); + ManualTimeZoneSuggestion timeZoneSuggestion = createManualTimeZoneSuggestion(); + mTimeZoneDetectorService.suggestManualTimeZone(timeZoneSuggestion); mTestHandler.assertTotalMessagesEnqueued(1); - verify(mMockContext).enforceCallingPermission( - eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE), + verify(mMockContext).enforceCallingOrSelfPermission( + eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE), anyString()); mTestHandler.waitForMessagesToBeProcessed(); - mStubbedTimeZoneDetectorStrategy.verifySuggestTelephonyTimeZoneCalled(timeZoneSuggestion); + mStubbedTimeZoneDetectorStrategy.verifySuggestManualTimeZoneCalled(timeZoneSuggestion); } @Test(expected = SecurityException.class) - public void testSuggestManualTime_withoutPermission() { + public void testSuggestTelephonyTimeZone_withoutPermission() { doThrow(new SecurityException("Mock")) - .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any()); - ManualTimeZoneSuggestion timeZoneSuggestion = createManualTimeZoneSuggestion(); + .when(mMockContext).enforceCallingPermission(anyString(), any()); + TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion(); try { - mTimeZoneDetectorService.suggestManualTimeZone(timeZoneSuggestion); + mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion); fail(); } finally { - verify(mMockContext).enforceCallingOrSelfPermission( - eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE), + verify(mMockContext).enforceCallingPermission( + eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE), anyString()); } } @Test - public void testSuggestManualTimeZone() throws Exception { - doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any()); + public void testSuggestTelephonyTimeZone() throws Exception { + doNothing().when(mMockContext).enforceCallingPermission(anyString(), any()); - ManualTimeZoneSuggestion timeZoneSuggestion = createManualTimeZoneSuggestion(); - mTimeZoneDetectorService.suggestManualTimeZone(timeZoneSuggestion); + TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion(); + mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion); mTestHandler.assertTotalMessagesEnqueued(1); - verify(mMockContext).enforceCallingOrSelfPermission( - eq(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE), + verify(mMockContext).enforceCallingPermission( + eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE), anyString()); mTestHandler.waitForMessagesToBeProcessed(); - mStubbedTimeZoneDetectorStrategy.verifySuggestManualTimeZoneCalled(timeZoneSuggestion); + mStubbedTimeZoneDetectorStrategy.verifySuggestTelephonyTimeZoneCalled(timeZoneSuggestion); } @Test @@ -165,6 +165,10 @@ public class TimeZoneDetectorServiceTest { mStubbedTimeZoneDetectorStrategy.verifyHandleAutoTimeZoneDetectionChangedCalled(); } + private static ManualTimeZoneSuggestion createManualTimeZoneSuggestion() { + return new ManualTimeZoneSuggestion("TestZoneId"); + } + private static TelephonyTimeZoneSuggestion createTelephonyTimeZoneSuggestion() { int slotIndex = 1234; return new TelephonyTimeZoneSuggestion.Builder(slotIndex) @@ -174,26 +178,22 @@ public class TimeZoneDetectorServiceTest { .build(); } - private static ManualTimeZoneSuggestion createManualTimeZoneSuggestion() { - return new ManualTimeZoneSuggestion("TestZoneId"); - } - private static class StubbedTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy { // Call tracking. - private TelephonyTimeZoneSuggestion mLastTelephonySuggestion; private ManualTimeZoneSuggestion mLastManualSuggestion; + private TelephonyTimeZoneSuggestion mLastTelephonySuggestion; private boolean mHandleAutoTimeZoneDetectionChangedCalled; private boolean mDumpCalled; @Override - public void suggestTelephonyTimeZone(TelephonyTimeZoneSuggestion timeZoneSuggestion) { - mLastTelephonySuggestion = timeZoneSuggestion; + public void suggestManualTimeZone(ManualTimeZoneSuggestion timeZoneSuggestion) { + mLastManualSuggestion = timeZoneSuggestion; } @Override - public void suggestManualTimeZone(ManualTimeZoneSuggestion timeZoneSuggestion) { - mLastManualSuggestion = timeZoneSuggestion; + public void suggestTelephonyTimeZone(TelephonyTimeZoneSuggestion timeZoneSuggestion) { + mLastTelephonySuggestion = timeZoneSuggestion; } @Override @@ -207,18 +207,18 @@ public class TimeZoneDetectorServiceTest { } void resetCallTracking() { - mLastTelephonySuggestion = null; mLastManualSuggestion = null; + mLastTelephonySuggestion = null; mHandleAutoTimeZoneDetectionChangedCalled = false; mDumpCalled = false; } - void verifySuggestTelephonyTimeZoneCalled(TelephonyTimeZoneSuggestion expectedSuggestion) { - assertEquals(expectedSuggestion, mLastTelephonySuggestion); + void verifySuggestManualTimeZoneCalled(ManualTimeZoneSuggestion expectedSuggestion) { + assertEquals(expectedSuggestion, mLastManualSuggestion); } - public void verifySuggestManualTimeZoneCalled(ManualTimeZoneSuggestion expectedSuggestion) { - assertEquals(expectedSuggestion, mLastManualSuggestion); + void verifySuggestTelephonyTimeZoneCalled(TelephonyTimeZoneSuggestion expectedSuggestion) { + assertEquals(expectedSuggestion, mLastTelephonySuggestion); } void verifyHandleAutoTimeZoneDetectionChangedCalled() { @@ -229,5 +229,4 @@ public class TimeZoneDetectorServiceTest { assertTrue(mDumpCalled); } } - } diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java index ba309679e47a..30bb12e3e616 100644 --- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java @@ -128,43 +128,69 @@ public class TimeZoneDetectorStrategyImplTest { } @Test - public void testFirstPlausibleTelephonySuggestionAcceptedWhenTimeZoneUninitialized() { + public void testTelephonySuggestionsWhenTimeZoneUninitialized() { + assertTrue(TELEPHONY_SCORE_LOW < TELEPHONY_SCORE_USAGE_THRESHOLD); + assertTrue(TELEPHONY_SCORE_HIGH >= TELEPHONY_SCORE_USAGE_THRESHOLD); SuggestionTestCase testCase = newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, TELEPHONY_SCORE_LOW); - TelephonyTimeZoneSuggestion lowQualitySuggestion = - testCase.createSuggestion(SLOT_INDEX1, "America/New_York"); + SuggestionTestCase testCase2 = newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, + QUALITY_SINGLE_ZONE, TELEPHONY_SCORE_HIGH); - // The device time zone setting is left uninitialized. Script script = new Script() .initializeAutoTimeZoneDetection(true); - // The very first suggestion will be taken. - script.suggestTelephonyTimeZone(lowQualitySuggestion) - .verifyTimeZoneSetAndReset(lowQualitySuggestion); + // A low quality suggestions will not be taken: The device time zone setting is left + // uninitialized. + { + TelephonyTimeZoneSuggestion lowQualitySuggestion = + testCase.createSuggestion(SLOT_INDEX1, "America/New_York"); - // Assert internal service state. - QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion = - new QualifiedTelephonyTimeZoneSuggestion( - lowQualitySuggestion, testCase.expectedScore); - assertEquals(expectedScoredSuggestion, - mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); - assertEquals(expectedScoredSuggestion, - mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + script.suggestTelephonyTimeZone(lowQualitySuggestion) + .verifyTimeZoneNotSet(); - // Another low quality suggestion will be ignored now that the setting is initialized. - TelephonyTimeZoneSuggestion lowQualitySuggestion2 = - testCase.createSuggestion(SLOT_INDEX1, "America/Los_Angeles"); - script.suggestTelephonyTimeZone(lowQualitySuggestion2) - .verifyTimeZoneNotSet(); + // Assert internal service state. + QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion = + new QualifiedTelephonyTimeZoneSuggestion( + lowQualitySuggestion, testCase.expectedScore); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + } - // Assert internal service state. - QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion2 = - new QualifiedTelephonyTimeZoneSuggestion( - lowQualitySuggestion2, testCase.expectedScore); - assertEquals(expectedScoredSuggestion2, - mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); - assertEquals(expectedScoredSuggestion2, - mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + // A good quality suggestion will be used. + { + TelephonyTimeZoneSuggestion goodQualitySuggestion = + testCase2.createSuggestion(SLOT_INDEX1, "Europe/London"); + script.suggestTelephonyTimeZone(goodQualitySuggestion) + .verifyTimeZoneSetAndReset(goodQualitySuggestion); + + // Assert internal service state. + QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion = + new QualifiedTelephonyTimeZoneSuggestion( + goodQualitySuggestion, testCase2.expectedScore); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + } + + // A low quality suggestion will be accepted, but not used to set the device time zone. + { + TelephonyTimeZoneSuggestion lowQualitySuggestion2 = + testCase.createSuggestion(SLOT_INDEX1, "America/Los_Angeles"); + script.suggestTelephonyTimeZone(lowQualitySuggestion2) + .verifyTimeZoneNotSet(); + + // Assert internal service state. + QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion = + new QualifiedTelephonyTimeZoneSuggestion( + lowQualitySuggestion2, testCase.expectedScore); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + } } /** diff --git a/services/usb/OWNERS b/services/usb/OWNERS index 7897a0c8555c..8ee72b577f3c 100644 --- a/services/usb/OWNERS +++ b/services/usb/OWNERS @@ -1,4 +1,6 @@ badhri@google.com elaurent@google.com moltmann@google.com -zhangjerry@google.com +albertccwang@google.com +jameswei@google.com +howardyen@google.com
\ No newline at end of file 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/CallRedirectionService.java b/telecomm/java/android/telecom/CallRedirectionService.java index 36c637723c0a..c832f53ae073 100644 --- a/telecomm/java/android/telecom/CallRedirectionService.java +++ b/telecomm/java/android/telecom/CallRedirectionService.java @@ -38,16 +38,14 @@ import com.android.internal.telecom.ICallRedirectionService; * * <p> * Below is an example manifest registration for a {@code CallRedirectionService}. - * <pre> * {@code * <service android:name="your.package.YourCallRedirectionServiceImplementation" - * android:permission="android.permission.BIND_REDIRECTION_SERVICE"> + * android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE"> * <intent-filter> * <action android:name="android.telecom.CallRedirectionService"/> * </intent-filter> * </service> * } - * </pre> */ public abstract class CallRedirectionService extends Service { /** 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/OWNERS b/telephony/OWNERS index 58a7ea08da3f..628c48070314 100644 --- a/telephony/OWNERS +++ b/telephony/OWNERS @@ -1,18 +1,16 @@ set noparent -tgunn@google.com -breadley@google.com -hallliu@google.com -rgreenwalt@google.com -mpq@google.com amitmahajan@google.com +breadley@google.com fionaxu@google.com jackyu@google.com +hallliu@google.com +rgreenwalt@google.com +tgunn@google.com jminjie@google.com -satk@google.com shuoq@google.com refuhoo@google.com -paulye@google.com nazaninb@google.com sarahchin@google.com dbright@google.com +xiaotonj@google.com diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt new file mode 100644 index 000000000000..efe586abcfe9 --- /dev/null +++ b/telephony/api/system-current.txt @@ -0,0 +1,2151 @@ +// Signature format: 2.0 +package android.telephony { + + public final class AccessNetworkConstants { + field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff + } + + public static final class AccessNetworkConstants.NgranBands { + method public static int getFrequencyRangeGroup(int); + field public static final int FREQUENCY_RANGE_GROUP_1 = 1; // 0x1 + field public static final int FREQUENCY_RANGE_GROUP_2 = 2; // 0x2 + field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0 + } + + public final class BarringInfo implements android.os.Parcelable { + ctor public BarringInfo(); + method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy(); + } + + public final class CallAttributes implements android.os.Parcelable { + ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality); + method public int describeContents(); + method @NonNull public android.telephony.CallQuality getCallQuality(); + method public int getNetworkType(); + method @NonNull public android.telephony.PreciseCallState getPreciseCallState(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR; + } + + 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); + method public int describeContents(); + method public int getAverageRelativeJitter(); + method public int getAverageRoundTripTime(); + method public int getCallDuration(); + method public int getCodecType(); + method public int getDownlinkCallQualityLevel(); + method public int getMaxRelativeJitter(); + method public int getNumRtpPacketsNotReceived(); + method public int getNumRtpPacketsReceived(); + method public int getNumRtpPacketsTransmitted(); + method public int getNumRtpPacketsTransmittedLost(); + method public int getUplinkCallQualityLevel(); + method public boolean isIncomingSilenceDetected(); + method public boolean isOutgoingSilenceDetected(); + method public boolean isRtpInactivityDetected(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CALL_QUALITY_BAD = 4; // 0x4 + field public static final int CALL_QUALITY_EXCELLENT = 0; // 0x0 + field public static final int CALL_QUALITY_FAIR = 2; // 0x2 + field public static final int CALL_QUALITY_GOOD = 1; // 0x1 + field public static final int CALL_QUALITY_NOT_AVAILABLE = 5; // 0x5 + field public static final int CALL_QUALITY_POOR = 3; // 0x3 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR; + } + + public class CarrierConfigManager { + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName(); + method @NonNull public static android.os.PersistableBundle getDefaultConfig(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void updateConfigForPhoneId(int, String); + field public static final String KEY_CARRIER_SETUP_APP_STRING = "carrier_setup_app_string"; + field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool"; + } + + public static final class CarrierConfigManager.Wifi { + field public static final String KEY_HOTSPOT_MAX_CLIENT_COUNT = "wifi.hotspot_maximum_client_count"; + field public static final String KEY_PREFIX = "wifi."; + } + + public final class CarrierRestrictionRules implements android.os.Parcelable { + method @NonNull public java.util.List<java.lang.Boolean> areCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); + method public int describeContents(); + method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(); + method public int getDefaultCarrierRestriction(); + method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getExcludedCarriers(); + method public int getMultiSimPolicy(); + method public boolean isAllCarriersAllowed(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1; // 0x1 + field public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0; // 0x0 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CarrierRestrictionRules> CREATOR; + field public static final int MULTISIM_POLICY_NONE = 0; // 0x0 + field public static final int MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT = 1; // 0x1 + } + + public static final class CarrierRestrictionRules.Builder { + ctor public CarrierRestrictionRules.Builder(); + method @NonNull public android.telephony.CarrierRestrictionRules build(); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed(); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setDefaultCarrierRestriction(int); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setExcludedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>); + method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int); + } + + public class CbGeoUtils { + } + + public static class CbGeoUtils.Circle implements android.telephony.CbGeoUtils.Geometry { + ctor public CbGeoUtils.Circle(@NonNull android.telephony.CbGeoUtils.LatLng, double); + method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng); + method @NonNull public android.telephony.CbGeoUtils.LatLng getCenter(); + method public double getRadius(); + } + + public static interface CbGeoUtils.Geometry { + method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng); + } + + public static class CbGeoUtils.LatLng { + ctor public CbGeoUtils.LatLng(double, double); + method public double distance(@NonNull android.telephony.CbGeoUtils.LatLng); + method @NonNull public android.telephony.CbGeoUtils.LatLng subtract(@NonNull android.telephony.CbGeoUtils.LatLng); + field public final double lat; + field public final double lng; + } + + public static class CbGeoUtils.Polygon implements android.telephony.CbGeoUtils.Geometry { + ctor public CbGeoUtils.Polygon(@NonNull java.util.List<android.telephony.CbGeoUtils.LatLng>); + method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng); + method @NonNull public java.util.List<android.telephony.CbGeoUtils.LatLng> getVertices(); + } + + public abstract class CellBroadcastService extends android.app.Service { + ctor public CellBroadcastService(); + method @NonNull @WorkerThread public abstract CharSequence getCellBroadcastAreaInfo(int); + method public android.os.IBinder onBind(@Nullable android.content.Intent); + method public abstract void onCdmaCellBroadcastSms(int, @NonNull byte[], int); + method public abstract void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>); + method public abstract void onGsmCellBroadcastSms(int, @NonNull byte[]); + field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService"; + } + + public abstract class CellIdentity implements android.os.Parcelable { + method @NonNull public abstract android.telephony.CellLocation asCellLocation(); + method @NonNull public abstract android.telephony.CellIdentity sanitizeLocationInfo(); + } + + public final class CellIdentityCdma extends android.telephony.CellIdentity { + method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo(); + } + + public final class CellIdentityGsm extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityGsm sanitizeLocationInfo(); + } + + public final class CellIdentityLte extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityLte sanitizeLocationInfo(); + } + + public final class CellIdentityNr extends android.telephony.CellIdentity { + method @NonNull public android.telephony.CellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityNr sanitizeLocationInfo(); + } + + public final class CellIdentityTdscdma extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityTdscdma sanitizeLocationInfo(); + } + + public final class CellIdentityWcdma extends android.telephony.CellIdentity { + method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation(); + method @NonNull public android.telephony.CellIdentityWcdma sanitizeLocationInfo(); + } + + public final class DataFailCause { + field @Deprecated public static final int VSNCP_APN_UNATHORIZED = 2238; // 0x8be + } + + public final class DataSpecificRegistrationInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR; + } + + public final class DisconnectCause { + field public static final int ALREADY_DIALING = 72; // 0x48 + field public static final int ANSWERED_ELSEWHERE = 52; // 0x34 + field public static final int BUSY = 4; // 0x4 + field public static final int CALLING_DISABLED = 74; // 0x4a + field public static final int CALL_BARRED = 20; // 0x14 + field public static final int CALL_PULLED = 51; // 0x33 + field public static final int CANT_CALL_WHILE_RINGING = 73; // 0x49 + field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23 + field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20 + field public static final int CDMA_ALREADY_ACTIVATED = 49; // 0x31 + field public static final int CDMA_DROP = 27; // 0x1b + field public static final int CDMA_INTERCEPT = 28; // 0x1c + field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a + field public static final int CDMA_NOT_EMERGENCY = 34; // 0x22 + field public static final int CDMA_PREEMPTED = 33; // 0x21 + field public static final int CDMA_REORDER = 29; // 0x1d + field public static final int CDMA_RETRY_ORDER = 31; // 0x1f + field public static final int CDMA_SO_REJECT = 30; // 0x1e + field public static final int CONGESTION = 5; // 0x5 + field public static final int CS_RESTRICTED = 22; // 0x16 + field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18 + field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17 + field public static final int DATA_DISABLED = 54; // 0x36 + field public static final int DATA_LIMIT_REACHED = 55; // 0x37 + field public static final int DIALED_CALL_FORWARDING_WHILE_ROAMING = 57; // 0x39 + field public static final int DIALED_MMI = 39; // 0x27 + field public static final int DIAL_LOW_BATTERY = 62; // 0x3e + field public static final int DIAL_MODIFIED_TO_DIAL = 48; // 0x30 + field public static final int DIAL_MODIFIED_TO_DIAL_VIDEO = 66; // 0x42 + field public static final int DIAL_MODIFIED_TO_SS = 47; // 0x2f + field public static final int DIAL_MODIFIED_TO_USSD = 46; // 0x2e + field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL = 69; // 0x45 + field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 70; // 0x46 + field public static final int DIAL_VIDEO_MODIFIED_TO_SS = 67; // 0x43 + field public static final int DIAL_VIDEO_MODIFIED_TO_USSD = 68; // 0x44 + field public static final int EMERGENCY_PERM_FAILURE = 64; // 0x40 + field public static final int EMERGENCY_TEMP_FAILURE = 63; // 0x3f + field public static final int ERROR_UNSPECIFIED = 36; // 0x24 + field public static final int FDN_BLOCKED = 21; // 0x15 + field public static final int ICC_ERROR = 19; // 0x13 + field public static final int IMEI_NOT_ACCEPTED = 58; // 0x3a + field public static final int IMS_ACCESS_BLOCKED = 60; // 0x3c + field public static final int IMS_MERGED_SUCCESSFULLY = 45; // 0x2d + field public static final int IMS_SIP_ALTERNATE_EMERGENCY_CALL = 71; // 0x47 + field public static final int INCOMING_AUTO_REJECTED = 81; // 0x51 + field public static final int INCOMING_MISSED = 1; // 0x1 + field public static final int INCOMING_REJECTED = 16; // 0x10 + field public static final int INVALID_CREDENTIALS = 10; // 0xa + field public static final int INVALID_NUMBER = 7; // 0x7 + field public static final int LIMIT_EXCEEDED = 15; // 0xf + field public static final int LOCAL = 3; // 0x3 + field public static final int LOST_SIGNAL = 14; // 0xe + field public static final int LOW_BATTERY = 61; // 0x3d + field public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53; // 0x35 + field public static final int MMI = 6; // 0x6 + field public static final int NORMAL = 2; // 0x2 + field public static final int NORMAL_UNSPECIFIED = 65; // 0x41 + field public static final int NOT_DISCONNECTED = 0; // 0x0 + field public static final int NOT_VALID = -1; // 0xffffffff + field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26 + field public static final int NUMBER_UNREACHABLE = 8; // 0x8 + field public static final int OTASP_PROVISIONING_IN_PROCESS = 76; // 0x4c + field public static final int OUTGOING_CANCELED = 44; // 0x2c + field public static final int OUTGOING_EMERGENCY_CALL_PLACED = 80; // 0x50 + field public static final int OUTGOING_FAILURE = 43; // 0x2b + field public static final int OUT_OF_NETWORK = 11; // 0xb + field public static final int OUT_OF_SERVICE = 18; // 0x12 + field public static final int POWER_OFF = 17; // 0x11 + field public static final int SERVER_ERROR = 12; // 0xc + field public static final int SERVER_UNREACHABLE = 9; // 0x9 + field public static final int TIMED_OUT = 13; // 0xd + field public static final int TOO_MANY_ONGOING_CALLS = 75; // 0x4b + field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19 + field public static final int VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED = 50; // 0x32 + field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28 + field public static final int WIFI_LOST = 59; // 0x3b + } + + public final class ImsiEncryptionInfo implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public String getKeyIdentifier(); + method @Nullable public java.security.PublicKey getPublicKey(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ImsiEncryptionInfo> CREATOR; + } + + public final class LteVopsSupportInfo implements android.os.Parcelable { + ctor public LteVopsSupportInfo(int, int); + method public int describeContents(); + method public int getEmcBearerSupport(); + method public int getVopsSupport(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR; + field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1 + field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3 + field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2 + } + + public class MbmsDownloadSession implements java.lang.AutoCloseable { + field public static final String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload"; + } + + public class MbmsGroupCallSession implements java.lang.AutoCloseable { + field public static final String MBMS_GROUP_CALL_SERVICE_ACTION = "android.telephony.action.EmbmsGroupCall"; + } + + public class MbmsStreamingSession implements java.lang.AutoCloseable { + field public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming"; + } + + public final class ModemActivityInfo implements android.os.Parcelable { + ctor public ModemActivityInfo(long, int, int, @NonNull int[], int); + method public int describeContents(); + method public int getIdleTimeMillis(); + method public int getReceiveTimeMillis(); + method public int getSleepTimeMillis(); + method public long getTimestamp(); + method @NonNull public java.util.List<android.telephony.ModemActivityInfo.TransmitPower> getTransmitPowerInfo(); + method public boolean isValid(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR; + field public static final int TX_POWER_LEVELS = 5; // 0x5 + field public static final int TX_POWER_LEVEL_0 = 0; // 0x0 + field public static final int TX_POWER_LEVEL_1 = 1; // 0x1 + field public static final int TX_POWER_LEVEL_2 = 2; // 0x2 + field public static final int TX_POWER_LEVEL_3 = 3; // 0x3 + field public static final int TX_POWER_LEVEL_4 = 4; // 0x4 + } + + public class ModemActivityInfo.TransmitPower { + method @NonNull public android.util.Range<java.lang.Integer> getPowerRangeInDbm(); + method public int getTimeInMillis(); + } + + public final class NetworkRegistrationInfo implements android.os.Parcelable { + method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); + method public int getRegistrationState(); + method public int getRejectCause(); + method public int getRoamingType(); + method public boolean isEmergencyEnabled(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3 + field public static final int REGISTRATION_STATE_HOME = 1; // 0x1 + field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0 + field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2 + field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5 + field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4 + } + + public static final class NetworkRegistrationInfo.Builder { + ctor public NetworkRegistrationInfo.Builder(); + method @NonNull public android.telephony.NetworkRegistrationInfo build(); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List<java.lang.Integer>); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int); + } + + public abstract class NetworkService extends android.app.Service { + ctor public NetworkService(); + method public android.os.IBinder onBind(android.content.Intent); + method @Nullable public abstract android.telephony.NetworkService.NetworkServiceProvider onCreateNetworkServiceProvider(int); + field public static final String SERVICE_INTERFACE = "android.telephony.NetworkService"; + } + + public abstract class NetworkService.NetworkServiceProvider implements java.lang.AutoCloseable { + ctor public NetworkService.NetworkServiceProvider(int); + method public abstract void close(); + method public final int getSlotIndex(); + method public final void notifyNetworkRegistrationInfoChanged(); + method public void requestNetworkRegistrationInfo(int, @NonNull android.telephony.NetworkServiceCallback); + } + + public class NetworkServiceCallback { + method public void onRequestNetworkRegistrationInfoComplete(int, @Nullable android.telephony.NetworkRegistrationInfo); + field public static final int RESULT_ERROR_BUSY = 3; // 0x3 + field public static final int RESULT_ERROR_FAILED = 5; // 0x5 + field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4 + field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2 + field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1 + field public static final int RESULT_SUCCESS = 0; // 0x0 + } + + public interface NumberVerificationCallback { + method public default void onCallReceived(@NonNull String); + method public default void onVerificationFailed(int); + field public static final int REASON_CONCURRENT_REQUESTS = 4; // 0x4 + field public static final int REASON_IN_ECBM = 5; // 0x5 + field public static final int REASON_IN_EMERGENCY_CALL = 6; // 0x6 + field public static final int REASON_NETWORK_NOT_AVAILABLE = 2; // 0x2 + field public static final int REASON_TIMED_OUT = 1; // 0x1 + field public static final int REASON_TOO_MANY_CALLS = 3; // 0x3 + field public static final int REASON_UNSPECIFIED = 0; // 0x0 + } + + public final class PhoneNumberRange implements android.os.Parcelable { + ctor public PhoneNumberRange(@NonNull String, @NonNull String, @NonNull String, @NonNull String); + method public int describeContents(); + method public boolean matches(@NonNull String); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR; + } + + public class PhoneNumberUtils { + method @NonNull public static String getUsernameFromUriNumber(@NonNull String); + method public static boolean isUriNumber(@Nullable String); + method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String); + } + + public final class PreciseCallState implements android.os.Parcelable { + ctor public PreciseCallState(int, int, int, int, int); + method public int describeContents(); + method public int getBackgroundCallState(); + method public int getForegroundCallState(); + method public int getRingingCallState(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseCallState> CREATOR; + field public static final int PRECISE_CALL_STATE_ACTIVE = 1; // 0x1 + field public static final int PRECISE_CALL_STATE_ALERTING = 4; // 0x4 + field public static final int PRECISE_CALL_STATE_DIALING = 3; // 0x3 + field public static final int PRECISE_CALL_STATE_DISCONNECTED = 7; // 0x7 + field public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; // 0x8 + field public static final int PRECISE_CALL_STATE_HOLDING = 2; // 0x2 + field public static final int PRECISE_CALL_STATE_IDLE = 0; // 0x0 + field public static final int PRECISE_CALL_STATE_INCOMING = 5; // 0x5 + field public static final int PRECISE_CALL_STATE_NOT_VALID = -1; // 0xffffffff + field public static final int PRECISE_CALL_STATE_WAITING = 6; // 0x6 + } + + public final class PreciseDataConnectionState implements android.os.Parcelable { + method @Deprecated @NonNull public String getDataConnectionApn(); + method @Deprecated public int getDataConnectionApnTypeBitMask(); + method @Deprecated public int getDataConnectionFailCause(); + method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties(); + method @Deprecated public int getDataConnectionNetworkType(); + method @Deprecated public int getDataConnectionState(); + } + + public final class PreciseDisconnectCause { + field public static final int ACCESS_CLASS_BLOCKED = 260; // 0x104 + field public static final int ACCESS_INFORMATION_DISCARDED = 43; // 0x2b + field public static final int ACM_LIMIT_EXCEEDED = 68; // 0x44 + field public static final int BEARER_CAPABILITY_NOT_AUTHORIZED = 57; // 0x39 + field public static final int BEARER_NOT_AVAIL = 58; // 0x3a + field public static final int BEARER_SERVICE_NOT_IMPLEMENTED = 65; // 0x41 + field public static final int BUSY = 17; // 0x11 + field public static final int CALL_BARRED = 240; // 0xf0 + field public static final int CALL_REJECTED = 21; // 0x15 + field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1 + field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee + field public static final int CDMA_DROP = 1001; // 0x3e9 + field public static final int CDMA_INTERCEPT = 1002; // 0x3ea + field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8 + field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0 + field public static final int CDMA_PREEMPTED = 1007; // 0x3ef + field public static final int CDMA_REORDER = 1003; // 0x3eb + field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed + field public static final int CDMA_SO_REJECT = 1004; // 0x3ec + field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c + field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6 + field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64 + field public static final int DESTINATION_OUT_OF_ORDER = 27; // 0x1b + field public static final int ERROR_UNSPECIFIED = 65535; // 0xffff + field public static final int FACILITY_REJECTED = 29; // 0x1d + field public static final int FDN_BLOCKED = 241; // 0xf1 + field public static final int IMEI_NOT_ACCEPTED = 243; // 0xf3 + field public static final int IMSI_UNKNOWN_IN_VLR = 242; // 0xf2 + field public static final int INCOMING_CALLS_BARRED_WITHIN_CUG = 55; // 0x37 + field public static final int INCOMPATIBLE_DESTINATION = 88; // 0x58 + field public static final int INFORMATION_ELEMENT_NON_EXISTENT = 99; // 0x63 + field public static final int INTERWORKING_UNSPECIFIED = 127; // 0x7f + field public static final int INVALID_MANDATORY_INFORMATION = 96; // 0x60 + field public static final int INVALID_NUMBER_FORMAT = 28; // 0x1c + field public static final int INVALID_TRANSACTION_IDENTIFIER = 81; // 0x51 + field public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101; // 0x65 + field public static final int MESSAGE_TYPE_NON_IMPLEMENTED = 97; // 0x61 + field public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98; // 0x62 + field public static final int NETWORK_DETACH = 261; // 0x105 + field public static final int NETWORK_OUT_OF_ORDER = 38; // 0x26 + field public static final int NETWORK_REJECT = 252; // 0xfc + field public static final int NETWORK_RESP_TIMEOUT = 251; // 0xfb + field public static final int NORMAL = 16; // 0x10 + field public static final int NORMAL_UNSPECIFIED = 31; // 0x1f + field public static final int NOT_VALID = -1; // 0xffffffff + field public static final int NO_ANSWER_FROM_USER = 19; // 0x13 + field public static final int NO_CIRCUIT_AVAIL = 34; // 0x22 + field public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0; // 0x0 + field public static final int NO_ROUTE_TO_DESTINATION = 3; // 0x3 + field public static final int NO_USER_RESPONDING = 18; // 0x12 + field public static final int NO_VALID_SIM = 249; // 0xf9 + field public static final int NUMBER_CHANGED = 22; // 0x16 + field public static final int OEM_CAUSE_1 = 61441; // 0xf001 + field public static final int OEM_CAUSE_10 = 61450; // 0xf00a + field public static final int OEM_CAUSE_11 = 61451; // 0xf00b + field public static final int OEM_CAUSE_12 = 61452; // 0xf00c + field public static final int OEM_CAUSE_13 = 61453; // 0xf00d + field public static final int OEM_CAUSE_14 = 61454; // 0xf00e + field public static final int OEM_CAUSE_15 = 61455; // 0xf00f + field public static final int OEM_CAUSE_2 = 61442; // 0xf002 + field public static final int OEM_CAUSE_3 = 61443; // 0xf003 + field public static final int OEM_CAUSE_4 = 61444; // 0xf004 + field public static final int OEM_CAUSE_5 = 61445; // 0xf005 + field public static final int OEM_CAUSE_6 = 61446; // 0xf006 + field public static final int OEM_CAUSE_7 = 61447; // 0xf007 + field public static final int OEM_CAUSE_8 = 61448; // 0xf008 + field public static final int OEM_CAUSE_9 = 61449; // 0xf009 + field public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70; // 0x46 + field public static final int OPERATOR_DETERMINED_BARRING = 8; // 0x8 + field public static final int OUT_OF_SRV = 248; // 0xf8 + field public static final int PREEMPTION = 25; // 0x19 + field public static final int PROTOCOL_ERROR_UNSPECIFIED = 111; // 0x6f + field public static final int QOS_NOT_AVAIL = 49; // 0x31 + field public static final int RADIO_ACCESS_FAILURE = 253; // 0xfd + field public static final int RADIO_INTERNAL_ERROR = 250; // 0xfa + field public static final int RADIO_LINK_FAILURE = 254; // 0xfe + field public static final int RADIO_LINK_LOST = 255; // 0xff + field public static final int RADIO_OFF = 247; // 0xf7 + field public static final int RADIO_RELEASE_ABNORMAL = 259; // 0x103 + field public static final int RADIO_RELEASE_NORMAL = 258; // 0x102 + field public static final int RADIO_SETUP_FAILURE = 257; // 0x101 + field public static final int RADIO_UPLINK_FAILURE = 256; // 0x100 + field public static final int RECOVERY_ON_TIMER_EXPIRED = 102; // 0x66 + field public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED = 69; // 0x45 + field public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED = 50; // 0x32 + field public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47; // 0x2f + field public static final int SEMANTICALLY_INCORRECT_MESSAGE = 95; // 0x5f + field public static final int SERVICE_OPTION_NOT_AVAILABLE = 63; // 0x3f + field public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79; // 0x4f + field public static final int STATUS_ENQUIRY = 30; // 0x1e + field public static final int SWITCHING_CONGESTION = 42; // 0x2a + field public static final int TEMPORARY_FAILURE = 41; // 0x29 + field public static final int UNOBTAINABLE_NUMBER = 1; // 0x1 + field public static final int USER_NOT_MEMBER_OF_CUG = 87; // 0x57 + } + + public class ServiceState implements android.os.Parcelable { + method public void fillInNotifierBundle(@NonNull android.os.Bundle); + 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 @NonNull public static android.telephony.ServiceState newFromBundle(@NonNull android.os.Bundle); + field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2 + field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3 + field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0 + field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1 + } + + public class SignalStrength implements android.os.Parcelable { + ctor public SignalStrength(@NonNull android.telephony.SignalStrength); + } + + public final class SmsCbCmasInfo implements android.os.Parcelable { + ctor public SmsCbCmasInfo(int, int, int, int, int, int); + method public int describeContents(); + method public int getCategory(); + method public int getCertainty(); + method public int getMessageClass(); + method public int getResponseType(); + method public int getSeverity(); + method public int getUrgency(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CMAS_CATEGORY_CBRNE = 10; // 0xa + field public static final int CMAS_CATEGORY_ENV = 7; // 0x7 + field public static final int CMAS_CATEGORY_FIRE = 5; // 0x5 + field public static final int CMAS_CATEGORY_GEO = 0; // 0x0 + field public static final int CMAS_CATEGORY_HEALTH = 6; // 0x6 + field public static final int CMAS_CATEGORY_INFRA = 9; // 0x9 + field public static final int CMAS_CATEGORY_MET = 1; // 0x1 + field public static final int CMAS_CATEGORY_OTHER = 11; // 0xb + field public static final int CMAS_CATEGORY_RESCUE = 4; // 0x4 + field public static final int CMAS_CATEGORY_SAFETY = 2; // 0x2 + field public static final int CMAS_CATEGORY_SECURITY = 3; // 0x3 + field public static final int CMAS_CATEGORY_TRANSPORT = 8; // 0x8 + field public static final int CMAS_CATEGORY_UNKNOWN = -1; // 0xffffffff + field public static final int CMAS_CERTAINTY_LIKELY = 1; // 0x1 + field public static final int CMAS_CERTAINTY_OBSERVED = 0; // 0x0 + field public static final int CMAS_CERTAINTY_UNKNOWN = -1; // 0xffffffff + field public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 3; // 0x3 + field public static final int CMAS_CLASS_CMAS_EXERCISE = 5; // 0x5 + field public static final int CMAS_CLASS_EXTREME_THREAT = 1; // 0x1 + field public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 6; // 0x6 + field public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0; // 0x0 + field public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 4; // 0x4 + field public static final int CMAS_CLASS_SEVERE_THREAT = 2; // 0x2 + field public static final int CMAS_CLASS_UNKNOWN = -1; // 0xffffffff + field public static final int CMAS_RESPONSE_TYPE_ASSESS = 6; // 0x6 + field public static final int CMAS_RESPONSE_TYPE_AVOID = 5; // 0x5 + field public static final int CMAS_RESPONSE_TYPE_EVACUATE = 1; // 0x1 + field public static final int CMAS_RESPONSE_TYPE_EXECUTE = 3; // 0x3 + field public static final int CMAS_RESPONSE_TYPE_MONITOR = 4; // 0x4 + field public static final int CMAS_RESPONSE_TYPE_NONE = 7; // 0x7 + field public static final int CMAS_RESPONSE_TYPE_PREPARE = 2; // 0x2 + field public static final int CMAS_RESPONSE_TYPE_SHELTER = 0; // 0x0 + field public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1; // 0xffffffff + field public static final int CMAS_SEVERITY_EXTREME = 0; // 0x0 + field public static final int CMAS_SEVERITY_SEVERE = 1; // 0x1 + field public static final int CMAS_SEVERITY_UNKNOWN = -1; // 0xffffffff + field public static final int CMAS_URGENCY_EXPECTED = 1; // 0x1 + field public static final int CMAS_URGENCY_IMMEDIATE = 0; // 0x0 + field public static final int CMAS_URGENCY_UNKNOWN = -1; // 0xffffffff + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbCmasInfo> CREATOR; + } + + public final class SmsCbEtwsInfo implements android.os.Parcelable { + ctor public SmsCbEtwsInfo(int, boolean, boolean, boolean, @Nullable byte[]); + method public int describeContents(); + method @Nullable public byte[] getPrimaryNotificationSignature(); + method public long getPrimaryNotificationTimestamp(); + method public int getWarningType(); + method public boolean isEmergencyUserAlert(); + method public boolean isPopupAlert(); + method public boolean isPrimary(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbEtwsInfo> CREATOR; + field public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0; // 0x0 + field public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 2; // 0x2 + field public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 4; // 0x4 + field public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 3; // 0x3 + field public static final int ETWS_WARNING_TYPE_TSUNAMI = 1; // 0x1 + field public static final int ETWS_WARNING_TYPE_UNKNOWN = -1; // 0xffffffff + } + + public final class SmsCbLocation implements android.os.Parcelable { + ctor public SmsCbLocation(@NonNull String, int, int); + method public int describeContents(); + method public int getCid(); + method public int getLac(); + method @NonNull public String getPlmn(); + method public boolean isInLocationArea(@NonNull android.telephony.SmsCbLocation); + method public boolean isInLocationArea(@Nullable String, int, int); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbLocation> CREATOR; + } + + public final class SmsCbMessage implements android.os.Parcelable { + ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, int, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int, @Nullable java.util.List<android.telephony.CbGeoUtils.Geometry>, long, int, int); + method @NonNull public static android.telephony.SmsCbMessage createFromCursor(@NonNull android.database.Cursor); + method public int describeContents(); + method @Nullable public android.telephony.SmsCbCmasInfo getCmasWarningInfo(); + method @NonNull public android.content.ContentValues getContentValues(); + method public int getDataCodingScheme(); + method @Nullable public android.telephony.SmsCbEtwsInfo getEtwsWarningInfo(); + method public int getGeographicalScope(); + method @NonNull public java.util.List<android.telephony.CbGeoUtils.Geometry> getGeometries(); + method @Nullable public String getLanguageCode(); + method @NonNull public android.telephony.SmsCbLocation getLocation(); + method public int getMaximumWaitingDuration(); + method @Nullable public String getMessageBody(); + method public int getMessageFormat(); + method public int getMessagePriority(); + method public long getReceivedTime(); + method public int getSerialNumber(); + method public int getServiceCategory(); + method public int getSlotIndex(); + method public int getSubscriptionId(); + method public boolean isCmasMessage(); + method public boolean isEmergencyMessage(); + method public boolean isEtwsMessage(); + method public boolean needGeoFencingCheck(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbMessage> CREATOR; + field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3; // 0x3 + field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; // 0x0 + field public static final int GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2; // 0x2 + field public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; // 0x1 + field public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; // 0xff + field public static final int MESSAGE_FORMAT_3GPP = 1; // 0x1 + field public static final int MESSAGE_FORMAT_3GPP2 = 2; // 0x2 + field public static final int MESSAGE_PRIORITY_EMERGENCY = 3; // 0x3 + field public static final int MESSAGE_PRIORITY_INTERACTIVE = 1; // 0x1 + field public static final int MESSAGE_PRIORITY_NORMAL = 0; // 0x0 + field public static final int MESSAGE_PRIORITY_URGENT = 2; // 0x2 + } + + public final class SmsManager { + method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean copyMessageToIcc(@Nullable byte[], @NonNull byte[], int); + method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean deleteMessageFromIcc(int); + method public boolean disableCellBroadcastRange(int, int, int); + method public boolean enableCellBroadcastRange(int, int, int); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public java.util.List<android.telephony.SmsMessage> getMessagesFromIcc(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int); + field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3 + field public static final int PREMIUM_SMS_CONSENT_ASK_USER = 1; // 0x1 + field public static final int PREMIUM_SMS_CONSENT_NEVER_ALLOW = 2; // 0x2 + field public static final int PREMIUM_SMS_CONSENT_UNKNOWN = 0; // 0x0 + } + + public class SmsMessage { + method @Nullable public static android.telephony.SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[], boolean); + method @Nullable public static android.telephony.SmsMessage.SubmitPdu getSmsPdu(int, int, @Nullable String, @NonNull String, @NonNull String, long); + method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static byte[] getSubmitPduEncodedMessage(boolean, @NonNull String, @NonNull String, int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0, to=255) int, @IntRange(from=1, to=255) int, @IntRange(from=1, to=255) int); + } + + public class SubscriptionInfo implements android.os.Parcelable { + method public boolean areUiccApplicationsEnabled(); + method @Nullable public java.util.List<android.telephony.UiccAccessRule> getAccessRules(); + method public int getProfileClass(); + method public boolean isGroupDisabled(); + } + + public class SubscriptionManager { + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean canDisablePhysicalSubscription(); + method public boolean canManageSubscription(@NonNull android.telephony.SubscriptionInfo, @NonNull String); + method @NonNull public int[] getActiveAndHiddenSubscriptionIdList(); + method @NonNull public int[] getActiveSubscriptionIdList(); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String); + method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEnabledSubscriptionId(int); + method @NonNull public static android.content.res.Resources getResourcesForSubId(@NonNull android.content.Context, int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSubscriptionEnabled(int); + method public void requestEmbeddedSubscriptionInfoListRefresh(); + method public void requestEmbeddedSubscriptionInfoListRefresh(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setDisplayName(@Nullable String, int, int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setIconTint(int, int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(int, boolean); + field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED"; + field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI; + field @Deprecated public static final int PROFILE_CLASS_DEFAULT; + field public static final int PROFILE_CLASS_OPERATIONAL; + field public static final int PROFILE_CLASS_PROVISIONING; + field public static final int PROFILE_CLASS_TESTING; + field public static final int PROFILE_CLASS_UNSET; + field @NonNull public static final android.net.Uri VT_ENABLED_CONTENT_URI; + field @NonNull public static final android.net.Uri WFC_ENABLED_CONTENT_URI; + field @NonNull public static final android.net.Uri WFC_MODE_CONTENT_URI; + field @NonNull public static final android.net.Uri WFC_ROAMING_ENABLED_CONTENT_URI; + field @NonNull public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI; + } + + public class TelephonyFrameworkInitializer { + method public static void registerServiceWrappers(); + method public static void setTelephonyServiceManager(@NonNull android.os.TelephonyServiceManager); + } + + public final class TelephonyHistogram implements android.os.Parcelable { + ctor public TelephonyHistogram(int, int, int); + ctor public TelephonyHistogram(android.telephony.TelephonyHistogram); + ctor public TelephonyHistogram(android.os.Parcel); + method public void addTimeTaken(int); + method public int describeContents(); + method public int getAverageTime(); + method public int getBucketCount(); + method public int[] getBucketCounters(); + method public int[] getBucketEndPoints(); + method public int getCategory(); + method public int getId(); + method public int getMaxTime(); + method public int getMinTime(); + method public int getSampleCount(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.TelephonyHistogram> CREATOR; + field public static final int TELEPHONY_CATEGORY_RIL = 1; // 0x1 + } + + public class TelephonyManager { + method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String); + method public int checkCarrierPrivilegesForPackage(String); + method public int checkCarrierPrivilegesForPackageAnyPhone(String); + method public void dial(String); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean disableDataConnectivity(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableDataConnectivity(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableModemForSlot(int, boolean); + method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean); + 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 @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication(); + 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); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCarrierPrivilegeStatus(int); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPrivilegedPackagesForAllActiveSubscriptions(); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int); + method public String getCdmaPrlVersion(); + method public int getCurrentPhoneType(); + method public int getCurrentPhoneType(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState(); + method @Deprecated public boolean getDataEnabled(); + method @Deprecated public boolean getDataEnabled(int); + method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getDefaultRespondViaMessageApplication(); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); + method public int getMaxNumberOfSimultaneouslyActiveSims(); + method public static long getMaxNumberVerificationTimeoutMillis(); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String[] getMergedImsisFromGroup(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask(); + method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState(); + method public int getSimApplicationState(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimApplicationState(int); + method public int getSimCardState(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimCardState(int); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Locale getSimLocale(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getSupportedRadioAccessFamily(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.UiccSlotInfo[] getUiccSlotsInfo(); + method @Nullable public android.os.Bundle getVisualVoicemailSettings(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String); + method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); + method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int); + method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); + method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApnMetered(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionAllowed(); + method public boolean isDataConnectivityPossible(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled(); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled(); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn(); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isTetheringApnRequired(); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled(); + method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean matchesCurrentSimOperator(@NonNull String, int, @Nullable String); + method public boolean needsOtaServiceProvisioning(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyUserActivity(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean); + method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); + method public void requestModemActivityInfo(@NonNull android.os.ResultReceiver); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int); + method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig(); + method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings(); + 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 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 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); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRadioEnabled(boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadioPower(boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerState(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerStateForSlot(int, int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>); + method @Deprecated public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios(); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String); + method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String); + method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff(); + method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor); + method public void updateServiceLocation(); + field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED"; + field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; + field public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE"; + field public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED"; + field public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; + field public static final String ACTION_CARRIER_SIGNAL_RESET = "com.android.internal.telephony.CARRIER_SIGNAL_RESET"; + field public static final String ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED"; + field public static final String ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED"; + field public static final String ACTION_EMERGENCY_ASSISTANCE = "android.telephony.action.EMERGENCY_ASSISTANCE"; + field public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED"; + field public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED = "android.intent.action.EMERGENCY_CALL_STATE_CHANGED"; + field public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE = "com.android.omadm.service.CONFIGURATION_UPDATE"; + field public static final String ACTION_SERVICE_PROVIDERS_UPDATED = "android.telephony.action.SERVICE_PROVIDERS_UPDATED"; + field public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS = "android.telephony.action.SHOW_NOTICE_ECM_BLOCK_OTHERS"; + 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 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 + field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe + field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1 + field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0 + field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff + field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION"; + field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID"; + field @Deprecated public static final String EXTRA_APN_PROTOCOL = "apnProto"; + field public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt"; + field @Deprecated public static final String EXTRA_APN_TYPE = "apnType"; + field public static final String EXTRA_APN_TYPE_INT = "apnTypeInt"; + field public static final String EXTRA_DATA_SPN = "android.telephony.extra.DATA_SPN"; + field public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable"; + field public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE = "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE"; + field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4; // 0x4 + field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA = 1; // 0x1 + field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE = 0; // 0x0 + field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_SMS = 3; // 0x3 + field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_VOICE = 2; // 0x2 + field public static final String EXTRA_ERROR_CODE = "errorCode"; + field public static final String EXTRA_PCO_ID = "pcoId"; + field public static final String EXTRA_PCO_VALUE = "pcoValue"; + field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE"; + field public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = "android.telephony.extra.PHONE_IN_EMERGENCY_CALL"; + field public static final String EXTRA_PLMN = "android.telephony.extra.PLMN"; + field public static final String EXTRA_REDIRECTION_URL = "redirectionUrl"; + field public static final String EXTRA_SHOW_PLMN = "android.telephony.extra.SHOW_PLMN"; + field public static final String EXTRA_SHOW_SPN = "android.telephony.extra.SHOW_SPN"; + field public static final String EXTRA_SIM_COMBINATION_NAMES = "android.telephony.extra.SIM_COMBINATION_NAMES"; + field public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE = "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE"; + field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1; // 0x1 + field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0; // 0x0 + field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE"; + field public static final String EXTRA_SPN = "android.telephony.extra.SPN"; + field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL"; + field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING"; + field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff + field public static final int KEY_TYPE_EPDG = 1; // 0x1 + field public static final int KEY_TYPE_WLAN = 2; // 0x2 + field public static final String MODEM_ACTIVITY_RESULT_KEY = "controller_activity"; + field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L + field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L + field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L + field public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L + field public static final long NETWORK_TYPE_BITMASK_EVDO_0 = 16L; // 0x10L + field public static final long NETWORK_TYPE_BITMASK_EVDO_A = 32L; // 0x20L + field public static final long NETWORK_TYPE_BITMASK_EVDO_B = 2048L; // 0x800L + field public static final long NETWORK_TYPE_BITMASK_GPRS = 1L; // 0x1L + field public static final long NETWORK_TYPE_BITMASK_GSM = 32768L; // 0x8000L + field public static final long NETWORK_TYPE_BITMASK_HSDPA = 128L; // 0x80L + field public static final long NETWORK_TYPE_BITMASK_HSPA = 512L; // 0x200L + field public static final long NETWORK_TYPE_BITMASK_HSPAP = 16384L; // 0x4000L + field public static final long NETWORK_TYPE_BITMASK_HSUPA = 256L; // 0x100L + field public static final long NETWORK_TYPE_BITMASK_IWLAN = 131072L; // 0x20000L + field public static final long NETWORK_TYPE_BITMASK_LTE = 4096L; // 0x1000L + field public static final long NETWORK_TYPE_BITMASK_LTE_CA = 262144L; // 0x40000L + field public static final long NETWORK_TYPE_BITMASK_NR = 524288L; // 0x80000L + field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L + field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L + field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L + field public static final int RADIO_POWER_OFF = 0; // 0x0 + field public static final int RADIO_POWER_ON = 1; // 0x1 + field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2 + field public static final int SET_CARRIER_RESTRICTION_ERROR = 2; // 0x2 + field public static final int SET_CARRIER_RESTRICTION_NOT_SUPPORTED = 1; // 0x1 + field public static final int SET_CARRIER_RESTRICTION_SUCCESS = 0; // 0x0 + field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2 + field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1 + field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3 + field public static final int SIM_ACTIVATION_STATE_RESTRICTED = 4; // 0x4 + field public static final int SIM_ACTIVATION_STATE_UNKNOWN = 0; // 0x0 + field public static final int SIM_STATE_LOADED = 10; // 0xa + field public static final int SIM_STATE_PRESENT = 11; // 0xb + field public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; // 0x3 + field public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; // 0x1 + field public static final int SRVCC_STATE_HANDOVER_FAILED = 2; // 0x2 + field public static final int SRVCC_STATE_HANDOVER_NONE = -1; // 0xffffffff + field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0 + } + + public final class UiccAccessRule implements android.os.Parcelable { + ctor public UiccAccessRule(byte[], @Nullable String, long); + method public int describeContents(); + method public int getCarrierPrivilegeStatus(android.content.pm.PackageInfo); + method public int getCarrierPrivilegeStatus(android.content.pm.Signature, String); + method public String getCertificateHexString(); + method @Nullable public String getPackageName(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR; + } + + public class UiccSlotInfo implements android.os.Parcelable { + ctor @Deprecated public UiccSlotInfo(boolean, boolean, String, int, int, boolean); + method public int describeContents(); + method public String getCardId(); + method public int getCardStateInfo(); + method public boolean getIsActive(); + method public boolean getIsEuicc(); + method public boolean getIsExtendedApduSupported(); + method public int getLogicalSlotIdx(); + method public boolean isRemovable(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CARD_STATE_INFO_ABSENT = 1; // 0x1 + field public static final int CARD_STATE_INFO_ERROR = 3; // 0x3 + field public static final int CARD_STATE_INFO_PRESENT = 2; // 0x2 + field public static final int CARD_STATE_INFO_RESTRICTED = 4; // 0x4 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccSlotInfo> CREATOR; + } + + public abstract class VisualVoicemailService extends android.app.Service { + method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, String, short, String, android.app.PendingIntent); + method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings); + } + +} + +package android.telephony.cdma { + + public final class CdmaSmsCbProgramData implements android.os.Parcelable { + method public int describeContents(); + method public int getCategory(); + method public int getOperation(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003 + field public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001 + field public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff + field public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000 + field public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002 + field public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR; + field public static final int OPERATION_ADD_CATEGORY = 1; // 0x1 + field public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2 + field public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0 + } + +} + +package android.telephony.data { + + public final class DataCallResponse implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public java.util.List<android.net.LinkAddress> getAddresses(); + method public int getCause(); + method @NonNull public java.util.List<java.net.InetAddress> getDnsAddresses(); + method @NonNull public java.util.List<java.net.InetAddress> getGatewayAddresses(); + method public int getId(); + method @NonNull public String getInterfaceName(); + method public int getLinkStatus(); + method @Deprecated public int getMtu(); + method public int getMtuV4(); + method public int getMtuV6(); + method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses(); + method public int getProtocolType(); + method public int getSuggestedRetryTime(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR; + field public static final int LINK_STATUS_ACTIVE = 2; // 0x2 + field public static final int LINK_STATUS_DORMANT = 1; // 0x1 + field public static final int LINK_STATUS_INACTIVE = 0; // 0x0 + field public static final int LINK_STATUS_UNKNOWN = -1; // 0xffffffff + } + + public static final class DataCallResponse.Builder { + ctor public DataCallResponse.Builder(); + method @NonNull public android.telephony.data.DataCallResponse build(); + method @NonNull public android.telephony.data.DataCallResponse.Builder setAddresses(@NonNull java.util.List<android.net.LinkAddress>); + method @NonNull public android.telephony.data.DataCallResponse.Builder setCause(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setDnsAddresses(@NonNull java.util.List<java.net.InetAddress>); + method @NonNull public android.telephony.data.DataCallResponse.Builder setGatewayAddresses(@NonNull java.util.List<java.net.InetAddress>); + method @NonNull public android.telephony.data.DataCallResponse.Builder setId(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setInterfaceName(@NonNull String); + method @NonNull public android.telephony.data.DataCallResponse.Builder setLinkStatus(int); + method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV4(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>); + method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int); + } + + public final class DataProfile implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public String getApn(); + method public int getAuthType(); + method public int getBearerBitmask(); + method @Deprecated public int getMtu(); + method public int getMtuV4(); + method public int getMtuV6(); + method @Nullable public String getPassword(); + method public int getProfileId(); + method public int getProtocolType(); + method public int getRoamingProtocolType(); + method public int getSupportedApnTypesBitmask(); + method public int getType(); + method @Nullable public String getUserName(); + method public boolean isEnabled(); + method public boolean isPersistent(); + method public boolean isPreferred(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataProfile> CREATOR; + field public static final int TYPE_3GPP = 1; // 0x1 + field public static final int TYPE_3GPP2 = 2; // 0x2 + field public static final int TYPE_COMMON = 0; // 0x0 + } + + public static final class DataProfile.Builder { + ctor public DataProfile.Builder(); + method @NonNull public android.telephony.data.DataProfile build(); + method @NonNull public android.telephony.data.DataProfile.Builder enable(boolean); + method @NonNull public android.telephony.data.DataProfile.Builder setApn(@NonNull String); + method @NonNull public android.telephony.data.DataProfile.Builder setAuthType(int); + method @NonNull public android.telephony.data.DataProfile.Builder setBearerBitmask(int); + method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setMtu(int); + method @NonNull public android.telephony.data.DataProfile.Builder setMtuV4(int); + method @NonNull public android.telephony.data.DataProfile.Builder setMtuV6(int); + method @NonNull public android.telephony.data.DataProfile.Builder setPassword(@NonNull String); + method @NonNull public android.telephony.data.DataProfile.Builder setPersistent(boolean); + method @NonNull public android.telephony.data.DataProfile.Builder setPreferred(boolean); + method @NonNull public android.telephony.data.DataProfile.Builder setProfileId(int); + method @NonNull public android.telephony.data.DataProfile.Builder setProtocolType(int); + method @NonNull public android.telephony.data.DataProfile.Builder setRoamingProtocolType(int); + method @NonNull public android.telephony.data.DataProfile.Builder setSupportedApnTypesBitmask(int); + method @NonNull public android.telephony.data.DataProfile.Builder setType(int); + method @NonNull public android.telephony.data.DataProfile.Builder setUserName(@NonNull String); + } + + public abstract class DataService extends android.app.Service { + ctor public DataService(); + method public android.os.IBinder onBind(android.content.Intent); + method @Nullable public abstract android.telephony.data.DataService.DataServiceProvider onCreateDataServiceProvider(int); + field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3 + field public static final int REQUEST_REASON_NORMAL = 1; // 0x1 + field public static final int REQUEST_REASON_SHUTDOWN = 2; // 0x2 + field public static final int REQUEST_REASON_UNKNOWN = 0; // 0x0 + field public static final String SERVICE_INTERFACE = "android.telephony.data.DataService"; + } + + public abstract class DataService.DataServiceProvider implements java.lang.AutoCloseable { + ctor public DataService.DataServiceProvider(int); + method public abstract void close(); + method public void deactivateDataCall(int, int, @Nullable android.telephony.data.DataServiceCallback); + method public final int getSlotIndex(); + method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>); + method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback); + method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback); + method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback); + method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback); + } + + public class DataServiceCallback { + method public void onDataCallListChanged(@NonNull java.util.List<android.telephony.data.DataCallResponse>); + method public void onDeactivateDataCallComplete(int); + method public void onRequestDataCallListComplete(int, @NonNull java.util.List<android.telephony.data.DataCallResponse>); + method public void onSetDataProfileComplete(int); + method public void onSetInitialAttachApnComplete(int); + method public void onSetupDataCallComplete(int, @Nullable android.telephony.data.DataCallResponse); + field public static final int RESULT_ERROR_BUSY = 3; // 0x3 + field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4 + field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2 + field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1 + field public static final int RESULT_SUCCESS = 0; // 0x0 + } + + public abstract class QualifiedNetworksService extends android.app.Service { + ctor public QualifiedNetworksService(); + method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int); + field public static final String QUALIFIED_NETWORKS_SERVICE_INTERFACE = "android.telephony.data.QualifiedNetworksService"; + } + + public abstract class QualifiedNetworksService.NetworkAvailabilityProvider implements java.lang.AutoCloseable { + ctor public QualifiedNetworksService.NetworkAvailabilityProvider(int); + method public abstract void close(); + method public final int getSlotIndex(); + method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>); + } + +} + +package android.telephony.euicc { + + public final class DownloadableSubscription implements android.os.Parcelable { + method public java.util.List<android.telephony.UiccAccessRule> getAccessRules(); + method @Nullable public String getCarrierName(); + } + + public static final class DownloadableSubscription.Builder { + ctor public DownloadableSubscription.Builder(); + ctor public DownloadableSubscription.Builder(android.telephony.euicc.DownloadableSubscription); + method public android.telephony.euicc.DownloadableSubscription build(); + method public android.telephony.euicc.DownloadableSubscription.Builder setAccessRules(java.util.List<android.telephony.UiccAccessRule>); + method public android.telephony.euicc.DownloadableSubscription.Builder setCarrierName(String); + method public android.telephony.euicc.DownloadableSubscription.Builder setConfirmationCode(String); + method public android.telephony.euicc.DownloadableSubscription.Builder setEncodedActivationCode(String); + } + + public class EuiccCardManager { + method public void authenticateServer(String, String, byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); + method public void cancelSession(String, byte[], @android.telephony.euicc.EuiccCardManager.CancelReason int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); + method public void deleteProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); + method public void disableProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); + method public void listNotifications(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>); + method public void loadBoundProfilePackage(String, byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); + method public void prepareDownload(String, @Nullable byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); + method public void removeNotificationFromList(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); + method public void requestAllProfiles(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo[]>); + method public void requestDefaultSmdpAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>); + method public void requestEuiccChallenge(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); + method public void requestEuiccInfo1(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); + method public void requestEuiccInfo2(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>); + method public void requestProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>); + method public void requestRulesAuthTable(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccRulesAuthTable>); + method public void requestSmdsAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>); + method public void resetMemory(String, @android.telephony.euicc.EuiccCardManager.ResetOption int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); + method public void retrieveNotification(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification>); + method public void retrieveNotificationList(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>); + method public void setDefaultSmdpAddress(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); + method public void setNickname(String, String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>); + method public void switchToProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>); + field public static final int CANCEL_REASON_END_USER_REJECTED = 0; // 0x0 + field public static final int CANCEL_REASON_POSTPONED = 1; // 0x1 + field public static final int CANCEL_REASON_PPR_NOT_ALLOWED = 3; // 0x3 + field public static final int CANCEL_REASON_TIMEOUT = 2; // 0x2 + field public static final int RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 2; // 0x2 + field public static final int RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1; // 0x1 + field public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 4; // 0x4 + field public static final int RESULT_CALLER_NOT_ALLOWED = -3; // 0xfffffffd + field public static final int RESULT_EUICC_NOT_FOUND = -2; // 0xfffffffe + field public static final int RESULT_OK = 0; // 0x0 + field public static final int RESULT_UNKNOWN_ERROR = -1; // 0xffffffff + } + + @IntDef(prefix={"CANCEL_REASON_"}, value={android.telephony.euicc.EuiccCardManager.CANCEL_REASON_END_USER_REJECTED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_POSTPONED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_TIMEOUT, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_PPR_NOT_ALLOWED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.CancelReason { + } + + @IntDef(flag=true, prefix={"RESET_OPTION_"}, value={android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.ResetOption { + } + + public static interface EuiccCardManager.ResultCallback<T> { + method public void onComplete(int, T); + } + + public class EuiccManager { + method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void continueOperation(android.content.Intent, android.os.Bundle); + method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@NonNull android.app.PendingIntent); + method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@android.telephony.euicc.EuiccCardManager.ResetOption int, @NonNull android.app.PendingIntent); + method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDefaultDownloadableSubscriptionList(android.app.PendingIntent); + method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDownloadableSubscriptionMetadata(android.telephony.euicc.DownloadableSubscription, android.app.PendingIntent); + method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public int getOtaStatus(); + method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getSupportedCountries(); + method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getUnsupportedCountries(); + method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public boolean isSupportedCountry(@NonNull String); + method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setSupportedCountries(@NonNull java.util.List<java.lang.String>); + method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setUnsupportedCountries(@NonNull java.util.List<java.lang.String>); + field public static final String ACTION_DELETE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED"; + field @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public static final String ACTION_OTA_STATUS_CHANGED = "android.telephony.euicc.action.OTA_STATUS_CHANGED"; + field public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION"; + field public static final String ACTION_RENAME_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED"; + field public static final String ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED"; + field public static final int EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED = 4; // 0x4 + field public static final int EUICC_ACTIVATION_TYPE_BACKUP = 2; // 0x2 + field public static final int EUICC_ACTIVATION_TYPE_DEFAULT = 1; // 0x1 + field public static final int EUICC_ACTIVATION_TYPE_TRANSFER = 3; // 0x3 + field public static final int EUICC_OTA_FAILED = 2; // 0x2 + field public static final int EUICC_OTA_IN_PROGRESS = 1; // 0x1 + field public static final int EUICC_OTA_NOT_NEEDED = 4; // 0x4 + field public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; // 0x5 + field public static final int EUICC_OTA_SUCCEEDED = 3; // 0x3 + field public static final String EXTRA_ACTIVATION_TYPE = "android.telephony.euicc.extra.ACTIVATION_TYPE"; + field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS"; + field public static final String EXTRA_ENABLE_SUBSCRIPTION = "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION"; + field public static final String EXTRA_FORCE_PROVISION = "android.telephony.euicc.extra.FORCE_PROVISION"; + field public static final String EXTRA_FROM_SUBSCRIPTION_ID = "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID"; + field public static final String EXTRA_PHYSICAL_SLOT_ID = "android.telephony.euicc.extra.PHYSICAL_SLOT_ID"; + field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.euicc.extra.SUBSCRIPTION_ID"; + field public static final String EXTRA_SUBSCRIPTION_NICKNAME = "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME"; + } + + @IntDef(prefix={"EUICC_OTA_"}, value={android.telephony.euicc.EuiccManager.EUICC_OTA_IN_PROGRESS, android.telephony.euicc.EuiccManager.EUICC_OTA_FAILED, android.telephony.euicc.EuiccManager.EUICC_OTA_SUCCEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_NOT_NEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccManager.OtaStatus { + } + + public final class EuiccNotification implements android.os.Parcelable { + ctor public EuiccNotification(int, String, @android.telephony.euicc.EuiccNotification.Event int, @Nullable byte[]); + method public int describeContents(); + method @Nullable public byte[] getData(); + method @android.telephony.euicc.EuiccNotification.Event public int getEvent(); + method public int getSeq(); + method public String getTargetAddr(); + method public void writeToParcel(android.os.Parcel, int); + field @android.telephony.euicc.EuiccNotification.Event public static final int ALL_EVENTS = 15; // 0xf + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccNotification> CREATOR; + field public static final int EVENT_DELETE = 8; // 0x8 + field public static final int EVENT_DISABLE = 4; // 0x4 + field public static final int EVENT_ENABLE = 2; // 0x2 + field public static final int EVENT_INSTALL = 1; // 0x1 + } + + @IntDef(flag=true, prefix={"EVENT_"}, value={android.telephony.euicc.EuiccNotification.EVENT_INSTALL, android.telephony.euicc.EuiccNotification.EVENT_ENABLE, android.telephony.euicc.EuiccNotification.EVENT_DISABLE, android.telephony.euicc.EuiccNotification.EVENT_DELETE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccNotification.Event { + } + + public final class EuiccRulesAuthTable implements android.os.Parcelable { + method public int describeContents(); + method public int findIndex(@android.service.euicc.EuiccProfileInfo.PolicyRule int, android.service.carrier.CarrierIdentifier); + method public boolean hasPolicyRuleFlag(int, @android.telephony.euicc.EuiccRulesAuthTable.PolicyRuleFlag int); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccRulesAuthTable> CREATOR; + field public static final int POLICY_RULE_FLAG_CONSENT_REQUIRED = 1; // 0x1 + } + + public static final class EuiccRulesAuthTable.Builder { + ctor public EuiccRulesAuthTable.Builder(int); + method public android.telephony.euicc.EuiccRulesAuthTable.Builder add(int, java.util.List<android.service.carrier.CarrierIdentifier>, int); + method public android.telephony.euicc.EuiccRulesAuthTable build(); + } + + @IntDef(flag=true, prefix={"POLICY_RULE_FLAG_"}, value={android.telephony.euicc.EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccRulesAuthTable.PolicyRuleFlag { + } + +} + +package android.telephony.ims { + + public final class ImsCallForwardInfo implements android.os.Parcelable { + ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int); + method public int describeContents(); + method public int getCondition(); + method public String getNumber(); + method public int getServiceClass(); + method public int getStatus(); + method public int getTimeSeconds(); + method public int getToA(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CDIV_CF_REASON_ALL = 4; // 0x4 + field public static final int CDIV_CF_REASON_ALL_CONDITIONAL = 5; // 0x5 + field public static final int CDIV_CF_REASON_BUSY = 1; // 0x1 + field public static final int CDIV_CF_REASON_NOT_LOGGED_IN = 6; // 0x6 + field public static final int CDIV_CF_REASON_NOT_REACHABLE = 3; // 0x3 + field public static final int CDIV_CF_REASON_NO_REPLY = 2; // 0x2 + field public static final int CDIV_CF_REASON_UNCONDITIONAL = 0; // 0x0 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallForwardInfo> CREATOR; + field public static final int STATUS_ACTIVE = 1; // 0x1 + field public static final int STATUS_NOT_ACTIVE = 0; // 0x0 + field public static final int TYPE_OF_ADDRESS_INTERNATIONAL = 145; // 0x91 + field public static final int TYPE_OF_ADDRESS_UNKNOWN = 129; // 0x81 + } + + public final class ImsCallProfile implements android.os.Parcelable { + ctor public ImsCallProfile(); + ctor public ImsCallProfile(int, int); + ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile); + method public int describeContents(); + method public String getCallExtra(String); + method public String getCallExtra(String, String); + method public boolean getCallExtraBoolean(String); + method public boolean getCallExtraBoolean(String, boolean); + method public int getCallExtraInt(String); + method public int getCallExtraInt(String, int); + method public android.os.Bundle getCallExtras(); + method public int getCallType(); + method public static int getCallTypeFromVideoState(int); + method public int getCallerNumberVerificationStatus(); + method public int getEmergencyCallRouting(); + method public int getEmergencyServiceCategories(); + method @NonNull public java.util.List<java.lang.String> getEmergencyUrns(); + method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile(); + method @NonNull public android.os.Bundle getProprietaryCallExtras(); + method public int getRestrictCause(); + method public int getServiceType(); + method public static int getVideoStateFromCallType(int); + method public static int getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile); + method public boolean hasKnownUserIntentEmergency(); + method public boolean isEmergencyCallTesting(); + method public boolean isVideoCall(); + method public boolean isVideoPaused(); + method public static int presentationToOir(int); + method public void setCallExtra(String, String); + method public void setCallExtraBoolean(String, boolean); + method public void setCallExtraInt(String, int); + method public void setCallRestrictCause(int); + method public void setCallerNumberVerificationStatus(int); + method public void setEmergencyCallRouting(int); + method public void setEmergencyCallTesting(boolean); + method public void setEmergencyServiceCategories(int); + method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>); + method public void setHasKnownUserIntentEmergency(boolean); + method public void updateCallExtras(android.telephony.ims.ImsCallProfile); + method public void updateCallType(android.telephony.ims.ImsCallProfile); + method public void updateMediaProfile(android.telephony.ims.ImsCallProfile); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; // 0x2 + field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3 + field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0 + field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1 + field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3 + field public static final int CALL_TYPE_VOICE = 2; // 0x2 + field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1 + field public static final int CALL_TYPE_VS = 8; // 0x8 + field public static final int CALL_TYPE_VS_RX = 10; // 0xa + field public static final int CALL_TYPE_VS_TX = 9; // 0x9 + field public static final int CALL_TYPE_VT = 4; // 0x4 + field public static final int CALL_TYPE_VT_NODIR = 7; // 0x7 + field public static final int CALL_TYPE_VT_RX = 6; // 0x6 + field public static final int CALL_TYPE_VT_TX = 5; // 0x5 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallProfile> CREATOR; + field public static final int DIALSTRING_NORMAL = 0; // 0x0 + field public static final int DIALSTRING_SS_CONF = 1; // 0x1 + field public static final int DIALSTRING_USSD = 2; // 0x2 + field public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo"; + field public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS"; + field public static final String EXTRA_CALL_DISCONNECT_CAUSE = "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE"; + field public static final String EXTRA_CALL_NETWORK_TYPE = "android.telephony.ims.extra.CALL_NETWORK_TYPE"; + field @Deprecated public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech"; + field public static final String EXTRA_CHILD_NUMBER = "ChildNum"; + field public static final String EXTRA_CNA = "cna"; + field public static final String EXTRA_CNAP = "cnap"; + field public static final String EXTRA_CODEC = "Codec"; + field public static final String EXTRA_DIALSTRING = "dialstring"; + field public static final String EXTRA_DISPLAY_TEXT = "DisplayText"; + field public static final String EXTRA_EMERGENCY_CALL = "e_call"; + field public static final String EXTRA_FORWARDED_NUMBER = "android.telephony.ims.extra.FORWARDED_NUMBER"; + field public static final String EXTRA_IS_CALL_PULL = "CallPull"; + field public static final String EXTRA_OI = "oi"; + field public static final String EXTRA_OIR = "oir"; + field public static final String EXTRA_REMOTE_URI = "remote_uri"; + field public static final String EXTRA_USSD = "ussd"; + field public static final int OIR_DEFAULT = 0; // 0x0 + field public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; // 0x2 + field public static final int OIR_PRESENTATION_PAYPHONE = 4; // 0x4 + field public static final int OIR_PRESENTATION_RESTRICTED = 1; // 0x1 + field public static final int OIR_PRESENTATION_UNKNOWN = 3; // 0x3 + field public static final int SERVICE_TYPE_EMERGENCY = 2; // 0x2 + field public static final int SERVICE_TYPE_NONE = 0; // 0x0 + field public static final int SERVICE_TYPE_NORMAL = 1; // 0x1 + field public static final int VERIFICATION_STATUS_FAILED = 2; // 0x2 + field public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0; // 0x0 + field public static final int VERIFICATION_STATUS_PASSED = 1; // 0x1 + } + + public class ImsCallSessionListener { + method public void callQualityChanged(@NonNull android.telephony.CallQuality); + method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile); + method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile); + method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState); + method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo); + method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo); + method public void callSessionHeld(android.telephony.ims.ImsCallProfile); + method public void callSessionHoldFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionHoldReceived(android.telephony.ims.ImsCallProfile); + method public void callSessionInitiated(android.telephony.ims.ImsCallProfile); + method public void callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionInviteParticipantsRequestDelivered(); + method public void callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo); + method @Deprecated public void callSessionMayHandover(int, int); + method public void callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase); + method public void callSessionMergeFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile); + method public void callSessionMultipartyStateChanged(boolean); + method public void callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile); + method public void callSessionRemoveParticipantsRequestDelivered(); + method public void callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile); + method public void callSessionResumed(android.telephony.ims.ImsCallProfile); + method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile); + method public void callSessionRttMessageReceived(String); + method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile); + method public void callSessionRttModifyResponseReceived(int); + method public void callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification); + method public void callSessionTerminated(android.telephony.ims.ImsReasonInfo); + method public void callSessionTtyModeReceived(int); + method public void callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionUpdateReceived(android.telephony.ims.ImsCallProfile); + method public void callSessionUpdated(android.telephony.ims.ImsCallProfile); + method public void callSessionUssdMessageReceived(int, String); + method public void onHandover(int, int, @Nullable android.telephony.ims.ImsReasonInfo); + method public void onHandoverFailed(int, int, @NonNull android.telephony.ims.ImsReasonInfo); + method public void onMayHandover(int, int); + } + + public final class ImsConferenceState implements android.os.Parcelable { + method public int describeContents(); + method public static int getConnectionStateForStatus(String); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsConferenceState> CREATOR; + field public static final String DISPLAY_TEXT = "display-text"; + field public static final String ENDPOINT = "endpoint"; + field public static final String SIP_STATUS_CODE = "sipstatuscode"; + field public static final String STATUS = "status"; + field public static final String STATUS_ALERTING = "alerting"; + field public static final String STATUS_CONNECTED = "connected"; + field public static final String STATUS_CONNECT_FAIL = "connect-fail"; + field public static final String STATUS_DIALING_IN = "dialing-in"; + field public static final String STATUS_DIALING_OUT = "dialing-out"; + field public static final String STATUS_DISCONNECTED = "disconnected"; + field public static final String STATUS_DISCONNECTING = "disconnecting"; + field public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus"; + field public static final String STATUS_ON_HOLD = "on-hold"; + field public static final String STATUS_PENDING = "pending"; + field public static final String STATUS_SEND_ONLY = "sendonly"; + field public static final String STATUS_SEND_RECV = "sendrecv"; + field public static final String USER = "user"; + field public final java.util.HashMap<java.lang.String,android.os.Bundle> mParticipants; + } + + public final class ImsException extends java.lang.Exception { + ctor public ImsException(@Nullable String); + ctor public ImsException(@Nullable String, int); + ctor public ImsException(@Nullable String, int, @Nullable Throwable); + } + + public final class ImsExternalCallState implements android.os.Parcelable { + ctor public ImsExternalCallState(@NonNull String, @NonNull android.net.Uri, @Nullable android.net.Uri, boolean, int, int, boolean); + method public int describeContents(); + method @NonNull public android.net.Uri getAddress(); + method public int getCallId(); + method public int getCallState(); + method public int getCallType(); + method @Nullable public android.net.Uri getLocalAddress(); + method public boolean isCallHeld(); + method public boolean isCallPullable(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CALL_STATE_CONFIRMED = 1; // 0x1 + field public static final int CALL_STATE_TERMINATED = 2; // 0x2 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsExternalCallState> CREATOR; + } + + public class ImsMmTelManager implements android.telephony.ims.RegistrationManager { + method @Deprecated @NonNull @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException; + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAvailable(int, int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isCapable(int, int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void isSupported(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>) throws android.telephony.ims.ImsException; + method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException; + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiModeSetting(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiNonPersistent(boolean, int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingModeSetting(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingSettingEnabled(boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean); + method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback); + } + + @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback { + ctor @Deprecated public ImsMmTelManager.RegistrationCallback(); + } + + public final class ImsReasonInfo implements android.os.Parcelable { + field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service"; + } + + public class ImsService extends android.app.Service { + ctor public ImsService(); + method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int); + method public android.telephony.ims.feature.RcsFeature createRcsFeature(int); + method public void disableIms(int); + method public void enableIms(int); + method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int); + method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int); + method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException; + method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures(); + method public void readyForFeatureCreation(); + } + + public final class ImsSsData implements android.os.Parcelable { + ctor public ImsSsData(int, int, int, int, int); + method public int describeContents(); + method @Nullable public java.util.List<android.telephony.ims.ImsCallForwardInfo> getCallForwardInfo(); + method public int getRequestType(); + method public int getResult(); + method public int getServiceClass(); + method public int getServiceType(); + method @NonNull public java.util.List<android.telephony.ims.ImsSsInfo> getSuppServiceInfo(); + method public int getTeleserviceType(); + method public boolean isTypeBarring(); + method public boolean isTypeCf(); + method public boolean isTypeClip(); + method public boolean isTypeClir(); + method public boolean isTypeColp(); + method public boolean isTypeColr(); + method public boolean isTypeCw(); + method public boolean isTypeIcb(); + method public boolean isTypeInterrogation(); + method public boolean isTypeUnConditional(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsData> CREATOR; + field public static final int RESULT_SUCCESS = 0; // 0x0 + field public static final int SERVICE_CLASS_DATA = 2; // 0x2 + field public static final int SERVICE_CLASS_DATA_CIRCUIT_ASYNC = 32; // 0x20 + field public static final int SERVICE_CLASS_DATA_CIRCUIT_SYNC = 16; // 0x10 + field public static final int SERVICE_CLASS_DATA_PACKET_ACCESS = 64; // 0x40 + field public static final int SERVICE_CLASS_DATA_PAD = 128; // 0x80 + field public static final int SERVICE_CLASS_FAX = 4; // 0x4 + field public static final int SERVICE_CLASS_NONE = 0; // 0x0 + field public static final int SERVICE_CLASS_SMS = 8; // 0x8 + field public static final int SERVICE_CLASS_VOICE = 1; // 0x1 + field public static final int SS_ACTIVATION = 0; // 0x0 + field public static final int SS_ALL_BARRING = 18; // 0x12 + field public static final int SS_ALL_DATA_TELESERVICES = 3; // 0x3 + field public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; // 0x5 + field public static final int SS_ALL_TELESEVICES = 1; // 0x1 + field public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; // 0x0 + field public static final int SS_BAIC = 16; // 0x10 + field public static final int SS_BAIC_ROAMING = 17; // 0x11 + field public static final int SS_BAOC = 13; // 0xd + field public static final int SS_BAOIC = 14; // 0xe + field public static final int SS_BAOIC_EXC_HOME = 15; // 0xf + field public static final int SS_CFU = 0; // 0x0 + field public static final int SS_CFUT = 6; // 0x6 + field public static final int SS_CF_ALL = 4; // 0x4 + field public static final int SS_CF_ALL_CONDITIONAL = 5; // 0x5 + field public static final int SS_CF_BUSY = 1; // 0x1 + field public static final int SS_CF_NOT_REACHABLE = 3; // 0x3 + field public static final int SS_CF_NO_REPLY = 2; // 0x2 + field public static final int SS_CLIP = 7; // 0x7 + field public static final int SS_CLIR = 8; // 0x8 + field public static final int SS_CNAP = 11; // 0xb + field public static final int SS_COLP = 9; // 0x9 + field public static final int SS_COLR = 10; // 0xa + field public static final int SS_DEACTIVATION = 1; // 0x1 + field public static final int SS_ERASURE = 4; // 0x4 + field public static final int SS_INCOMING_BARRING = 20; // 0x14 + field public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; // 0x16 + field public static final int SS_INCOMING_BARRING_DN = 21; // 0x15 + field public static final int SS_INTERROGATION = 2; // 0x2 + field public static final int SS_OUTGOING_BARRING = 19; // 0x13 + field public static final int SS_REGISTRATION = 3; // 0x3 + field public static final int SS_SMS_SERVICES = 4; // 0x4 + field public static final int SS_TELEPHONY = 2; // 0x2 + field public static final int SS_WAIT = 12; // 0xc + } + + public static final class ImsSsData.Builder { + ctor public ImsSsData.Builder(int, int, int, int, int); + method @NonNull public android.telephony.ims.ImsSsData build(); + method @NonNull public android.telephony.ims.ImsSsData.Builder setCallForwardingInfo(@NonNull java.util.List<android.telephony.ims.ImsCallForwardInfo>); + method @NonNull public android.telephony.ims.ImsSsData.Builder setSuppServiceInfo(@NonNull java.util.List<android.telephony.ims.ImsSsInfo>); + } + + public final class ImsSsInfo implements android.os.Parcelable { + ctor @Deprecated public ImsSsInfo(int, @Nullable String); + method public int describeContents(); + method public int getClirInterrogationStatus(); + method public int getClirOutgoingState(); + method @Deprecated public String getIcbNum(); + method @Nullable public String getIncomingCommunicationBarringNumber(); + method public int getProvisionStatus(); + method public int getStatus(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CLIR_OUTGOING_DEFAULT = 0; // 0x0 + field public static final int CLIR_OUTGOING_INVOCATION = 1; // 0x1 + field public static final int CLIR_OUTGOING_SUPPRESSION = 2; // 0x2 + field public static final int CLIR_STATUS_NOT_PROVISIONED = 0; // 0x0 + field public static final int CLIR_STATUS_PROVISIONED_PERMANENT = 1; // 0x1 + field public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4; // 0x4 + field public static final int CLIR_STATUS_TEMPORARILY_RESTRICTED = 3; // 0x3 + field public static final int CLIR_STATUS_UNKNOWN = 2; // 0x2 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsInfo> CREATOR; + field public static final int DISABLED = 0; // 0x0 + field public static final int ENABLED = 1; // 0x1 + field public static final int NOT_REGISTERED = -1; // 0xffffffff + field public static final int SERVICE_NOT_PROVISIONED = 0; // 0x0 + field public static final int SERVICE_PROVISIONED = 1; // 0x1 + field public static final int SERVICE_PROVISIONING_UNKNOWN = -1; // 0xffffffff + } + + public static final class ImsSsInfo.Builder { + ctor public ImsSsInfo.Builder(int); + method @NonNull public android.telephony.ims.ImsSsInfo build(); + method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirInterrogationStatus(int); + method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirOutgoingState(int); + method @NonNull public android.telephony.ims.ImsSsInfo.Builder setIncomingCommunicationBarringNumber(@NonNull String); + method @NonNull public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int); + } + + public final class ImsStreamMediaProfile implements android.os.Parcelable { + ctor public ImsStreamMediaProfile(int, int, int, int, int); + method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile); + method public int describeContents(); + method public int getAudioDirection(); + method public int getAudioQuality(); + method public int getRttMode(); + method public int getVideoDirection(); + method public int getVideoQuality(); + method public boolean isReceivingRttAudio(); + method public boolean isRttCall(); + method public void setReceivingRttAudio(boolean); + method public void setRttMode(int); + method public void writeToParcel(android.os.Parcel, int); + field public static final int AUDIO_QUALITY_AMR = 1; // 0x1 + field public static final int AUDIO_QUALITY_AMR_WB = 2; // 0x2 + field public static final int AUDIO_QUALITY_EVRC = 4; // 0x4 + field public static final int AUDIO_QUALITY_EVRC_B = 5; // 0x5 + field public static final int AUDIO_QUALITY_EVRC_NW = 7; // 0x7 + field public static final int AUDIO_QUALITY_EVRC_WB = 6; // 0x6 + field public static final int AUDIO_QUALITY_EVS_FB = 20; // 0x14 + field public static final int AUDIO_QUALITY_EVS_NB = 17; // 0x11 + field public static final int AUDIO_QUALITY_EVS_SWB = 19; // 0x13 + field public static final int AUDIO_QUALITY_EVS_WB = 18; // 0x12 + field public static final int AUDIO_QUALITY_G711A = 13; // 0xd + field public static final int AUDIO_QUALITY_G711AB = 15; // 0xf + field public static final int AUDIO_QUALITY_G711U = 11; // 0xb + field public static final int AUDIO_QUALITY_G722 = 14; // 0xe + field public static final int AUDIO_QUALITY_G723 = 12; // 0xc + field public static final int AUDIO_QUALITY_G729 = 16; // 0x10 + field public static final int AUDIO_QUALITY_GSM_EFR = 8; // 0x8 + field public static final int AUDIO_QUALITY_GSM_FR = 9; // 0x9 + field public static final int AUDIO_QUALITY_GSM_HR = 10; // 0xa + field public static final int AUDIO_QUALITY_NONE = 0; // 0x0 + field public static final int AUDIO_QUALITY_QCELP13K = 3; // 0x3 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsStreamMediaProfile> CREATOR; + field public static final int DIRECTION_INACTIVE = 0; // 0x0 + field public static final int DIRECTION_INVALID = -1; // 0xffffffff + field public static final int DIRECTION_RECEIVE = 1; // 0x1 + field public static final int DIRECTION_SEND = 2; // 0x2 + field public static final int DIRECTION_SEND_RECEIVE = 3; // 0x3 + field public static final int RTT_MODE_DISABLED = 0; // 0x0 + field public static final int RTT_MODE_FULL = 1; // 0x1 + field public static final int VIDEO_QUALITY_NONE = 0; // 0x0 + field public static final int VIDEO_QUALITY_QCIF = 1; // 0x1 + field public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = 2; // 0x2 + field public static final int VIDEO_QUALITY_QVGA_PORTRAIT = 4; // 0x4 + field public static final int VIDEO_QUALITY_VGA_LANDSCAPE = 8; // 0x8 + field public static final int VIDEO_QUALITY_VGA_PORTRAIT = 16; // 0x10 + } + + public final class ImsSuppServiceNotification implements android.os.Parcelable { + ctor public ImsSuppServiceNotification(int, int, int, int, String, String[]); + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSuppServiceNotification> CREATOR; + field public final int code; + field public final String[] history; + field public final int index; + field public final int notificationType; + field public final String number; + field public final int type; + } + + public class ImsUtListener { + method public void onLineIdentificationSupplementaryServiceResponse(int, @NonNull android.telephony.ims.ImsSsInfo); + method public void onSupplementaryServiceIndication(android.telephony.ims.ImsSsData); + method public void onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]); + method public void onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]); + method public void onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]); + method @Deprecated public void onUtConfigurationQueried(int, android.os.Bundle); + method public void onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo); + method public void onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo); + method public void onUtConfigurationUpdated(int); + field @Deprecated public static final String BUNDLE_KEY_CLIR = "queryClir"; + field @Deprecated public static final String BUNDLE_KEY_SSINFO = "imsSsInfo"; + } + + public abstract class ImsVideoCallProvider { + ctor public ImsVideoCallProvider(); + method public void changeCallDataUsage(long); + method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities); + method public void changePeerDimensions(int, int); + method public void changeVideoQuality(int); + method public void handleCallSessionEvent(int); + method public abstract void onRequestCallDataUsage(); + method public abstract void onRequestCameraCapabilities(); + method public abstract void onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile); + method public abstract void onSendSessionModifyResponse(android.telecom.VideoProfile); + method public abstract void onSetCamera(String); + method public void onSetCamera(String, int); + method public abstract void onSetDeviceOrientation(int); + method public abstract void onSetDisplaySurface(android.view.Surface); + method public abstract void onSetPauseImage(android.net.Uri); + method public abstract void onSetPreviewSurface(android.view.Surface); + method public abstract void onSetZoom(float); + method public void receiveSessionModifyRequest(android.telecom.VideoProfile); + method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile); + } + + public class ProvisioningManager { + method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getProvisioningIntValue(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getProvisioningStatusForCapability(int, int); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getRcsProvisioningStatusForCapability(int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException; + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(int, int, boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback); + field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b + field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a + field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0 + field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1 + field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC"; + field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY"; + } + + public static class ProvisioningManager.Callback { + ctor public ProvisioningManager.Callback(); + method public void onProvisioningIntChanged(int, int); + method public void onProvisioningStringChanged(int, @NonNull String); + } + + public class RcsUceAdapter { + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException; + } + +} + +package android.telephony.ims.feature { + + public final class CapabilityChangeRequest implements android.os.Parcelable { + method public void addCapabilitiesToDisableForTech(int, int); + method public void addCapabilitiesToEnableForTech(int, int); + method public int describeContents(); + method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToDisable(); + method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToEnable(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.feature.CapabilityChangeRequest> CREATOR; + } + + public static class CapabilityChangeRequest.CapabilityPair { + ctor public CapabilityChangeRequest.CapabilityPair(int, int); + method public int getCapability(); + method public int getRadioTech(); + } + + public abstract class ImsFeature { + ctor public ImsFeature(); + method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); + method public int getFeatureState(); + method public final int getSlotIndex(); + method public abstract void onFeatureReady(); + method public abstract void onFeatureRemoved(); + method public final void setFeatureState(int); + field public static final int CAPABILITY_ERROR_GENERIC = -1; // 0xffffffff + field public static final int CAPABILITY_SUCCESS = 0; // 0x0 + field public static final int FEATURE_EMERGENCY_MMTEL = 0; // 0x0 + field public static final int FEATURE_MMTEL = 1; // 0x1 + field public static final int FEATURE_RCS = 2; // 0x2 + field public static final int STATE_INITIALIZING = 1; // 0x1 + field public static final int STATE_READY = 2; // 0x2 + field public static final int STATE_UNAVAILABLE = 0; // 0x0 + } + + @Deprecated public static class ImsFeature.Capabilities { + field @Deprecated protected int mCapabilities; + } + + protected static class ImsFeature.CapabilityCallbackProxy { + method public void onChangeCapabilityConfigurationError(int, int, int); + } + + public class MmTelFeature extends android.telephony.ims.feature.ImsFeature { + ctor public MmTelFeature(); + method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); + method @Nullable public android.telephony.ims.ImsCallProfile createCallProfile(int, int); + method @Nullable public android.telephony.ims.stub.ImsCallSessionImplBase createCallSession(@NonNull android.telephony.ims.ImsCallProfile); + method @NonNull public android.telephony.ims.stub.ImsEcbmImplBase getEcbm(); + method @NonNull public android.telephony.ims.stub.ImsMultiEndpointImplBase getMultiEndpoint(); + method @NonNull public android.telephony.ims.stub.ImsSmsImplBase getSmsImplementation(); + method @NonNull public android.telephony.ims.stub.ImsUtImplBase getUt(); + method public final void notifyCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities); + method public final void notifyIncomingCall(@NonNull android.telephony.ims.stub.ImsCallSessionImplBase, @NonNull android.os.Bundle); + method public final void notifyRejectedCall(@NonNull android.telephony.ims.ImsCallProfile, @NonNull android.telephony.ims.ImsReasonInfo); + method public final void notifyVoiceMessageCountUpdate(int); + method public void onFeatureReady(); + method public void onFeatureRemoved(); + method public boolean queryCapabilityConfiguration(int, int); + method @NonNull public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus(); + method public void setUiTtyMode(int, @Nullable android.os.Message); + method public int shouldProcessCall(@NonNull String[]); + field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL"; + field public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD"; + field public static final int PROCESS_CALL_CSFB = 1; // 0x1 + field public static final int PROCESS_CALL_IMS = 0; // 0x0 + } + + public static class MmTelFeature.MmTelCapabilities extends android.telephony.ims.feature.ImsFeature.Capabilities { + ctor public MmTelFeature.MmTelCapabilities(); + ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities); + ctor public MmTelFeature.MmTelCapabilities(int); + method public final void addCapabilities(int); + method public final boolean isCapable(int); + method public final void removeCapabilities(int); + } + + public class RcsFeature extends android.telephony.ims.feature.ImsFeature { + ctor public RcsFeature(); + method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); + method public void onFeatureReady(); + method public void onFeatureRemoved(); + } + +} + +package android.telephony.ims.stub { + + public class ImsCallSessionImplBase implements java.lang.AutoCloseable { + ctor public ImsCallSessionImplBase(); + method public void accept(int, android.telephony.ims.ImsStreamMediaProfile); + method public void close(); + method public void deflect(String); + method public void extendToConference(String[]); + method public String getCallId(); + method public android.telephony.ims.ImsCallProfile getCallProfile(); + method public android.telephony.ims.ImsVideoCallProvider getImsVideoCallProvider(); + method public android.telephony.ims.ImsCallProfile getLocalCallProfile(); + method public String getProperty(String); + method public android.telephony.ims.ImsCallProfile getRemoteCallProfile(); + method public int getState(); + method public void hold(android.telephony.ims.ImsStreamMediaProfile); + method public void inviteParticipants(String[]); + method public boolean isInCall(); + method public boolean isMultiparty(); + method public void merge(); + method public void reject(int); + method public void removeParticipants(String[]); + method public void resume(android.telephony.ims.ImsStreamMediaProfile); + method public void sendDtmf(char, android.os.Message); + method public void sendRttMessage(String); + method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile); + method public void sendRttModifyResponse(boolean); + method public void sendUssd(String); + method public void setListener(android.telephony.ims.ImsCallSessionListener); + method public void setMute(boolean); + method public void start(String, android.telephony.ims.ImsCallProfile); + method public void startConference(String[], android.telephony.ims.ImsCallProfile); + method public void startDtmf(char); + method public void stopDtmf(); + method public void terminate(int); + method public void update(int, android.telephony.ims.ImsStreamMediaProfile); + field public static final int USSD_MODE_NOTIFY = 0; // 0x0 + field public static final int USSD_MODE_REQUEST = 1; // 0x1 + } + + public static class ImsCallSessionImplBase.State { + method public static String toString(int); + field public static final int ESTABLISHED = 4; // 0x4 + field public static final int ESTABLISHING = 3; // 0x3 + field public static final int IDLE = 0; // 0x0 + field public static final int INITIATED = 1; // 0x1 + field public static final int INVALID = -1; // 0xffffffff + field public static final int NEGOTIATING = 2; // 0x2 + field public static final int REESTABLISHING = 6; // 0x6 + field public static final int RENEGOTIATING = 5; // 0x5 + field public static final int TERMINATED = 8; // 0x8 + field public static final int TERMINATING = 7; // 0x7 + } + + public class ImsConfigImplBase { + ctor public ImsConfigImplBase(); + method public int getConfigInt(int); + method public String getConfigString(int); + method public final void notifyProvisionedValueChanged(int, int); + method public final void notifyProvisionedValueChanged(int, String); + method public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean); + method public int setConfig(int, int); + method public int setConfig(int, String); + field public static final int CONFIG_RESULT_FAILED = 1; // 0x1 + field public static final int CONFIG_RESULT_SUCCESS = 0; // 0x0 + field public static final int CONFIG_RESULT_UNKNOWN = -1; // 0xffffffff + } + + public class ImsEcbmImplBase { + ctor public ImsEcbmImplBase(); + method public final void enteredEcbm(); + method public void exitEmergencyCallbackMode(); + method public final void exitedEcbm(); + } + + public final class ImsFeatureConfiguration implements android.os.Parcelable { + method public int describeContents(); + method public java.util.Set<android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair> getServiceFeatures(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.stub.ImsFeatureConfiguration> CREATOR; + } + + public static class ImsFeatureConfiguration.Builder { + ctor public ImsFeatureConfiguration.Builder(); + method public android.telephony.ims.stub.ImsFeatureConfiguration.Builder addFeature(int, int); + method public android.telephony.ims.stub.ImsFeatureConfiguration build(); + } + + public static final class ImsFeatureConfiguration.FeatureSlotPair { + ctor public ImsFeatureConfiguration.FeatureSlotPair(int, int); + field public final int featureType; + field public final int slotId; + } + + public class ImsMultiEndpointImplBase { + ctor public ImsMultiEndpointImplBase(); + method public final void onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>); + method public void requestImsExternalCallStateInfo(); + } + + public class ImsRegistrationImplBase { + ctor public ImsRegistrationImplBase(); + method public final void onDeregistered(android.telephony.ims.ImsReasonInfo); + method public final void onRegistered(int); + method public final void onRegistering(int); + method public final void onSubscriberAssociatedUriChanged(android.net.Uri[]); + method public final void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo); + field public static final int REGISTRATION_TECH_IWLAN = 1; // 0x1 + field public static final int REGISTRATION_TECH_LTE = 0; // 0x0 + field public static final int REGISTRATION_TECH_NONE = -1; // 0xffffffff + } + + public class ImsSmsImplBase { + ctor public ImsSmsImplBase(); + method public void acknowledgeSms(int, @IntRange(from=0, to=65535) int, int); + method public void acknowledgeSmsReport(int, @IntRange(from=0, to=65535) int, int); + method public String getSmsFormat(); + method public void onReady(); + method @Deprecated public final void onSendSmsResult(int, @IntRange(from=0, to=65535) int, int, int) throws java.lang.RuntimeException; + method public final void onSendSmsResultError(int, @IntRange(from=0, to=65535) int, int, int, int) throws java.lang.RuntimeException; + method public final void onSendSmsResultSuccess(int, @IntRange(from=0, to=65535) int) throws java.lang.RuntimeException; + method public final void onSmsReceived(int, String, byte[]) throws java.lang.RuntimeException; + method @Deprecated public final void onSmsStatusReportReceived(int, @IntRange(from=0, to=65535) int, String, byte[]) throws java.lang.RuntimeException; + method public final void onSmsStatusReportReceived(int, String, byte[]) throws java.lang.RuntimeException; + method public void sendSms(int, @IntRange(from=0, to=65535) int, String, String, boolean, byte[]); + field public static final int DELIVER_STATUS_ERROR_GENERIC = 2; // 0x2 + field public static final int DELIVER_STATUS_ERROR_NO_MEMORY = 3; // 0x3 + field public static final int DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED = 4; // 0x4 + field public static final int DELIVER_STATUS_OK = 1; // 0x1 + field public static final int RESULT_NO_NETWORK_ERROR = -1; // 0xffffffff + field public static final int SEND_STATUS_ERROR = 2; // 0x2 + field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4 + field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3 + field public static final int SEND_STATUS_OK = 1; // 0x1 + field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2 + field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1 + } + + public class ImsUtImplBase { + ctor public ImsUtImplBase(); + method public void close(); + method public int queryCallBarring(int); + method public int queryCallBarringForServiceClass(int, int); + method public int queryCallForward(int, String); + method public int queryCallWaiting(); + method public int queryClip(); + method public int queryClir(); + method public int queryColp(); + method public int queryColr(); + method public void setListener(android.telephony.ims.ImsUtListener); + method public int transact(android.os.Bundle); + method public int updateCallBarring(int, int, String[]); + method public int updateCallBarringForServiceClass(int, int, String[], int); + method public int updateCallForward(int, int, String, int, int); + method public int updateCallWaiting(boolean, int); + method public int updateClip(boolean); + method public int updateClir(int); + method public int updateColp(boolean); + method public int updateColr(int); + } + +} + +package android.telephony.mbms { + + public static class DownloadRequest.Builder { + method public android.telephony.mbms.DownloadRequest.Builder setServiceId(String); + } + + public final class FileInfo implements android.os.Parcelable { + ctor public FileInfo(android.net.Uri, String); + } + + public final class FileServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable { + ctor public FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>); + } + + public class MbmsDownloadReceiver extends android.content.BroadcastReceiver { + field public static final int RESULT_APP_NOTIFICATION_ERROR = 6; // 0x6 + field public static final int RESULT_BAD_TEMP_FILE_ROOT = 3; // 0x3 + field public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4; // 0x4 + field public static final int RESULT_INVALID_ACTION = 1; // 0x1 + field public static final int RESULT_MALFORMED_INTENT = 2; // 0x2 + field public static final int RESULT_OK = 0; // 0x0 + field public static final int RESULT_TEMP_FILE_GENERATION_ERROR = 5; // 0x5 + } + + public final class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable { + ctor public StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date); + } + + public final class UriPathPair implements android.os.Parcelable { + method public int describeContents(); + method public android.net.Uri getContentUri(); + method public android.net.Uri getFilePathUri(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.mbms.UriPathPair> CREATOR; + } + +} + +package android.telephony.mbms.vendor { + + public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface { + ctor public MbmsDownloadServiceBase(); + method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException; + method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException; + method public android.os.IBinder asBinder(); + method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException; + method public void dispose(int) throws android.os.RemoteException; + method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException; + method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException; + method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException; + method public void onAppCallbackDied(int, int); + method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException; + method public int removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException; + method public int removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException; + method public int requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException; + method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException; + method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException; + method public int setTempFileRootDirectory(int, String) throws android.os.RemoteException; + } + + public class MbmsGroupCallServiceBase extends android.app.Service { + ctor public MbmsGroupCallServiceBase(); + method public void dispose(int) throws android.os.RemoteException; + method public int initialize(@NonNull android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException; + method public void onAppCallbackDied(int, int); + method public android.os.IBinder onBind(android.content.Intent); + method public int startGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>, @NonNull android.telephony.mbms.GroupCallCallback); + method public void stopGroupCall(int, long); + method public void updateGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>); + } + + public class MbmsStreamingServiceBase extends android.os.Binder implements android.os.IInterface { + ctor public MbmsStreamingServiceBase(); + method public android.os.IBinder asBinder(); + method public void dispose(int) throws android.os.RemoteException; + method @Nullable public android.net.Uri getPlaybackUri(int, String) throws android.os.RemoteException; + method public int initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) throws android.os.RemoteException; + method public void onAppCallbackDied(int, int); + method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException; + method public int requestUpdateStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException; + method public int startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) throws android.os.RemoteException; + method public void stopStreaming(int, String) throws android.os.RemoteException; + } + + public class VendorUtils { + ctor public VendorUtils(); + method public static android.content.ComponentName getAppReceiverFromPackageName(android.content.Context, String); + field public static final String ACTION_CLEANUP = "android.telephony.mbms.action.CLEANUP"; + field public static final String ACTION_DOWNLOAD_RESULT_INTERNAL = "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL"; + field public static final String ACTION_FILE_DESCRIPTOR_REQUEST = "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST"; + field public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT"; + field public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI"; + field public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST"; + field public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST"; + field public static final String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST"; + field public static final String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID"; + field public static final String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE"; + field public static final String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT"; + field public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST"; + } + +} + 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/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java index 98a649fb0fc3..1a049e6c517e 100644 --- a/telephony/common/com/android/internal/telephony/SmsApplication.java +++ b/telephony/common/com/android/internal/telephony/SmsApplication.java @@ -1051,8 +1051,7 @@ public final class SmsApplication { } /** - * Check if a package is default sms app (or equivalent, like bluetooth), and verify that - * packageName belongs to the caller. + * Check if a package is default sms app (or equivalent, like bluetooth) * * @param context context from the calling app * @param packageName the name of the package to be checked @@ -1061,22 +1060,8 @@ public final class SmsApplication { @UnsupportedAppUsage public static boolean isDefaultSmsApplication(Context context, String packageName) { if (packageName == null) { - Log.e(LOG_TAG, "isDefaultSmsApplication: packageName is null"); return false; } - try { - if (Binder.getCallingUid() - == context.getPackageManager().getPackageUid(packageName, 0)) { - Log.e(LOG_TAG, "isDefaultSmsApplication: " + packageName + " calling uid " - + context.getPackageManager().getPackageUid(packageName, 0) - + " does not match calling uid " + Binder.getCallingUid()); - return false; - } - } catch (NameNotFoundException ex) { - Log.e(LOG_TAG, "isDefaultSmsApplication: packageName " + packageName + " not found"); - return false; - } - final String defaultSmsPackage = getDefaultSmsApplicationPackageName(context); if ((defaultSmsPackage != null && defaultSmsPackage.equals(packageName)) || BLUETOOTH_PACKAGE_NAME.equals(packageName)) { diff --git a/telephony/common/com/google/android/mms/pdu/PduComposer.java b/telephony/common/com/google/android/mms/pdu/PduComposer.java index b8b212c493aa..5e1f556f4c4a 100644 --- a/telephony/common/com/google/android/mms/pdu/PduComposer.java +++ b/telephony/common/com/google/android/mms/pdu/PduComposer.java @@ -745,7 +745,9 @@ public class PduComposer { return PDU_COMPOSE_CONTENT_ERROR; } - // X-Mms-Report-Allowed Optional (not support) + // X-Mms-Report-Allowed Optional + appendHeader(PduHeaders.REPORT_ALLOWED); + return PDU_COMPOSE_SUCCESS; } 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/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java index ef11f469d9a0..ae2652e6c229 100644 --- a/telephony/java/android/service/euicc/EuiccService.java +++ b/telephony/java/android/service/euicc/EuiccService.java @@ -31,7 +31,9 @@ import android.os.RemoteException; import android.telephony.TelephonyManager; import android.telephony.euicc.DownloadableSubscription; import android.telephony.euicc.EuiccInfo; +import android.telephony.euicc.EuiccManager; import android.telephony.euicc.EuiccManager.OtaStatus; +import android.text.TextUtils; import android.util.Log; import java.io.PrintWriter; @@ -311,6 +313,64 @@ public abstract class EuiccService extends Service { mStubWrapper = new IEuiccServiceWrapper(); } + /** + * Given a SubjectCode[5.2.6.1] and ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2), encode it to + * the format described in + * {@link android.telephony.euicc.EuiccManager#OPERATION_SMDX_SUBJECT_REASON_CODE} + * + * @param subjectCode SubjectCode[5.2.6.1] from GSMA (SGP.22 v2.2) + * @param reasonCode ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2) + * @return encoded error code described in + * {@link android.telephony.euicc.EuiccManager#OPERATION_SMDX_SUBJECT_REASON_CODE} + * @throws NumberFormatException when the Subject/Reason code contains non digits + * @throws IllegalArgumentException when Subject/Reason code is null/empty + * @throws UnsupportedOperationException when sections has more than four layers (e.g 5.8.1.2) + * or when an number is bigger than 15 + */ + public int encodeSmdxSubjectAndReasonCode(@NonNull String subjectCode, + @NonNull String reasonCode) { + final int maxSupportedSection = 3; + final int maxSupportedDigit = 15; + final int bitsPerSection = 4; + + if (TextUtils.isEmpty(subjectCode) || TextUtils.isEmpty(reasonCode)) { + throw new IllegalArgumentException("SubjectCode/ReasonCode is empty"); + } + + final String[] subjectCodeToken = subjectCode.split("\\."); + final String[] reasonCodeToken = reasonCode.split("\\."); + + if (subjectCodeToken.length > maxSupportedSection + || reasonCodeToken.length > maxSupportedSection) { + throw new UnsupportedOperationException("Only three nested layer is supported."); + } + + int result = EuiccManager.OPERATION_SMDX_SUBJECT_REASON_CODE; + + // Pad the 0s needed for subject code + result = result << (maxSupportedSection - subjectCodeToken.length) * bitsPerSection; + + for (String digitString : subjectCodeToken) { + int num = Integer.parseInt(digitString); + if (num > maxSupportedDigit) { + throw new UnsupportedOperationException("SubjectCode exceeds " + maxSupportedDigit); + } + result = (result << bitsPerSection) + num; + } + + // Pad the 0s needed for reason code + result = result << (maxSupportedSection - reasonCodeToken.length) * bitsPerSection; + for (String digitString : reasonCodeToken) { + int num = Integer.parseInt(digitString); + if (num > maxSupportedDigit) { + throw new UnsupportedOperationException("ReasonCode exceeds " + maxSupportedDigit); + } + result = (result << bitsPerSection) + num; + } + + return result; + } + @Override @CallSuper public void onCreate() { diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java index 01abb2661f39..558f4cd24471 100644 --- a/telephony/java/android/telephony/AccessNetworkConstants.java +++ b/telephony/java/android/telephony/AccessNetworkConstants.java @@ -19,6 +19,10 @@ package android.telephony; import android.annotation.IntDef; import android.annotation.SystemApi; import android.annotation.TestApi; +import android.hardware.radio.V1_1.EutranBands; +import android.hardware.radio.V1_1.GeranBands; +import android.hardware.radio.V1_5.AccessNetwork; +import android.hardware.radio.V1_5.UtranBands; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -84,13 +88,13 @@ public final class AccessNetworkConstants { public @interface RadioAccessNetworkType {} public static final class AccessNetworkType { - public static final int UNKNOWN = 0; - public static final int GERAN = 1; - public static final int UTRAN = 2; - public static final int EUTRAN = 3; - public static final int CDMA2000 = 4; - public static final int IWLAN = 5; - public static final int NGRAN = 6; + public static final int UNKNOWN = AccessNetwork.UNKNOWN; + public static final int GERAN = AccessNetwork.GERAN; + public static final int UTRAN = AccessNetwork.UTRAN; + public static final int EUTRAN = AccessNetwork.EUTRAN; + public static final int CDMA2000 = AccessNetwork.CDMA2000; + public static final int IWLAN = AccessNetwork.IWLAN; + public static final int NGRAN = AccessNetwork.NGRAN; /** @hide */ private AccessNetworkType() {} @@ -115,20 +119,20 @@ public final class AccessNetworkConstants { * http://www.etsi.org/deliver/etsi_ts/145000_145099/145005/14.00.00_60/ts_145005v140000p.pdf */ public static final class GeranBand { - public static final int BAND_T380 = 1; - public static final int BAND_T410 = 2; - public static final int BAND_450 = 3; - public static final int BAND_480 = 4; - public static final int BAND_710 = 5; - public static final int BAND_750 = 6; - public static final int BAND_T810 = 7; - public static final int BAND_850 = 8; - public static final int BAND_P900 = 9; - public static final int BAND_E900 = 10; - public static final int BAND_R900 = 11; - public static final int BAND_DCS1800 = 12; - public static final int BAND_PCS1900 = 13; - public static final int BAND_ER900 = 14; + public static final int BAND_T380 = GeranBands.BAND_T380; + public static final int BAND_T410 = GeranBands.BAND_T410; + public static final int BAND_450 = GeranBands.BAND_450; + public static final int BAND_480 = GeranBands.BAND_480; + public static final int BAND_710 = GeranBands.BAND_710; + public static final int BAND_750 = GeranBands.BAND_750; + public static final int BAND_T810 = GeranBands.BAND_T810; + public static final int BAND_850 = GeranBands.BAND_850; + public static final int BAND_P900 = GeranBands.BAND_P900; + public static final int BAND_E900 = GeranBands.BAND_E900; + public static final int BAND_R900 = GeranBands.BAND_R900; + public static final int BAND_DCS1800 = GeranBands.BAND_DCS1800; + public static final int BAND_PCS1900 = GeranBands.BAND_PCS1900; + public static final int BAND_ER900 = GeranBands.BAND_ER900; /** @hide */ private GeranBand() {} @@ -139,28 +143,28 @@ public final class AccessNetworkConstants { * http://www.etsi.org/deliver/etsi_ts/125100_125199/125104/13.03.00_60/ts_125104v130p.pdf */ public static final class UtranBand { - public static final int BAND_1 = 1; - public static final int BAND_2 = 2; - public static final int BAND_3 = 3; - public static final int BAND_4 = 4; - public static final int BAND_5 = 5; - public static final int BAND_6 = 6; - public static final int BAND_7 = 7; - public static final int BAND_8 = 8; - public static final int BAND_9 = 9; - public static final int BAND_10 = 10; - public static final int BAND_11 = 11; - public static final int BAND_12 = 12; - public static final int BAND_13 = 13; - public static final int BAND_14 = 14; + public static final int BAND_1 = UtranBands.BAND_1; + public static final int BAND_2 = UtranBands.BAND_2; + public static final int BAND_3 = UtranBands.BAND_3; + public static final int BAND_4 = UtranBands.BAND_4; + public static final int BAND_5 = UtranBands.BAND_5; + public static final int BAND_6 = UtranBands.BAND_6; + public static final int BAND_7 = UtranBands.BAND_7; + public static final int BAND_8 = UtranBands.BAND_8; + public static final int BAND_9 = UtranBands.BAND_9; + public static final int BAND_10 = UtranBands.BAND_10; + public static final int BAND_11 = UtranBands.BAND_11; + public static final int BAND_12 = UtranBands.BAND_12; + public static final int BAND_13 = UtranBands.BAND_13; + public static final int BAND_14 = UtranBands.BAND_14; // band 15, 16, 17, 18 are reserved - public static final int BAND_19 = 19; - public static final int BAND_20 = 20; - public static final int BAND_21 = 21; - public static final int BAND_22 = 22; + public static final int BAND_19 = UtranBands.BAND_19; + public static final int BAND_20 = UtranBands.BAND_20; + public static final int BAND_21 = UtranBands.BAND_21; + public static final int BAND_22 = UtranBands.BAND_22; // band 23, 24 are reserved - public static final int BAND_25 = 25; - public static final int BAND_26 = 26; + public static final int BAND_25 = UtranBands.BAND_25; + public static final int BAND_26 = UtranBands.BAND_26; // Frequency bands for TD-SCDMA. Defined in 3GPP TS 25.102, Table 5.2. @@ -169,38 +173,38 @@ public final class AccessNetworkConstants { * 1900 - 1920 MHz: Uplink and downlink transmission * 2010 - 2025 MHz: Uplink and downlink transmission */ - public static final int BAND_A = 101; + public static final int BAND_A = UtranBands.BAND_A; /** * Band B * 1850 - 1910 MHz: Uplink and downlink transmission * 1930 - 1990 MHz: Uplink and downlink transmission */ - public static final int BAND_B = 102; + public static final int BAND_B = UtranBands.BAND_B; /** * Band C * 1910 - 1930 MHz: Uplink and downlink transmission */ - public static final int BAND_C = 103; + public static final int BAND_C = UtranBands.BAND_C; /** * Band D * 2570 - 2620 MHz: Uplink and downlink transmission */ - public static final int BAND_D = 104; + public static final int BAND_D = UtranBands.BAND_D; /** * Band E * 2300—2400 MHz: Uplink and downlink transmission */ - public static final int BAND_E = 105; + public static final int BAND_E = UtranBands.BAND_E; /** * Band F * 1880 - 1920 MHz: Uplink and downlink transmission */ - public static final int BAND_F = 106; + public static final int BAND_F = UtranBands.BAND_F; /** @hide */ private UtranBand() {} @@ -211,54 +215,54 @@ public final class AccessNetworkConstants { * http://www.etsi.org/deliver/etsi_ts/136100_136199/136101/14.03.00_60/ts_136101v140p.pdf */ public static final class EutranBand { - public static final int BAND_1 = 1; - public static final int BAND_2 = 2; - public static final int BAND_3 = 3; - public static final int BAND_4 = 4; - public static final int BAND_5 = 5; - public static final int BAND_6 = 6; - public static final int BAND_7 = 7; - public static final int BAND_8 = 8; - public static final int BAND_9 = 9; - public static final int BAND_10 = 10; - public static final int BAND_11 = 11; - public static final int BAND_12 = 12; - public static final int BAND_13 = 13; - public static final int BAND_14 = 14; - public static final int BAND_17 = 17; - public static final int BAND_18 = 18; - public static final int BAND_19 = 19; - public static final int BAND_20 = 20; - public static final int BAND_21 = 21; - public static final int BAND_22 = 22; - public static final int BAND_23 = 23; - public static final int BAND_24 = 24; - public static final int BAND_25 = 25; - public static final int BAND_26 = 26; - public static final int BAND_27 = 27; - public static final int BAND_28 = 28; - public static final int BAND_30 = 30; - public static final int BAND_31 = 31; - public static final int BAND_33 = 33; - public static final int BAND_34 = 34; - public static final int BAND_35 = 35; - public static final int BAND_36 = 36; - public static final int BAND_37 = 37; - public static final int BAND_38 = 38; - public static final int BAND_39 = 39; - public static final int BAND_40 = 40; - public static final int BAND_41 = 41; - public static final int BAND_42 = 42; - public static final int BAND_43 = 43; - public static final int BAND_44 = 44; - public static final int BAND_45 = 45; - public static final int BAND_46 = 46; - public static final int BAND_47 = 47; - public static final int BAND_48 = 48; - public static final int BAND_65 = 65; - public static final int BAND_66 = 66; - public static final int BAND_68 = 68; - public static final int BAND_70 = 70; + public static final int BAND_1 = EutranBands.BAND_1; + public static final int BAND_2 = EutranBands.BAND_2; + public static final int BAND_3 = EutranBands.BAND_3; + public static final int BAND_4 = EutranBands.BAND_4; + public static final int BAND_5 = EutranBands.BAND_5; + public static final int BAND_6 = EutranBands.BAND_6; + public static final int BAND_7 = EutranBands.BAND_7; + public static final int BAND_8 = EutranBands.BAND_8; + public static final int BAND_9 = EutranBands.BAND_9; + public static final int BAND_10 = EutranBands.BAND_10; + public static final int BAND_11 = EutranBands.BAND_11; + public static final int BAND_12 = EutranBands.BAND_12; + public static final int BAND_13 = EutranBands.BAND_13; + public static final int BAND_14 = EutranBands.BAND_14; + public static final int BAND_17 = EutranBands.BAND_17; + public static final int BAND_18 = EutranBands.BAND_18; + public static final int BAND_19 = EutranBands.BAND_19; + public static final int BAND_20 = EutranBands.BAND_20; + public static final int BAND_21 = EutranBands.BAND_21; + public static final int BAND_22 = EutranBands.BAND_22; + public static final int BAND_23 = EutranBands.BAND_23; + public static final int BAND_24 = EutranBands.BAND_24; + public static final int BAND_25 = EutranBands.BAND_25; + public static final int BAND_26 = EutranBands.BAND_26; + public static final int BAND_27 = EutranBands.BAND_27; + public static final int BAND_28 = EutranBands.BAND_28; + public static final int BAND_30 = EutranBands.BAND_30; + public static final int BAND_31 = EutranBands.BAND_31; + public static final int BAND_33 = EutranBands.BAND_33; + public static final int BAND_34 = EutranBands.BAND_34; + public static final int BAND_35 = EutranBands.BAND_35; + public static final int BAND_36 = EutranBands.BAND_36; + public static final int BAND_37 = EutranBands.BAND_37; + public static final int BAND_38 = EutranBands.BAND_38; + public static final int BAND_39 = EutranBands.BAND_39; + public static final int BAND_40 = EutranBands.BAND_40; + public static final int BAND_41 = EutranBands.BAND_41; + public static final int BAND_42 = EutranBands.BAND_42; + public static final int BAND_43 = EutranBands.BAND_43; + public static final int BAND_44 = EutranBands.BAND_44; + public static final int BAND_45 = EutranBands.BAND_45; + public static final int BAND_46 = EutranBands.BAND_46; + public static final int BAND_47 = EutranBands.BAND_47; + public static final int BAND_48 = EutranBands.BAND_48; + public static final int BAND_65 = EutranBands.BAND_65; + public static final int BAND_66 = EutranBands.BAND_66; + public static final int BAND_68 = EutranBands.BAND_68; + public static final int BAND_70 = EutranBands.BAND_70; /** @hide */ private EutranBand() {}; @@ -304,51 +308,51 @@ public final class AccessNetworkConstants { */ public static final class NgranBands { /** FR1 bands */ - public static final int BAND_1 = 1; - public static final int BAND_2 = 2; - public static final int BAND_3 = 3; - public static final int BAND_5 = 5; - public static final int BAND_7 = 7; - public static final int BAND_8 = 8; - public static final int BAND_12 = 12; - public static final int BAND_14 = 14; - public static final int BAND_18 = 18; - public static final int BAND_20 = 20; - public static final int BAND_25 = 25; - public static final int BAND_28 = 28; - public static final int BAND_29 = 29; - public static final int BAND_30 = 30; - public static final int BAND_34 = 34; - public static final int BAND_38 = 38; - public static final int BAND_39 = 39; - public static final int BAND_40 = 40; - public static final int BAND_41 = 41; - public static final int BAND_48 = 48; - public static final int BAND_50 = 50; - public static final int BAND_51 = 51; - public static final int BAND_65 = 65; - public static final int BAND_66 = 66; - public static final int BAND_70 = 70; - public static final int BAND_71 = 71; - public static final int BAND_74 = 74; - public static final int BAND_75 = 75; - public static final int BAND_76 = 76; - public static final int BAND_77 = 77; - public static final int BAND_78 = 78; - public static final int BAND_79 = 79; - public static final int BAND_80 = 80; - public static final int BAND_81 = 81; - public static final int BAND_82 = 82; - public static final int BAND_83 = 83; - public static final int BAND_84 = 84; - public static final int BAND_86 = 86; - public static final int BAND_90 = 90; + public static final int BAND_1 = android.hardware.radio.V1_5.NgranBands.BAND_1; + public static final int BAND_2 = android.hardware.radio.V1_5.NgranBands.BAND_2; + public static final int BAND_3 = android.hardware.radio.V1_5.NgranBands.BAND_3; + public static final int BAND_5 = android.hardware.radio.V1_5.NgranBands.BAND_5; + public static final int BAND_7 = android.hardware.radio.V1_5.NgranBands.BAND_7; + public static final int BAND_8 = android.hardware.radio.V1_5.NgranBands.BAND_8; + public static final int BAND_12 = android.hardware.radio.V1_5.NgranBands.BAND_12; + public static final int BAND_14 = android.hardware.radio.V1_5.NgranBands.BAND_14; + public static final int BAND_18 = android.hardware.radio.V1_5.NgranBands.BAND_18; + public static final int BAND_20 = android.hardware.radio.V1_5.NgranBands.BAND_20; + public static final int BAND_25 = android.hardware.radio.V1_5.NgranBands.BAND_25; + public static final int BAND_28 = android.hardware.radio.V1_5.NgranBands.BAND_28; + public static final int BAND_29 = android.hardware.radio.V1_5.NgranBands.BAND_29; + public static final int BAND_30 = android.hardware.radio.V1_5.NgranBands.BAND_30; + public static final int BAND_34 = android.hardware.radio.V1_5.NgranBands.BAND_34; + public static final int BAND_38 = android.hardware.radio.V1_5.NgranBands.BAND_38; + public static final int BAND_39 = android.hardware.radio.V1_5.NgranBands.BAND_39; + public static final int BAND_40 = android.hardware.radio.V1_5.NgranBands.BAND_40; + public static final int BAND_41 = android.hardware.radio.V1_5.NgranBands.BAND_41; + public static final int BAND_48 = android.hardware.radio.V1_5.NgranBands.BAND_48; + public static final int BAND_50 = android.hardware.radio.V1_5.NgranBands.BAND_50; + public static final int BAND_51 = android.hardware.radio.V1_5.NgranBands.BAND_51; + public static final int BAND_65 = android.hardware.radio.V1_5.NgranBands.BAND_65; + public static final int BAND_66 = android.hardware.radio.V1_5.NgranBands.BAND_66; + public static final int BAND_70 = android.hardware.radio.V1_5.NgranBands.BAND_70; + public static final int BAND_71 = android.hardware.radio.V1_5.NgranBands.BAND_71; + public static final int BAND_74 = android.hardware.radio.V1_5.NgranBands.BAND_74; + public static final int BAND_75 = android.hardware.radio.V1_5.NgranBands.BAND_75; + public static final int BAND_76 = android.hardware.radio.V1_5.NgranBands.BAND_76; + public static final int BAND_77 = android.hardware.radio.V1_5.NgranBands.BAND_77; + public static final int BAND_78 = android.hardware.radio.V1_5.NgranBands.BAND_78; + public static final int BAND_79 = android.hardware.radio.V1_5.NgranBands.BAND_79; + public static final int BAND_80 = android.hardware.radio.V1_5.NgranBands.BAND_80; + public static final int BAND_81 = android.hardware.radio.V1_5.NgranBands.BAND_81; + public static final int BAND_82 = android.hardware.radio.V1_5.NgranBands.BAND_82; + public static final int BAND_83 = android.hardware.radio.V1_5.NgranBands.BAND_83; + public static final int BAND_84 = android.hardware.radio.V1_5.NgranBands.BAND_84; + public static final int BAND_86 = android.hardware.radio.V1_5.NgranBands.BAND_86; + public static final int BAND_90 = android.hardware.radio.V1_5.NgranBands.BAND_90; /** FR2 bands */ - public static final int BAND_257 = 257; - public static final int BAND_258 = 258; - public static final int BAND_260 = 260; - public static final int BAND_261 = 261; + public static final int BAND_257 = android.hardware.radio.V1_5.NgranBands.BAND_257; + public static final int BAND_258 = android.hardware.radio.V1_5.NgranBands.BAND_258; + public static final int BAND_260 = android.hardware.radio.V1_5.NgranBands.BAND_260; + public static final int BAND_261 = android.hardware.radio.V1_5.NgranBands.BAND_261; /** * NR Bands diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java index 0325c36e227e..ccda88f717c3 100644 --- a/telephony/java/android/telephony/Annotation.java +++ b/telephony/java/android/telephony/Annotation.java @@ -571,6 +571,19 @@ public class Annotation { public @interface PreciseDisconnectCauses { } + /** + * Carrier Privilege Status. + */ + @IntDef(prefix = { "CARRIER_PRIVILEGE_STATUS_" }, value = { + TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS, + TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS, + TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED, + TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface CarrierPrivilegeStatus { + } + @IntDef({ Connection.AUDIO_CODEC_NONE, Connection.AUDIO_CODEC_AMR, @@ -598,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/BarringInfo.aidl b/telephony/java/android/telephony/BarringInfo.aidl new file mode 100644 index 000000000000..50ddf6b31919 --- /dev/null +++ b/telephony/java/android/telephony/BarringInfo.aidl @@ -0,0 +1,20 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @hide */ +package android.telephony; + +parcelable BarringInfo; diff --git a/telephony/java/android/telephony/BarringInfo.java b/telephony/java/android/telephony/BarringInfo.java new file mode 100644 index 000000000000..92423a2f2218 --- /dev/null +++ b/telephony/java/android/telephony/BarringInfo.java @@ -0,0 +1,398 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.SparseArray; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; +import java.util.Objects; + +/** + * Provides the barring configuration for a particular service type. + * + * Provides indication about the barring of a particular service for use. Certain barring types + * are only valid for certain technology families. Any service that does not have a barring + * configuration is unbarred by default. + */ +public final class BarringInfo implements Parcelable { + + /** + * Barring Service Type + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = "BARRING_SERVICE_TYPE_", value = { + BARRING_SERVICE_TYPE_CS_SERVICE, + BARRING_SERVICE_TYPE_PS_SERVICE, + BARRING_SERVICE_TYPE_CS_VOICE, + BARRING_SERVICE_TYPE_MO_SIGNALLING, + BARRING_SERVICE_TYPE_MO_DATA, + BARRING_SERVICE_TYPE_CS_FALLBACK, + BARRING_SERVICE_TYPE_MMTEL_VOICE, + BARRING_SERVICE_TYPE_MMTEL_VIDEO, + BARRING_SERVICE_TYPE_EMERGENCY, + BARRING_SERVICE_TYPE_SMS}) + public @interface BarringServiceType {} + + /* Applicabe to UTRAN */ + /** Barring indicator for circuit-switched service; applicable to UTRAN */ + public static final int BARRING_SERVICE_TYPE_CS_SERVICE = + android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_SERVICE; + /** Barring indicator for packet-switched service; applicable to UTRAN */ + public static final int BARRING_SERVICE_TYPE_PS_SERVICE = + android.hardware.radio.V1_5.BarringInfo.ServiceType.PS_SERVICE; + /** Barring indicator for circuit-switched voice service; applicable to UTRAN */ + public static final int BARRING_SERVICE_TYPE_CS_VOICE = + android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_VOICE; + + /* Applicable to EUTRAN, NGRAN */ + /** Barring indicator for mobile-originated signalling; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_MO_SIGNALLING = + android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_SIGNALLING; + /** Barring indicator for mobile-originated data traffic; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_MO_DATA = + android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_DATA; + /** Barring indicator for circuit-switched fallback for voice; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_CS_FALLBACK = + android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_FALLBACK; + /** Barring indicator for MMTEL (IMS) voice; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_MMTEL_VOICE = + android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VOICE; + /** Barring indicator for MMTEL (IMS) video; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_MMTEL_VIDEO = + android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VIDEO; + + /* Applicable to UTRAN, EUTRAN, NGRAN */ + /** Barring indicator for emergency services; applicable to UTRAN, EUTRAN, and NGRAN */ + public static final int BARRING_SERVICE_TYPE_EMERGENCY = + android.hardware.radio.V1_5.BarringInfo.ServiceType.EMERGENCY; + /** Barring indicator for SMS sending; applicable to UTRAN, EUTRAN, and NGRAN */ + public static final int BARRING_SERVICE_TYPE_SMS = + android.hardware.radio.V1_5.BarringInfo.ServiceType.SMS; + + //TODO: add barring constants for Operator-Specific barring codes + + /** Describe the current barring configuration of a cell */ + public static final class BarringServiceInfo implements Parcelable { + /** + * Barring Type + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = "BARRING_TYPE_", value = + {BARRING_TYPE_NONE, + BARRING_TYPE_UNCONDITIONAL, + BARRING_TYPE_CONDITIONAL, + BARRING_TYPE_UNKNOWN}) + public @interface BarringType {} + + /** Barring is inactive */ + public static final int BARRING_TYPE_NONE = + android.hardware.radio.V1_5.BarringInfo.BarringType.NONE; + /** The service is barred */ + public static final int BARRING_TYPE_UNCONDITIONAL = + android.hardware.radio.V1_5.BarringInfo.BarringType.UNCONDITIONAL; + /** The service may be barred based on additional factors */ + public static final int BARRING_TYPE_CONDITIONAL = + android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL; + + /** If a modem does not report barring info, then the barring type will be UNKNOWN */ + public static final int BARRING_TYPE_UNKNOWN = -1; + + private final @BarringType int mBarringType; + + private final boolean mIsConditionallyBarred; + private final int mConditionalBarringFactor; + private final int mConditionalBarringTimeSeconds; + + /** @hide */ + public BarringServiceInfo(@BarringType int type) { + this(type, false, 0, 0); + } + + /** @hide */ + @TestApi + public BarringServiceInfo(@BarringType int barringType, boolean isConditionallyBarred, + int conditionalBarringFactor, int conditionalBarringTimeSeconds) { + mBarringType = barringType; + mIsConditionallyBarred = isConditionallyBarred; + mConditionalBarringFactor = conditionalBarringFactor; + mConditionalBarringTimeSeconds = conditionalBarringTimeSeconds; + } + + public @BarringType int getBarringType() { + return mBarringType; + } + + /** + * @return true if the conditional barring parameters have resulted in the service being + * barred; false if the service has either not been evaluated for conditional + * barring or has been evaluated and isn't barred. + */ + public boolean isConditionallyBarred() { + return mIsConditionallyBarred; + } + + /** + * @return the conditional barring factor as a percentage 0-100, which is the probability of + * a random device being barred for the service type. + */ + public int getConditionalBarringFactor() { + return mConditionalBarringFactor; + } + + /** + * @return the conditional barring time seconds, which is the interval between successive + * evaluations for conditional barring based on the barring factor. + */ + @SuppressLint("MethodNameUnits") + public int getConditionalBarringTimeSeconds() { + return mConditionalBarringTimeSeconds; + } + + /** + * Return whether a service is currently barred based on the BarringInfo + * + * @return true if the service is currently being barred, otherwise false + */ + public boolean isBarred() { + return mBarringType == BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL + || (mBarringType == BarringServiceInfo.BARRING_TYPE_CONDITIONAL + && mIsConditionallyBarred); + } + + @Override + public int hashCode() { + return Objects.hash(mBarringType, mIsConditionallyBarred, + mConditionalBarringFactor, mConditionalBarringTimeSeconds); + } + + @Override + public boolean equals(Object rhs) { + if (!(rhs instanceof BarringServiceInfo)) return false; + + BarringServiceInfo other = (BarringServiceInfo) rhs; + return mBarringType == other.mBarringType + && mIsConditionallyBarred == other.mIsConditionallyBarred + && mConditionalBarringFactor == other.mConditionalBarringFactor + && mConditionalBarringTimeSeconds == other.mConditionalBarringTimeSeconds; + } + + /** @hide */ + public BarringServiceInfo(Parcel p) { + mBarringType = p.readInt(); + mIsConditionallyBarred = p.readBoolean(); + mConditionalBarringFactor = p.readInt(); + mConditionalBarringTimeSeconds = p.readInt(); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mBarringType); + dest.writeBoolean(mIsConditionallyBarred); + dest.writeInt(mConditionalBarringFactor); + dest.writeInt(mConditionalBarringTimeSeconds); + } + + /* @inheritDoc */ + public static final @NonNull Parcelable.Creator<BarringServiceInfo> CREATOR = + new Parcelable.Creator<BarringServiceInfo>() { + @Override + public BarringServiceInfo createFromParcel(Parcel source) { + return new BarringServiceInfo(source); + } + + @Override + public BarringServiceInfo[] newArray(int size) { + return new BarringServiceInfo[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + } + + private static final BarringServiceInfo BARRING_SERVICE_INFO_UNKNOWN = + new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_UNKNOWN); + + private static final BarringServiceInfo BARRING_SERVICE_INFO_UNBARRED = + new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_NONE); + + private CellIdentity mCellIdentity; + + // A SparseArray potentially mapping each BarringService type to a BarringServiceInfo config + // that describes the current barring status of that particular service. + private SparseArray<BarringServiceInfo> mBarringServiceInfos; + + /** @hide */ + @TestApi + @SystemApi + public BarringInfo() { + mBarringServiceInfos = new SparseArray<>(); + } + + /** + * Constructor for new BarringInfo instances. + * + * @hide + */ + @TestApi + public BarringInfo(@Nullable CellIdentity barringCellId, + @NonNull SparseArray<BarringServiceInfo> barringServiceInfos) { + mCellIdentity = barringCellId; + mBarringServiceInfos = barringServiceInfos; + } + + /** @hide */ + public static BarringInfo create( + @NonNull android.hardware.radio.V1_5.CellIdentity halBarringCellId, + @NonNull List<android.hardware.radio.V1_5.BarringInfo> halBarringInfos) { + CellIdentity ci = CellIdentity.create(halBarringCellId); + SparseArray<BarringServiceInfo> serviceInfos = new SparseArray<>(); + + for (android.hardware.radio.V1_5.BarringInfo halBarringInfo : halBarringInfos) { + if (halBarringInfo.barringType + == android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL) { + if (halBarringInfo.barringTypeSpecificInfo.getDiscriminator() + != android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo + .hidl_discriminator.conditional) { + // this is an error case where the barring info is conditional but the + // conditional barring fields weren't included + continue; + } + android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo + .Conditional conditionalInfo = + halBarringInfo.barringTypeSpecificInfo.conditional(); + serviceInfos.put( + halBarringInfo.serviceType, new BarringServiceInfo( + halBarringInfo.barringType, // will always be CONDITIONAL here + conditionalInfo.isBarred, + conditionalInfo.factor, + conditionalInfo.timeSeconds)); + } else { + // Barring type is either NONE or UNCONDITIONAL + serviceInfos.put( + halBarringInfo.serviceType, new BarringServiceInfo( + halBarringInfo.barringType, false, 0, 0)); + } + } + return new BarringInfo(ci, serviceInfos); + } + + /** + * Get the BarringServiceInfo for a specified service. + * + * @return a BarringServiceInfo struct describing the current barring status for a service + */ + public @NonNull BarringServiceInfo getBarringServiceInfo(@BarringServiceType int service) { + BarringServiceInfo bsi = mBarringServiceInfos.get(service); + // If barring is reported but not for a particular service, then we report the barring + // type as UNKNOWN; if the modem reports barring info but doesn't report for a particular + // service then we can safely assume that the service isn't barred (for instance because + // that particular service isn't applicable to the current RAN). + return (bsi != null) ? bsi : mBarringServiceInfos.size() > 0 + ? BARRING_SERVICE_INFO_UNBARRED : BARRING_SERVICE_INFO_UNKNOWN; + } + + /** @hide */ + @SystemApi + public @NonNull BarringInfo createLocationInfoSanitizedCopy() { + // The only thing that would need sanitizing is the CellIdentity + if (mCellIdentity == null) return this; + + return new BarringInfo(mCellIdentity.sanitizeLocationInfo(), mBarringServiceInfos); + } + + /** @hide */ + public BarringInfo(Parcel p) { + mCellIdentity = p.readParcelable(CellIdentity.class.getClassLoader()); + mBarringServiceInfos = p.readSparseArray(BarringServiceInfo.class.getClassLoader()); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeParcelable(mCellIdentity, flags); + dest.writeSparseArray(mBarringServiceInfos); + } + + public static final @NonNull Parcelable.Creator<BarringInfo> CREATOR = + new Parcelable.Creator<BarringInfo>() { + @Override + public BarringInfo createFromParcel(Parcel source) { + return new BarringInfo(source); + } + + @Override + public BarringInfo[] newArray(int size) { + return new BarringInfo[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public int hashCode() { + int hash = mCellIdentity != null ? mCellIdentity.hashCode() : 7; + for (int i = 0; i < mBarringServiceInfos.size(); i++) { + hash = hash + 15 * mBarringServiceInfos.keyAt(i); + hash = hash + 31 * mBarringServiceInfos.valueAt(i).hashCode(); + } + return hash; + } + + @Override + public boolean equals(Object rhs) { + if (!(rhs instanceof BarringInfo)) return false; + + BarringInfo bi = (BarringInfo) rhs; + + if (hashCode() != bi.hashCode()) return false; + + if (mBarringServiceInfos.size() != bi.mBarringServiceInfos.size()) return false; + + for (int i = 0; i < mBarringServiceInfos.size(); i++) { + if (mBarringServiceInfos.keyAt(i) != bi.mBarringServiceInfos.keyAt(i)) return false; + if (!Objects.equals(mBarringServiceInfos.valueAt(i), + bi.mBarringServiceInfos.valueAt(i))) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "BarringInfo {mCellIdentity=" + mCellIdentity + + ", mBarringServiceInfos=" + mBarringServiceInfos + "}"; + } +} diff --git a/telephony/java/android/telephony/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 57a47d3d78c5..8cbeba14405b 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -37,6 +37,8 @@ import android.telephony.ims.ImsReasonInfo; import com.android.internal.telephony.ICarrierConfigLoader; import com.android.telephony.Rlog; +import java.util.concurrent.TimeUnit; + /** * Provides access to telephony configuration values that are carrier-specific. */ @@ -1551,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"; @@ -2362,17 +2365,16 @@ public class CarrierConfigManager { * <p> If a measure is not set, signal criteria reporting from modem will not be triggered and * not be used for calculating signal level. If multiple measures are set bit, the parameter * whose value is smallest is used to indicate the signal level. + * <UL> + * <LI>RSRP = 1 << 0</LI> + * <LI>RSRQ = 1 << 1</LI> + * <LI>RSSNR = 1 << 2</LI> + * </UL> + * <p> The value of this key must be bitwise OR of {@link CellSignalStrengthLte#USE_RSRP}, + * {@link CellSignalStrengthLte#USE_RSRQ}, {@link CellSignalStrengthLte#USE_RSSNR}. * - * RSRP = 1 << 0, - * RSRQ = 1 << 1, - * RSSNR = 1 << 2, - * - * The value of this key must be bitwise OR of {@link CellSignalStrengthLte#USE_RSRP}, - * {@link CellSignalStrengthLte#USE_RSRQ}, {@link CellSignalStrengthLte#USE_RSSNR}. - * - * For example, if both RSRP and RSRQ are used, the value of key is 3 (1 << 0 | 1 << 1). - * If the key is invalid or not configured, a default value (RSRP = 1 << 0) - * will apply. + * <p> For example, if both RSRP and RSRQ are used, the value of key is 3 (1 << 0 | 1 << 1). + * If the key is invalid or not configured, a default value (RSRP = 1 << 0) will apply. * * @hide */ @@ -2381,16 +2383,18 @@ public class CarrierConfigManager { /** * List of 4 customized 5G SS reference signal received power (SSRSRP) thresholds. - * + * <p> * Reference: 3GPP TS 38.215 - * + * <p> * 4 threshold integers must be within the boundaries [-140 dB, -44 dB], and the levels are: - * "NONE: [-140, threshold1]" - * "POOR: (threshold1, threshold2]" - * "MODERATE: (threshold2, threshold3]" - * "GOOD: (threshold3, threshold4]" - * "EXCELLENT: (threshold4, -44]" - * + * <UL> + * <LI>"NONE: [-140, threshold1]"</LI> + * <LI>"POOR: (threshold1, threshold2]"</LI> + * <LI>"MODERATE: (threshold2, threshold3]"</LI> + * <LI>"GOOD: (threshold3, threshold4]"</LI> + * <LI>"EXCELLENT: (threshold4, -44]"</LI> + * </UL> + * <p> * This key is considered invalid if the format is violated. If the key is invalid or * not configured, a default value set will apply. */ @@ -2399,16 +2403,18 @@ public class CarrierConfigManager { /** * List of 4 customized 5G SS reference signal received quality (SSRSRQ) thresholds. - * + * <p> * Reference: 3GPP TS 38.215 - * + * <p> * 4 threshold integers must be within the boundaries [-20 dB, -3 dB], and the levels are: - * "NONE: [-20, threshold1]" - * "POOR: (threshold1, threshold2]" - * "MODERATE: (threshold2, threshold3]" - * "GOOD: (threshold3, threshold4]" - * "EXCELLENT: (threshold4, -3]" - * + * <UL> + * <LI>"NONE: [-20, threshold1]"</LI> + * <LI>"POOR: (threshold1, threshold2]"</LI> + * <LI>"MODERATE: (threshold2, threshold3]"</LI> + * <LI>"GOOD: (threshold3, threshold4]"</LI> + * <LI>"EXCELLENT: (threshold4, -3]"</LI> + * </UL> + * <p> * This key is considered invalid if the format is violated. If the key is invalid or * not configured, a default value set will apply. */ @@ -2417,17 +2423,19 @@ public class CarrierConfigManager { /** * List of 4 customized 5G SS signal-to-noise and interference ratio (SSSINR) thresholds. - * + * <p> * Reference: 3GPP TS 38.215, * 3GPP TS 38.133 10.1.16.1 - * + * <p> * 4 threshold integers must be within the boundaries [-23 dB, 40 dB], and the levels are: - * "NONE: [-23, threshold1]" - * "POOR: (threshold1, threshold2]" - * "MODERATE: (threshold2, threshold3]" - * "GOOD: (threshold3, threshold4]" - * "EXCELLENT: (threshold4, 40]" - * + * <UL> + * <LI>"NONE: [-23, threshold1]"</LI> + * <LI>"POOR: (threshold1, threshold2]"</LI> + * <LI>"MODERATE: (threshold2, threshold3]"</LI> + * <LI>"GOOD: (threshold3, threshold4]"</LI> + * <LI>"EXCELLENT: (threshold4, 40]"</LI> + * </UL> + * <p> * This key is considered invalid if the format is violated. If the key is invalid or * not configured, a default value set will apply. */ @@ -2442,19 +2450,19 @@ public class CarrierConfigManager { * <p> If a measure is not set, signal criteria reporting from modem will not be triggered and * not be used for calculating signal level. If multiple measures are set bit, the parameter * whose value is smallest is used to indicate the signal level. - * - * SSRSRP = 1 << 0, - * SSRSRQ = 1 << 1, - * SSSINR = 1 << 2, - * + * <UL> + * <LI>SSRSRP = 1 << 0</LI> + * <LI>SSRSRQ = 1 << 1</LI> + * <LI>SSSINR = 1 << 2</LI> + * </UL> * The value of this key must be bitwise OR of {@link CellSignalStrengthNr#USE_SSRSRP}, * {@link CellSignalStrengthNr#USE_SSRSRQ}, {@link CellSignalStrengthNr#USE_SSSINR}. * - * For example, if both SSRSRP and SSSINR are used, the value of key is 5 (1 << 0 | 1 << 2). + * <p> For example, if both SSRSRP and SSSINR are used, the value of key is 5 (1 << 0 | 1 << 2). * If the key is invalid or not configured, a default value (SSRSRP = 1 << 0) will apply. * - * Reference: 3GPP TS 38.215, - * 3GPP TS 38.133 10.1.16.1 + * <p> Reference: 3GPP TS 38.215, + * 3GPP TS 38.133 10.1.16.1 * * @hide */ @@ -2960,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 @@ -2974,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"; @@ -3716,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); @@ -3990,7 +4000,8 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_USE_CALLER_ID_USSD_BOOL, false); sDefaults.putInt(KEY_CALL_WAITING_SERVICE_CLASS_INT, 1 /* SERVICE_CLASS_VOICE */); sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING, - "connected_mmwave:5G,connected:5G"); + "connected_mmwave:5G,connected:5G,not_restricted_rrc_idle:5G," + + "not_restricted_rrc_con:5G"); sDefaults.putInt(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0); /* Default value is 1 hour. */ sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000); @@ -4054,7 +4065,7 @@ public class CarrierConfigManager { sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG, 2000); sDefaults.putInt(KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT, CellSignalStrengthLte.USE_RSRP); - sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG, 0); + sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG, TimeUnit.DAYS.toMillis(1)); sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_ORIGINATOR_STRING_ARRAY, new String[0]); sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_PATTERN_STRING_ARRAY, new String[0]); diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java index 9f2537c7ed10..203047fb111d 100644 --- a/telephony/java/android/telephony/CellIdentityGsm.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -22,11 +22,12 @@ import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; +import android.util.ArraySet; -import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Objects; +import java.util.Set; /** * CellIdentity to represent a unique GSM cell @@ -50,7 +51,7 @@ public final class CellIdentityGsm extends CellIdentity { private final int mBsic; // a list of additional PLMN-IDs reported for this cell - private final List<String> mAdditionalPlmns; + private final ArraySet<String> mAdditionalPlmns; /** * @hide @@ -62,7 +63,7 @@ public final class CellIdentityGsm extends CellIdentity { mCid = CellInfo.UNAVAILABLE; mArfcn = CellInfo.UNAVAILABLE; mBsic = CellInfo.UNAVAILABLE; - mAdditionalPlmns = Collections.emptyList(); + mAdditionalPlmns = new ArraySet<>(); } /** @@ -81,13 +82,13 @@ public final class CellIdentityGsm extends CellIdentity { */ public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas, - @NonNull List<String> additionalPlmns) { + @NonNull Collection<String> additionalPlmns) { super(TAG, CellInfo.TYPE_GSM, mccStr, mncStr, alphal, alphas); mLac = inRangeOrUnavailable(lac, 0, MAX_LAC); mCid = inRangeOrUnavailable(cid, 0, MAX_CID); mArfcn = inRangeOrUnavailable(arfcn, 0, MAX_ARFCN); mBsic = inRangeOrUnavailable(bsic, 0, MAX_BSIC); - mAdditionalPlmns = new ArrayList<>(additionalPlmns.size()); + mAdditionalPlmns = new ArraySet<>(additionalPlmns.size()); for (String plmn : additionalPlmns) { if (isValidPlmn(plmn)) { mAdditionalPlmns.add(plmn); @@ -99,7 +100,7 @@ public final class CellIdentityGsm extends CellIdentity { public CellIdentityGsm(@NonNull android.hardware.radio.V1_0.CellIdentityGsm cid) { this(cid.lac, cid.cid, cid.arfcn, cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic, - cid.mcc, cid.mnc, "", "", Collections.emptyList()); + cid.mcc, cid.mnc, "", "", new ArraySet<>()); } /** @hide */ @@ -107,7 +108,7 @@ public final class CellIdentityGsm extends CellIdentity { this(cid.base.lac, cid.base.cid, cid.base.arfcn, cid.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.bsic, cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort, - Collections.emptyList()); + new ArraySet<>()); } /** @hide */ @@ -221,8 +222,8 @@ public final class CellIdentityGsm extends CellIdentity { * @return a list of additional PLMN IDs supported by this cell. */ @NonNull - public List<String> getAdditionalPlmns() { - return mAdditionalPlmns; + public Set<String> getAdditionalPlmns() { + return Collections.unmodifiableSet(mAdditionalPlmns); } /** @@ -296,7 +297,7 @@ public final class CellIdentityGsm extends CellIdentity { dest.writeInt(mCid); dest.writeInt(mArfcn); dest.writeInt(mBsic); - dest.writeList(mAdditionalPlmns); + dest.writeArraySet(mAdditionalPlmns); } /** Construct from Parcel, type has already been processed */ @@ -306,7 +307,7 @@ public final class CellIdentityGsm extends CellIdentity { mCid = in.readInt(); mArfcn = in.readInt(); mBsic = in.readInt(); - mAdditionalPlmns = in.readArrayList(null); + mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null); if (DBG) log(toString()); } diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index a194ae35216c..b4ce162274fb 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -23,11 +23,13 @@ import android.os.Build; import android.os.Parcel; 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; /** * CellIdentity is to represent a unique LTE cell @@ -52,9 +54,11 @@ public final class CellIdentityLte extends CellIdentity { private final int mEarfcn; // cell bandwidth, in kHz private final int mBandwidth; + // cell bands + private final int[] mBands; // a list of additional PLMN-IDs reported for this cell - private final List<String> mAdditionalPlmns; + private final ArraySet<String> mAdditionalPlmns; private ClosedSubscriberGroupInfo mCsgInfo; @@ -68,8 +72,9 @@ public final class CellIdentityLte extends CellIdentity { mPci = CellInfo.UNAVAILABLE; mTac = CellInfo.UNAVAILABLE; mEarfcn = CellInfo.UNAVAILABLE; + mBands = new int[] {}; mBandwidth = CellInfo.UNAVAILABLE; - mAdditionalPlmns = Collections.emptyList(); + mAdditionalPlmns = new ArraySet<>(); mCsgInfo = null; } @@ -85,8 +90,9 @@ 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, CellInfo.UNAVAILABLE, String.valueOf(mcc), - String.valueOf(mnc), null, null, Collections.emptyList(), null); + this(ci, pci, tac, CellInfo.UNAVAILABLE, new int[] {}, CellInfo.UNAVAILABLE, + String.valueOf(mcc), String.valueOf(mnc), null, null, new ArraySet<>(), + null); } /** @@ -105,17 +111,19 @@ public final class CellIdentityLte extends CellIdentity { * * @hide */ - public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth, - @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal, - @Nullable String alphas, @NonNull List<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 = bands; mBandwidth = inRangeOrUnavailable(bandwidth, 0, MAX_BANDWIDTH); - mAdditionalPlmns = new ArrayList<>(additionalPlmns.size()); + mAdditionalPlmns = new ArraySet<>(additionalPlmns.size()); for (String plmn : additionalPlmns) { if (isValidPlmn(plmn)) { mAdditionalPlmns.add(plmn); @@ -126,28 +134,29 @@ 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, - CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", Collections.emptyList(), null); + 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, cid.bandwidth, - cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong, - cid.operatorNames.alphaShort, Collections.emptyList(), null); + 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); } /** @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.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); } private CellIdentityLte(@NonNull CellIdentityLte cid) { - this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBandwidth, cid.mMccStr, + this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBands, cid.mBandwidth, cid.mMccStr, cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo); } @@ -155,7 +164,7 @@ public final class CellIdentityLte extends CellIdentity { @Override public @NonNull CellIdentityLte sanitizeLocationInfo() { return new CellIdentityLte(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, - CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + CellInfo.UNAVAILABLE, mBands, CellInfo.UNAVAILABLE, mMccStr, mMncStr, mAlphaLong, mAlphaShort, mAdditionalPlmns, null); } @@ -220,12 +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() { - // Todo: Add actual support - return Collections.emptyList(); + public int[] getBands() { + return Arrays.copyOf(mBands, mBands.length); } /** @@ -270,8 +278,8 @@ public final class CellIdentityLte extends CellIdentity { * @return a list of additional PLMN IDs supported by this cell. */ @NonNull - public List<String> getAdditionalPlmns() { - return mAdditionalPlmns; + public Set<String> getAdditionalPlmns() { + return Collections.unmodifiableSet(mAdditionalPlmns); } /** @@ -307,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 @@ -326,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) @@ -341,6 +350,7 @@ public final class CellIdentityLte extends CellIdentity { .append(" mPci=").append(mPci) .append(" mTac=").append(mTac) .append(" mEarfcn=").append(mEarfcn) + .append(" mBands=").append(mBands) .append(" mBandwidth=").append(mBandwidth) .append(" mMcc=").append(mMccStr) .append(" mMnc=").append(mMncStr) @@ -360,8 +370,9 @@ public final class CellIdentityLte extends CellIdentity { dest.writeInt(mPci); dest.writeInt(mTac); dest.writeInt(mEarfcn); + dest.writeIntArray(mBands); dest.writeInt(mBandwidth); - dest.writeList(mAdditionalPlmns); + dest.writeArraySet(mAdditionalPlmns); dest.writeParcelable(mCsgInfo, flags); } @@ -372,8 +383,9 @@ public final class CellIdentityLte extends CellIdentity { mPci = in.readInt(); mTac = in.readInt(); mEarfcn = in.readInt(); + mBands = in.createIntArray(); mBandwidth = in.readInt(); - mAdditionalPlmns = in.readArrayList(null); + mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null); mCsgInfo = in.readParcelable(null); if (DBG) log(toString()); } diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index a0ef5aa2feae..69cf7e7d4814 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -22,11 +22,13 @@ import android.annotation.Nullable; import android.os.Parcel; 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; /** * Information to represent a unique NR(New Radio 5G) cell. @@ -43,10 +45,10 @@ 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 List<String> mAdditionalPlmns; + private final ArraySet<String> mAdditionalPlmns; /** * @@ -63,17 +65,18 @@ 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 List<String> additionalPlmns) { + @NonNull Collection<String> additionalPlmns) { super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas); 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 ArrayList<>(additionalPlmns.size()); + mAdditionalPlmns = new ArraySet<>(additionalPlmns.size()); for (String plmn : additionalPlmns) { if (isValidPlmn(plmn)) { mAdditionalPlmns.add(plmn); @@ -83,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, - Collections.emptyList()); + 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); } @@ -116,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); } @@ -160,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); } /** @@ -212,8 +220,8 @@ public final class CellIdentityNr extends CellIdentity { * @return a list of additional PLMN IDs supported by this cell. */ @NonNull - public List<String> getAdditionalPlmns() { - return Collections.unmodifiableList(mAdditionalPlmns); + public Set<String> getAdditionalPlmns() { + return Collections.unmodifiableSet(mAdditionalPlmns); } @Override @@ -239,9 +247,9 @@ 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.writeList(mAdditionalPlmns); + dest.writeArraySet(mAdditionalPlmns); } /** Construct from Parcel, type has already been processed */ @@ -250,9 +258,9 @@ 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 = in.readArrayList(null); + mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null); } /** Implement the Parcelable interface */ diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java index 531487a313d9..30f98bc57458 100644 --- a/telephony/java/android/telephony/CellIdentityTdscdma.java +++ b/telephony/java/android/telephony/CellIdentityTdscdma.java @@ -20,11 +20,12 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; +import android.util.ArraySet; -import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Objects; +import java.util.Set; /** * CellIdentity is to represent a unique TD-SCDMA cell @@ -50,7 +51,7 @@ public final class CellIdentityTdscdma extends CellIdentity { private final int mUarfcn; // a list of additional PLMN-IDs reported for this cell - private final List<String> mAdditionalPlmns; + private final ArraySet<String> mAdditionalPlmns; private ClosedSubscriberGroupInfo mCsgInfo; @@ -63,7 +64,7 @@ public final class CellIdentityTdscdma extends CellIdentity { mCid = CellInfo.UNAVAILABLE; mCpid = CellInfo.UNAVAILABLE; mUarfcn = CellInfo.UNAVAILABLE; - mAdditionalPlmns = Collections.emptyList(); + mAdditionalPlmns = new ArraySet<>(); mCsgInfo = null; } @@ -85,13 +86,14 @@ public final class CellIdentityTdscdma extends CellIdentity { */ public CellIdentityTdscdma(@Nullable String mcc, @Nullable String mnc, int lac, int cid, int cpid, int uarfcn, @Nullable String alphal, @Nullable String alphas, - @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) { + @NonNull Collection<String> additionalPlmns, + @Nullable ClosedSubscriberGroupInfo csgInfo) { super(TAG, CellInfo.TYPE_TDSCDMA, mcc, mnc, alphal, alphas); mLac = inRangeOrUnavailable(lac, 0, MAX_LAC); mCid = inRangeOrUnavailable(cid, 0, MAX_CID); mCpid = inRangeOrUnavailable(cpid, 0, MAX_CPID); mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN); - mAdditionalPlmns = new ArrayList<>(additionalPlmns.size()); + mAdditionalPlmns = new ArraySet<>(additionalPlmns.size()); for (String plmn : additionalPlmns) { if (isValidPlmn(plmn)) { mAdditionalPlmns.add(plmn); @@ -208,8 +210,8 @@ public final class CellIdentityTdscdma extends CellIdentity { * @return a list of additional PLMN IDs supported by this cell. */ @NonNull - public List<String> getAdditionalPlmns() { - return mAdditionalPlmns; + public Set<String> getAdditionalPlmns() { + return Collections.unmodifiableSet(mAdditionalPlmns); } /** @@ -289,7 +291,7 @@ public final class CellIdentityTdscdma extends CellIdentity { dest.writeInt(mCid); dest.writeInt(mCpid); dest.writeInt(mUarfcn); - dest.writeList(mAdditionalPlmns); + dest.writeArraySet(mAdditionalPlmns); dest.writeParcelable(mCsgInfo, flags); } @@ -300,7 +302,7 @@ public final class CellIdentityTdscdma extends CellIdentity { mCid = in.readInt(); mCpid = in.readInt(); mUarfcn = in.readInt(); - mAdditionalPlmns = in.readArrayList(null); + mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null); mCsgInfo = in.readParcelable(null); if (DBG) log(toString()); } diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java index 15e491b66575..9d2cb74bac23 100644 --- a/telephony/java/android/telephony/CellIdentityWcdma.java +++ b/telephony/java/android/telephony/CellIdentityWcdma.java @@ -22,11 +22,12 @@ import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; +import android.util.ArraySet; -import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Objects; +import java.util.Set; /** * CellIdentity to represent a unique UMTS cell @@ -51,7 +52,7 @@ public final class CellIdentityWcdma extends CellIdentity { private final int mUarfcn; // a list of additional PLMN-IDs reported for this cell - private final List<String> mAdditionalPlmns; + private final ArraySet<String> mAdditionalPlmns; @Nullable private final ClosedSubscriberGroupInfo mCsgInfo; @@ -65,7 +66,7 @@ public final class CellIdentityWcdma extends CellIdentity { mCid = CellInfo.UNAVAILABLE; mPsc = CellInfo.UNAVAILABLE; mUarfcn = CellInfo.UNAVAILABLE; - mAdditionalPlmns = Collections.emptyList(); + mAdditionalPlmns = new ArraySet<>(); mCsgInfo = null; } @@ -86,13 +87,14 @@ public final class CellIdentityWcdma extends CellIdentity { */ public CellIdentityWcdma(int lac, int cid, int psc, int uarfcn, @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas, - @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) { + @NonNull Collection<String> additionalPlmns, + @Nullable ClosedSubscriberGroupInfo csgInfo) { super(TAG, CellInfo.TYPE_WCDMA, mccStr, mncStr, alphal, alphas); mLac = inRangeOrUnavailable(lac, 0, MAX_LAC); mCid = inRangeOrUnavailable(cid, 0, MAX_CID); mPsc = inRangeOrUnavailable(psc, 0, MAX_PSC); mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN); - mAdditionalPlmns = new ArrayList<>(additionalPlmns.size()); + mAdditionalPlmns = new ArraySet<>(additionalPlmns.size()); for (String plmn : additionalPlmns) { if (isValidPlmn(plmn)) { mAdditionalPlmns.add(plmn); @@ -104,14 +106,14 @@ public final class CellIdentityWcdma extends CellIdentity { /** @hide */ public CellIdentityWcdma(@NonNull android.hardware.radio.V1_0.CellIdentityWcdma cid) { this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", "", - Collections.emptyList(), null); + new ArraySet<>(), null); } /** @hide */ public CellIdentityWcdma(@NonNull android.hardware.radio.V1_2.CellIdentityWcdma cid) { this(cid.base.lac, cid.base.cid, cid.base.psc, cid.base.uarfcn, cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong, - cid.operatorNames.alphaShort, Collections.emptyList(), null); + cid.operatorNames.alphaShort, new ArraySet<>(), null); } /** @hide */ @@ -232,8 +234,8 @@ public final class CellIdentityWcdma extends CellIdentity { * @return a list of additional PLMN IDs supported by this cell. */ @NonNull - public List<String> getAdditionalPlmns() { - return mAdditionalPlmns; + public Set<String> getAdditionalPlmns() { + return Collections.unmodifiableSet(mAdditionalPlmns); } /** @@ -305,7 +307,7 @@ public final class CellIdentityWcdma extends CellIdentity { dest.writeInt(mCid); dest.writeInt(mPsc); dest.writeInt(mUarfcn); - dest.writeList(mAdditionalPlmns); + dest.writeArraySet(mAdditionalPlmns); dest.writeParcelable(mCsgInfo, flags); } @@ -316,7 +318,7 @@ public final class CellIdentityWcdma extends CellIdentity { mCid = in.readInt(); mPsc = in.readInt(); mUarfcn = in.readInt(); - mAdditionalPlmns = in.readArrayList(null); + mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null); mCsgInfo = in.readParcelable(null); if (DBG) log(toString()); } diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java index bfa209bd31f5..b381ccecde47 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -21,6 +21,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; import android.hardware.radio.V1_4.CellInfo.Info; +import android.hardware.radio.V1_5.CellInfo.CellInfoRatSpecificInfo; import android.os.Parcel; import android.os.Parcelable; @@ -28,6 +29,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Objects; /** * Immutable cell information from a point in time. @@ -152,7 +154,7 @@ public abstract class CellInfo implements Parcelable { protected CellInfo() { this.mRegistered = false; this.mTimeStamp = Long.MAX_VALUE; - mCellConnectionStatus = CONNECTION_NONE; + this.mCellConnectionStatus = CONNECTION_NONE; } /** @hide */ @@ -240,27 +242,17 @@ public abstract class CellInfo implements Parcelable { @Override public int hashCode() { - int primeNum = 31; - return ((mRegistered ? 0 : 1) * primeNum) + ((int)(mTimeStamp / 1000) * primeNum) - + (mCellConnectionStatus * primeNum); + return Objects.hash(mCellConnectionStatus, mRegistered, mTimeStamp); } @Override - public boolean equals(Object other) { - if (other == null) { - return false; - } - if (this == other) { - return true; - } - try { - CellInfo o = (CellInfo) other; - return mRegistered == o.mRegistered - && mTimeStamp == o.mTimeStamp - && mCellConnectionStatus == o.mCellConnectionStatus; - } catch (ClassCastException e) { - return false; - } + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof CellInfo)) return false; + CellInfo cellInfo = (CellInfo) o; + return mCellConnectionStatus == cellInfo.mCellConnectionStatus + && mRegistered == cellInfo.mRegistered + && mTimeStamp == cellInfo.mTimeStamp; } @Override @@ -353,6 +345,13 @@ public abstract class CellInfo implements Parcelable { } /** @hide */ + protected CellInfo(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) { + this.mRegistered = ci.registered; + this.mTimeStamp = timeStamp; + this.mCellConnectionStatus = ci.connectionStatus; + } + + /** @hide */ public static CellInfo create(android.hardware.radio.V1_0.CellInfo ci) { if (ci == null) return null; switch(ci.cellInfoType) { @@ -391,4 +390,24 @@ public abstract class CellInfo implements Parcelable { default: return null; } } + + /** @hide */ + public static CellInfo create(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) { + if (ci == null) return null; + switch (ci.ratSpecificInfo.getDiscriminator()) { + case CellInfoRatSpecificInfo.hidl_discriminator.gsm: + return new CellInfoGsm(ci, timeStamp); + case CellInfoRatSpecificInfo.hidl_discriminator.cdma: + return new CellInfoCdma(ci, timeStamp); + case CellInfoRatSpecificInfo.hidl_discriminator.lte: + return new CellInfoLte(ci, timeStamp); + case CellInfoRatSpecificInfo.hidl_discriminator.wcdma: + return new CellInfoWcdma(ci, timeStamp); + case CellInfoRatSpecificInfo.hidl_discriminator.tdscdma: + return new CellInfoTdscdma(ci, timeStamp); + case CellInfoRatSpecificInfo.hidl_discriminator.nr: + return new CellInfoNr(ci, timeStamp); + default: return null; + } + } } diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java index 0edb4a4eed9b..1bef681619ed 100644 --- a/telephony/java/android/telephony/CellInfoCdma.java +++ b/telephony/java/android/telephony/CellInfoCdma.java @@ -78,6 +78,15 @@ public final class CellInfoCdma extends CellInfo implements Parcelable { new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo); } + /** @hide */ + public CellInfoCdma(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) { + super(ci, timeStamp); + final android.hardware.radio.V1_2.CellInfoCdma cic = ci.ratSpecificInfo.cdma(); + mCellIdentityCdma = new CellIdentityCdma(cic.cellIdentityCdma); + mCellSignalStrengthCdma = + new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo); + } + /** * @return a {@link CellIdentityCdma} instance. */ diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java index 2dddd3f935cd..c19521fdfa99 100644 --- a/telephony/java/android/telephony/CellInfoGsm.java +++ b/telephony/java/android/telephony/CellInfoGsm.java @@ -73,6 +73,14 @@ public final class CellInfoGsm extends CellInfo implements Parcelable { mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm); } + /** @hide */ + public CellInfoGsm(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) { + super(ci, timeStamp); + final android.hardware.radio.V1_5.CellInfoGsm cig = ci.ratSpecificInfo.gsm(); + mCellIdentityGsm = new CellIdentityGsm(cig.cellIdentityGsm); + mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm); + } + /** * @return a {@link CellIdentityGsm} instance. */ diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java index a57c7cd136db..320925ea63ae 100644 --- a/telephony/java/android/telephony/CellInfoLte.java +++ b/telephony/java/android/telephony/CellInfoLte.java @@ -82,6 +82,15 @@ public final class CellInfoLte extends CellInfo implements Parcelable { mCellConfig = new CellConfigLte(cil.cellConfig); } + /** @hide */ + public CellInfoLte(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) { + super(ci, timeStamp); + final android.hardware.radio.V1_5.CellInfoLte cil = ci.ratSpecificInfo.lte(); + mCellIdentityLte = new CellIdentityLte(cil.cellIdentityLte); + mCellSignalStrengthLte = new CellSignalStrengthLte(cil.signalStrengthLte); + mCellConfig = new CellConfigLte(); + } + /** * @return a {@link CellIdentityLte} instance. */ diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java index 8b41b8be7137..a7e79f93ae89 100644 --- a/telephony/java/android/telephony/CellInfoNr.java +++ b/telephony/java/android/telephony/CellInfoNr.java @@ -53,6 +53,14 @@ public final class CellInfoNr extends CellInfo { mCellSignalStrength = new CellSignalStrengthNr(cil.signalStrength); } + /** @hide */ + public CellInfoNr(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) { + super(ci, timeStamp); + final android.hardware.radio.V1_5.CellInfoNr cil = ci.ratSpecificInfo.nr(); + mCellIdentity = new CellIdentityNr(cil.cellIdentityNr); + mCellSignalStrength = new CellSignalStrengthNr(cil.signalStrengthNr); + } + /** * @return a {@link CellIdentityNr} instance. */ diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java index d2cc9c6ce422..038c49ac37ee 100644 --- a/telephony/java/android/telephony/CellInfoTdscdma.java +++ b/telephony/java/android/telephony/CellInfoTdscdma.java @@ -77,6 +77,14 @@ public final class CellInfoTdscdma extends CellInfo implements Parcelable { mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma); } + /** @hide */ + public CellInfoTdscdma(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) { + super(ci, timeStamp); + final android.hardware.radio.V1_5.CellInfoTdscdma cit = ci.ratSpecificInfo.tdscdma(); + mCellIdentityTdscdma = new CellIdentityTdscdma(cit.cellIdentityTdscdma); + mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma); + } + /** * @return a {@link CellIdentityTdscdma} instance. */ diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java index 3f792d17b8ef..c74955f807b0 100644 --- a/telephony/java/android/telephony/CellInfoWcdma.java +++ b/telephony/java/android/telephony/CellInfoWcdma.java @@ -72,6 +72,14 @@ public final class CellInfoWcdma extends CellInfo implements Parcelable { mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma); } + /** @hide */ + public CellInfoWcdma(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) { + super(ci, timeStamp); + final android.hardware.radio.V1_5.CellInfoWcdma ciw = ci.ratSpecificInfo.wcdma(); + mCellIdentityWcdma = new CellIdentityWcdma(ciw.cellIdentityWcdma); + mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma); + } + /** * @return a {@link CellIdentityWcdma} instance. */ 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 32ffb75f373c..93fbb00ff9d5 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -25,6 +25,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.Annotation.NetworkType; +import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -214,6 +215,9 @@ public final class NetworkRegistrationInfo implements Parcelable { @Nullable private DataSpecificRegistrationInfo mDataSpecificInfo; + @NonNull + private String mRplmn; + /** * @param domain Network domain. Must be a {@link Domain}. For transport type * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}. @@ -234,13 +238,14 @@ public final class NetworkRegistrationInfo implements Parcelable { * @param availableServices The list of the supported services. * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the * information is not available. + * @param rplmn the registered plmn or the last plmn for attempted registration if reg failed. */ private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType, @RegistrationState int registrationState, @NetworkType int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, @Nullable @ServiceType List<Integer> availableServices, - @Nullable CellIdentity cellIdentity) { + @Nullable CellIdentity cellIdentity, @Nullable String rplmn) { mDomain = domain; mTransportType = transportType; mRegistrationState = registrationState; @@ -253,6 +258,7 @@ public final class NetworkRegistrationInfo implements Parcelable { mCellIdentity = cellIdentity; mEmergencyOnly = emergencyOnly; mNrState = NR_STATE_NONE; + mRplmn = rplmn; } /** @@ -263,11 +269,11 @@ public final class NetworkRegistrationInfo implements Parcelable { int registrationState, int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, @Nullable List<Integer> availableServices, - @Nullable CellIdentity cellIdentity, boolean cssSupported, - int roamingIndicator, int systemIsInPrl, + @Nullable CellIdentity cellIdentity, @Nullable String rplmn, + boolean cssSupported, int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator) { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, - emergencyOnly, availableServices, cellIdentity); + emergencyOnly, availableServices, cellIdentity, rplmn); mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator, systemIsInPrl, defaultRoamingIndicator); @@ -281,17 +287,17 @@ public final class NetworkRegistrationInfo implements Parcelable { int registrationState, int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, @Nullable List<Integer> availableServices, - @Nullable CellIdentity cellIdentity, int maxDataCalls, - boolean isDcNrRestricted, boolean isNrAvailable, - boolean isEndcAvailable, + @Nullable CellIdentity cellIdentity, @Nullable String rplmn, + int maxDataCalls, boolean isDcNrRestricted, + boolean isNrAvailable, boolean isEndcAvailable, LteVopsSupportInfo lteVopsSupportInfo, boolean isUsingCarrierAggregation) { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, - emergencyOnly, availableServices, cellIdentity); + emergencyOnly, availableServices, cellIdentity, rplmn); mDataSpecificInfo = new DataSpecificRegistrationInfo( maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo, isUsingCarrierAggregation); - updateNrState(mDataSpecificInfo); + updateNrState(); } private NetworkRegistrationInfo(Parcel source) { @@ -310,6 +316,7 @@ public final class NetworkRegistrationInfo implements Parcelable { mDataSpecificInfo = source.readParcelable( DataSpecificRegistrationInfo.class.getClassLoader()); mNrState = source.readInt(); + mRplmn = source.readString(); } /** @@ -343,6 +350,7 @@ public final class NetworkRegistrationInfo implements Parcelable { mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo); } mNrState = nri.mNrState; + mRplmn = nri.mRplmn; } /** @@ -359,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; @@ -395,6 +404,22 @@ public final class NetworkRegistrationInfo implements Parcelable { } /** + * Get the PLMN-ID for this Network Registration, also known as the RPLMN. + * + * <p>If the device is registered, this will return the registered PLMN-ID. If registration + * has failed, then this will return the PLMN ID of the last attempted registration. If the + * device is not registered, or if is registered to a non-3GPP radio technology, then this + * will return null. + * + * <p>See 3GPP TS 23.122 for further information about the Registered PLMN. + * + * @return the registered PLMN-ID or null. + */ + @Nullable public String getRegisteredPlmn() { + return mRplmn; + } + + /** * @return {@code true} if registered on roaming network, {@code false} otherwise. */ public boolean isRoaming() { @@ -590,6 +615,7 @@ public final class NetworkRegistrationInfo implements Parcelable { .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo) .append(" dataSpecificInfo=").append(mDataSpecificInfo) .append(" nrState=").append(nrStateToString(mNrState)) + .append(" rRplmn=").append(mRplmn) .append("}").toString(); } @@ -597,7 +623,7 @@ public final class NetworkRegistrationInfo implements Parcelable { public int hashCode() { return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, - mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState); + mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn); } @Override @@ -620,6 +646,7 @@ public final class NetworkRegistrationInfo implements Parcelable { && Objects.equals(mCellIdentity, other.mCellIdentity) && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo) && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo) + && TextUtils.equals(mRplmn, other.mRplmn) && mNrState == other.mNrState; } @@ -641,6 +668,7 @@ public final class NetworkRegistrationInfo implements Parcelable { dest.writeParcelable(mVoiceSpecificInfo, 0); dest.writeParcelable(mDataSpecificInfo, 0); dest.writeInt(mNrState); + dest.writeString(mRplmn); } /** @@ -658,12 +686,12 @@ public final class NetworkRegistrationInfo implements Parcelable { * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G * NR is restricted. * - * @param state data specific registration state contains the 5G NR indicators. + * @hide */ - private void updateNrState(DataSpecificRegistrationInfo state) { + public void updateNrState() { mNrState = NR_STATE_NONE; - if (state.isEnDcAvailable) { - if (!state.isDcNrRestricted && state.isNrAvailable) { + if (mDataSpecificInfo != null && mDataSpecificInfo.isEnDcAvailable) { + if (!mDataSpecificInfo.isDcNrRestricted && mDataSpecificInfo.isNrAvailable) { mNrState = NR_STATE_NOT_RESTRICTED; } else { mNrState = NR_STATE_RESTRICTED; @@ -741,6 +769,9 @@ public final class NetworkRegistrationInfo implements Parcelable { @Nullable private CellIdentity mCellIdentity; + @NonNull + private String mRplmn = ""; + /** * Default constructor for Builder. */ @@ -855,6 +886,18 @@ public final class NetworkRegistrationInfo implements Parcelable { } /** + * Set the registered PLMN. + * + * @param rplmn the registered plmn. + * + * @return The same instance of the builder. + */ + public @NonNull Builder setRegisteredPlmn(@Nullable String rplmn) { + mRplmn = rplmn; + return this; + } + + /** * Build the NetworkRegistrationInfo. * @return the NetworkRegistrationInfo object. * @hide @@ -863,7 +906,7 @@ public final class NetworkRegistrationInfo implements Parcelable { public @NonNull NetworkRegistrationInfo build() { return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, - mCellIdentity); + mCellIdentity, mRplmn); } } } diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java index 87d94bfda662..c75de42707a6 100644 --- a/telephony/java/android/telephony/NetworkService.java +++ b/telephony/java/android/telephony/NetworkService.java @@ -234,6 +234,9 @@ public abstract class NetworkService extends Service { * this method to facilitate the creation of {@link NetworkServiceProvider} instances. The system * will call this method after binding the network service for each active SIM slot id. * + * This methead is guaranteed to be invoked in {@link NetworkService}'s internal handler thread + * whose looper can be retrieved with {@link Looper.myLooper()} when override this method. + * * @param slotIndex SIM slot id the network service associated with. * @return Network service object. Null if failed to create the provider (e.g. invalid slot * index) diff --git a/telephony/java/android/telephony/PinResult.java b/telephony/java/android/telephony/PinResult.java index 683e85387c08..68c9d998ba92 100644 --- a/telephony/java/android/telephony/PinResult.java +++ b/telephony/java/android/telephony/PinResult.java @@ -19,7 +19,6 @@ package android.telephony; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -32,7 +31,6 @@ import java.util.Objects; * * @hide */ -@SystemApi public final class PinResult implements Parcelable { /** @hide */ @IntDef({ diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index 54c22ae282fb..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, @@ -265,10 +264,10 @@ public final class PreciseDataConnectionState implements Parcelable { /** * Return the APN Settings for this data connection. * - * Returns the ApnSetting that was used to configure this data connection. + * @return the ApnSetting that was used to configure this data connection. */ // FIXME: This shouldn't be nullable; update once the ApnSetting is supplied correctly - @Nullable ApnSetting getApnSetting() { + public @Nullable ApnSetting getApnSetting() { return mApnSetting; } diff --git a/telephony/java/android/telephony/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 f8e4bea9d98e..82470d41842d 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -580,7 +580,6 @@ public class ServiceState implements Parcelable { * * @hide */ - @SystemApi public @RegState int getDataRegistrationState() { return getDataRegState(); } @@ -1422,7 +1421,6 @@ public class ServiceState implements Parcelable { * @return the frequency range of 5G NR. * @hide */ - @SystemApi public @FrequencyRange int getNrFrequencyRange() { return mNrFrequencyRange; } @@ -1993,7 +1991,6 @@ public class ServiceState implements Parcelable { * @return the copied ServiceState with location info sanitized. * @hide */ - @SystemApi @NonNull public ServiceState createLocationInfoSanitizedCopy(boolean removeCoarseLocation) { ServiceState state = new ServiceState(this); diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index fe78588121c6..0f52ba7935ab 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -389,7 +389,7 @@ public final class SmsManager { String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, - true /* persistMessage*/, null); + true /* persistMessage*/, null, null); } /** @@ -507,7 +507,7 @@ public final class SmsManager { private void sendTextMessageInternal(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, - boolean persistMessage, String packageName) { + boolean persistMessage, String packageName, String attributionTag) { if (TextUtils.isEmpty(destinationAddress)) { throw new IllegalArgumentException("Invalid destinationAddress"); } @@ -532,7 +532,7 @@ public final class SmsManager { public void onSuccess(int subId) { ISms iSms = getISmsServiceOrThrow(); try { - iSms.sendTextForSubscriber(subId, packageName, + iSms.sendTextForSubscriber(subId, packageName, attributionTag, destinationAddress, scAddress, text, sentIntent, deliveryIntent, persistMessage); } catch (RemoteException e) { @@ -552,7 +552,7 @@ public final class SmsManager { // visible to the user. ISms iSms = getISmsServiceOrThrow(); try { - iSms.sendTextForSubscriber(getSubscriptionId(), packageName, + iSms.sendTextForSubscriber(getSubscriptionId(), packageName, attributionTag, destinationAddress, scAddress, text, sentIntent, deliveryIntent, persistMessage); } catch (RemoteException e) { @@ -599,7 +599,7 @@ public final class SmsManager { String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, - false /* persistMessage */, null); + false /* persistMessage */, null, null); } private void sendTextMessageInternal( @@ -642,7 +642,7 @@ public final class SmsManager { ISms iSms = getISmsServiceOrThrow(); if (iSms != null) { iSms.sendTextForSubscriberWithOptions(subId, - null, destinationAddress, + null, null, destinationAddress, scAddress, text, sentIntent, deliveryIntent, persistMessage, finalPriority, expectMore, finalValidity); @@ -664,7 +664,7 @@ public final class SmsManager { ISms iSms = getISmsServiceOrThrow(); if (iSms != null) { iSms.sendTextForSubscriberWithOptions(getSubscriptionId(), - null, destinationAddress, + null, null, destinationAddress, scAddress, text, sentIntent, deliveryIntent, persistMessage, finalPriority, expectMore, finalValidity); @@ -882,7 +882,24 @@ public final class SmsManager { String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, - deliveryIntents, true /* persistMessage*/, null); + deliveryIntents, true /* persistMessage*/, null, null); + } + + /** + * @deprecated Use {@link #sendMultipartTextMessage(String, String, List, List, List, String, + * String)} instead. + * + * @hide + */ + @Deprecated + @SystemApi + @TestApi + public void sendMultipartTextMessage( + @NonNull String destinationAddress, @NonNull String scAddress, + @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents, + @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) { + sendMultipartTextMessage(destinationAddress, scAddress, parts, sentIntents, deliveryIntents, + packageName, null); } /** @@ -909,15 +926,16 @@ public final class SmsManager { public void sendMultipartTextMessage( @NonNull String destinationAddress, @NonNull String scAddress, @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents, - @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) { + @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName, + @Nullable String attributionTag) { sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, - deliveryIntents, true /* persistMessage*/, packageName); + deliveryIntents, true /* persistMessage*/, packageName, attributionTag); } private void sendMultipartTextMessageInternal( String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, - boolean persistMessage, String packageName) { + boolean persistMessage, String packageName, String attributionTag) { if (TextUtils.isEmpty(destinationAddress)) { throw new IllegalArgumentException("Invalid destinationAddress"); } @@ -942,7 +960,7 @@ public final class SmsManager { public void onSuccess(int subId) { try { ISms iSms = getISmsServiceOrThrow(); - iSms.sendMultipartTextForSubscriber(subId, packageName, + iSms.sendMultipartTextForSubscriber(subId, packageName, attributionTag, destinationAddress, scAddress, parts, sentIntents, deliveryIntents, persistMessage); } catch (RemoteException e) { @@ -963,8 +981,8 @@ public final class SmsManager { ISms iSms = getISmsServiceOrThrow(); if (iSms != null) { iSms.sendMultipartTextForSubscriber(getSubscriptionId(), packageName, - destinationAddress, scAddress, parts, sentIntents, deliveryIntents, - persistMessage); + attributionTag, destinationAddress, scAddress, parts, sentIntents, + deliveryIntents, persistMessage); } } catch (RemoteException e) { Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - " @@ -982,7 +1000,7 @@ public final class SmsManager { deliveryIntent = deliveryIntents.get(0); } sendTextMessageInternal(destinationAddress, scAddress, parts.get(0), - sentIntent, deliveryIntent, true, packageName); + sentIntent, deliveryIntent, true, packageName, attributionTag); } } @@ -1012,7 +1030,7 @@ public final class SmsManager { String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, - deliveryIntents, false /* persistMessage*/, null); + deliveryIntents, false /* persistMessage*/, null, null); } /** @@ -1174,7 +1192,7 @@ public final class SmsManager { ISms iSms = getISmsServiceOrThrow(); if (iSms != null) { iSms.sendMultipartTextForSubscriberWithOptions(subId, - null, destinationAddress, + null, null, destinationAddress, scAddress, parts, sentIntents, deliveryIntents, persistMessage, finalPriority, expectMore, finalValidity); } @@ -1196,7 +1214,7 @@ public final class SmsManager { ISms iSms = getISmsServiceOrThrow(); if (iSms != null) { iSms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(), - null, destinationAddress, + null, null, destinationAddress, scAddress, parts, sentIntents, deliveryIntents, persistMessage, finalPriority, expectMore, finalValidity); } @@ -1327,9 +1345,8 @@ public final class SmsManager { public void onSuccess(int subId) { try { ISms iSms = getISmsServiceOrThrow(); - iSms.sendDataForSubscriber(subId, null, - destinationAddress, scAddress, destinationPort & 0xFFFF, data, - sentIntent, deliveryIntent); + iSms.sendDataForSubscriber(subId, null, null, destinationAddress, scAddress, + destinationPort & 0xFFFF, data, sentIntent, deliveryIntent); } catch (RemoteException e) { Log.e(TAG, "sendDataMessage: Couldn't send SMS - Exception: " + e.getMessage()); notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION); @@ -1481,7 +1498,7 @@ public final class SmsManager { // it here because we do not have access to the activity context that is performing this // operation. // Requires that the calling process has the SEND_SMS permission. - getITelephony().enqueueSmsPickResult(null, + getITelephony().enqueueSmsPickResult(null, null, new IIntegerConsumer.Stub() { @Override public void accept(int subId) { @@ -2751,7 +2768,7 @@ public final class SmsManager { getSubscriptionId(), null); } } catch (RemoteException ex) { - throw new RuntimeException(ex); + // ignore it } return smsc; } @@ -2773,8 +2790,7 @@ public final class SmsManager { * </p> * * @param smsc the SMSC address string. - * @return true for success, false otherwise. Failure can be due to caller not having the - * appropriate permission, or modem returning an error. + * @return true for success, false otherwise. */ @SuppressAutoDoc // for carrier privileges and default SMS application. @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @@ -2786,7 +2802,7 @@ public final class SmsManager { smsc, getSubscriptionId(), null); } } catch (RemoteException ex) { - throw new RuntimeException(ex); + // ignore it } return false; } diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index 832771daa409..dc75c58e9420 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -226,7 +226,7 @@ public class SubscriptionInfo implements Parcelable { this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number, roaming, icon, mcc, mnc, countryIso, isEmbedded, nativeAccessRules, cardString, -1, false, null, false, TelephonyManager.UNKNOWN_CARRIER_ID, - SubscriptionManager.PROFILE_CLASS_DEFAULT, + SubscriptionManager.PROFILE_CLASS_UNSET, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true); } @@ -798,7 +798,7 @@ public class SubscriptionInfo implements Parcelable { + " hplmns=" + Arrays.toString(mHplmns) + " subscriptionType=" + mSubscriptionType + " mGroupOwner=" + mGroupOwner - + " carrierConfigAccessRules=" + mCarrierConfigAccessRules + + " carrierConfigAccessRules=" + Arrays.toString(mCarrierConfigAccessRules) + " mAreUiccApplicationsEnabled=" + mAreUiccApplicationsEnabled + "}"; } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index d8cebfbef8a4..d4a76b7c1154 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -265,7 +265,8 @@ public class SubscriptionManager { * <P>Type: TEXT (String)</P> */ /** @hide */ - public static final String UNIQUE_KEY_SUBSCRIPTION_ID = SimInfo.UNIQUE_KEY_SUBSCRIPTION_ID; + public static final String UNIQUE_KEY_SUBSCRIPTION_ID = + SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID; /** * TelephonyProvider column name for a unique identifier for the subscription within the @@ -274,14 +275,14 @@ public class SubscriptionManager { * <P>Type: TEXT (String)</P> */ /** @hide */ - public static final String ICC_ID = SimInfo.ICC_ID; + public static final String ICC_ID = SimInfo.COLUMN_ICC_ID; /** * TelephonyProvider column name for user SIM_SlOT_INDEX * <P>Type: INTEGER (int)</P> */ /** @hide */ - public static final String SIM_SLOT_INDEX = SimInfo.SIM_SLOT_INDEX; + public static final String SIM_SLOT_INDEX = SimInfo.COLUMN_SIM_SLOT_INDEX; /** SIM is not inserted */ /** @hide */ @@ -300,7 +301,7 @@ public class SubscriptionManager { * Default value is 0. */ /** @hide */ - public static final String SUBSCRIPTION_TYPE = SimInfo.SUBSCRIPTION_TYPE; + public static final String SUBSCRIPTION_TYPE = SimInfo.COLUMN_SUBSCRIPTION_TYPE; /** * TelephonyProvider column name data_enabled_override_rules. @@ -313,7 +314,8 @@ public class SubscriptionManager { * * @hide */ - public static final String DATA_ENABLED_OVERRIDE_RULES = SimInfo.DATA_ENABLED_OVERRIDE_RULES; + public static final String DATA_ENABLED_OVERRIDE_RULES = + SimInfo.COLUMN_DATA_ENABLED_OVERRIDE_RULES; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -362,14 +364,14 @@ public class SubscriptionManager { * <P>Type: TEXT (String)</P> */ /** @hide */ - public static final String DISPLAY_NAME = SimInfo.DISPLAY_NAME; + public static final String DISPLAY_NAME = SimInfo.COLUMN_DISPLAY_NAME; /** * TelephonyProvider column name for the service provider name for the SIM. * <P>Type: TEXT (String)</P> */ /** @hide */ - public static final String CARRIER_NAME = SimInfo.CARRIER_NAME; + public static final String CARRIER_NAME = SimInfo.COLUMN_CARRIER_NAME; /** * Default name resource @@ -383,13 +385,13 @@ public class SubscriptionManager { * * @hide */ - public static final String NAME_SOURCE = SimInfo.NAME_SOURCE; + public static final String NAME_SOURCE = SimInfo.COLUMN_NAME_SOURCE; /** - * The name_source is the default, which is from the carrier id. + * The name_source is from the carrier id. * @hide */ - public static final int NAME_SOURCE_DEFAULT = SimInfo.NAME_SOURCE_DEFAULT; + public static final int NAME_SOURCE_CARRIER_ID = SimInfo.NAME_SOURCE_CARRIER_ID; /** * The name_source is from SIM EF_SPN. @@ -420,7 +422,7 @@ public class SubscriptionManager { @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"NAME_SOURCE_"}, value = { - NAME_SOURCE_DEFAULT, + NAME_SOURCE_CARRIER_ID, NAME_SOURCE_SIM_SPN, NAME_SOURCE_USER_INPUT, NAME_SOURCE_CARRIER, @@ -433,21 +435,21 @@ public class SubscriptionManager { * <P>Type: INTEGER (int)</P> */ /** @hide */ - public static final String COLOR = SimInfo.COLOR; + public static final String HUE = SimInfo.COLUMN_COLOR; /** * TelephonyProvider column name for the phone number of a SIM. * <P>Type: TEXT (String)</P> */ /** @hide */ - public static final String NUMBER = SimInfo.NUMBER; + public static final String NUMBER = SimInfo.COLUMN_NUMBER; /** * TelephonyProvider column name for whether data roaming is enabled. * <P>Type: INTEGER (int)</P> */ /** @hide */ - public static final String DATA_ROAMING = SimInfo.DATA_ROAMING; + public static final String DATA_ROAMING = SimInfo.COLUMN_DATA_ROAMING; /** Indicates that data roaming is enabled for a subscription */ public static final int DATA_ROAMING_ENABLE = SimInfo.DATA_ROAMING_ENABLE; @@ -455,63 +457,60 @@ public class SubscriptionManager { /** Indicates that data roaming is disabled for a subscription */ public static final int DATA_ROAMING_DISABLE = SimInfo.DATA_ROAMING_DISABLE; - /** @hide */ - public static final int DATA_ROAMING_DEFAULT = SimInfo.DATA_ROAMING_DEFAULT; - /** * TelephonyProvider column name for subscription carrier id. * @see TelephonyManager#getSimCarrierId() * <p>Type: INTEGER (int) </p> * @hide */ - public static final String CARRIER_ID = SimInfo.CARRIER_ID; + public static final String CARRIER_ID = SimInfo.COLUMN_CARRIER_ID; /** * @hide A comma-separated list of EHPLMNs associated with the subscription * <P>Type: TEXT (String)</P> */ - public static final String EHPLMNS = SimInfo.EHPLMNS; + public static final String EHPLMNS = SimInfo.COLUMN_EHPLMNS; /** * @hide A comma-separated list of HPLMNs associated with the subscription * <P>Type: TEXT (String)</P> */ - public static final String HPLMNS = SimInfo.HPLMNS; + public static final String HPLMNS = SimInfo.COLUMN_HPLMNS; /** * TelephonyProvider column name for the MCC associated with a SIM, stored as a string. * <P>Type: TEXT (String)</P> * @hide */ - public static final String MCC_STRING = SimInfo.MCC_STRING; + public static final String MCC_STRING = SimInfo.COLUMN_MCC_STRING; /** * TelephonyProvider column name for the MNC associated with a SIM, stored as a string. * <P>Type: TEXT (String)</P> * @hide */ - public static final String MNC_STRING = SimInfo.MNC_STRING; + public static final String MNC_STRING = SimInfo.COLUMN_MNC_STRING; /** * TelephonyProvider column name for the MCC associated with a SIM. * <P>Type: INTEGER (int)</P> * @hide */ - public static final String MCC = SimInfo.MCC; + public static final String MCC = SimInfo.COLUMN_MCC; /** * TelephonyProvider column name for the MNC associated with a SIM. * <P>Type: INTEGER (int)</P> * @hide */ - public static final String MNC = SimInfo.MNC; + public static final String MNC = SimInfo.COLUMN_MNC; /** * TelephonyProvider column name for the iso country code associated with a SIM. * <P>Type: TEXT (String)</P> * @hide */ - public static final String ISO_COUNTRY_CODE = SimInfo.ISO_COUNTRY_CODE; + public static final String ISO_COUNTRY_CODE = SimInfo.COLUMN_ISO_COUNTRY_CODE; /** * TelephonyProvider column name for whether a subscription is embedded (that is, present on an @@ -519,7 +518,7 @@ public class SubscriptionManager { * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded. * @hide */ - public static final String IS_EMBEDDED = SimInfo.IS_EMBEDDED; + public static final String IS_EMBEDDED = SimInfo.COLUMN_IS_EMBEDDED; /** * TelephonyProvider column name for SIM card identifier. For UICC card it is the ICCID of the @@ -527,7 +526,7 @@ public class SubscriptionManager { * <P>Type: TEXT (String)</P> * @hide */ - public static final String CARD_ID = SimInfo.CARD_ID; + public static final String CARD_ID = SimInfo.COLUMN_CARD_ID; /** * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from @@ -535,7 +534,7 @@ public class SubscriptionManager { * <p>TYPE: BLOB * @hide */ - public static final String ACCESS_RULES = SimInfo.ACCESS_RULES; + public static final String ACCESS_RULES = SimInfo.COLUMN_ACCESS_RULES; /** * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from @@ -545,7 +544,7 @@ public class SubscriptionManager { * @hide */ public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS = - SimInfo.ACCESS_RULES_FROM_CARRIER_CONFIGS; + SimInfo.COLUMN_ACCESS_RULES_FROM_CARRIER_CONFIGS; /** * TelephonyProvider column name identifying whether an embedded subscription is on a removable @@ -555,79 +554,82 @@ public class SubscriptionManager { * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable. * @hide */ - public static final String IS_REMOVABLE = SimInfo.IS_REMOVABLE; + public static final String IS_REMOVABLE = SimInfo.COLUMN_IS_REMOVABLE; /** * TelephonyProvider column name for extreme threat in CB settings * @hide */ - public static final String CB_EXTREME_THREAT_ALERT = SimInfo.CB_EXTREME_THREAT_ALERT; + public static final String CB_EXTREME_THREAT_ALERT = + SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT; /** * TelephonyProvider column name for severe threat in CB settings *@hide */ - public static final String CB_SEVERE_THREAT_ALERT = SimInfo.CB_SEVERE_THREAT_ALERT; + public static final String CB_SEVERE_THREAT_ALERT = SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT; /** * TelephonyProvider column name for amber alert in CB settings *@hide */ - public static final String CB_AMBER_ALERT = SimInfo.CB_AMBER_ALERT; + public static final String CB_AMBER_ALERT = SimInfo.COLUMN_CB_AMBER_ALERT; /** * TelephonyProvider column name for emergency alert in CB settings *@hide */ - public static final String CB_EMERGENCY_ALERT = SimInfo.CB_EMERGENCY_ALERT; + public static final String CB_EMERGENCY_ALERT = SimInfo.COLUMN_CB_EMERGENCY_ALERT; /** * TelephonyProvider column name for alert sound duration in CB settings *@hide */ - public static final String CB_ALERT_SOUND_DURATION = SimInfo.CB_ALERT_SOUND_DURATION; + public static final String CB_ALERT_SOUND_DURATION = + SimInfo.COLUMN_CB_ALERT_SOUND_DURATION; /** * TelephonyProvider column name for alert reminder interval in CB settings *@hide */ - public static final String CB_ALERT_REMINDER_INTERVAL = SimInfo.CB_ALERT_REMINDER_INTERVAL; + public static final String CB_ALERT_REMINDER_INTERVAL = + SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL; /** * TelephonyProvider column name for enabling vibrate in CB settings *@hide */ - public static final String CB_ALERT_VIBRATE = SimInfo.CB_ALERT_VIBRATE; + public static final String CB_ALERT_VIBRATE = SimInfo.COLUMN_CB_ALERT_VIBRATE; /** * TelephonyProvider column name for enabling alert speech in CB settings *@hide */ - public static final String CB_ALERT_SPEECH = SimInfo.CB_ALERT_SPEECH; + public static final String CB_ALERT_SPEECH = SimInfo.COLUMN_CB_ALERT_SPEECH; /** * TelephonyProvider column name for ETWS test alert in CB settings *@hide */ - public static final String CB_ETWS_TEST_ALERT = SimInfo.CB_ETWS_TEST_ALERT; + public static final String CB_ETWS_TEST_ALERT = SimInfo.COLUMN_CB_ETWS_TEST_ALERT; /** * TelephonyProvider column name for enable channel50 alert in CB settings *@hide */ - public static final String CB_CHANNEL_50_ALERT = SimInfo.CB_CHANNEL_50_ALERT; + public static final String CB_CHANNEL_50_ALERT = SimInfo.COLUMN_CB_CHANNEL_50_ALERT; /** * TelephonyProvider column name for CMAS test alert in CB settings *@hide */ - public static final String CB_CMAS_TEST_ALERT = SimInfo.CB_CMAS_TEST_ALERT; + public static final String CB_CMAS_TEST_ALERT = SimInfo.COLUMN_CB_CMAS_TEST_ALERT; /** * TelephonyProvider column name for Opt out dialog in CB settings *@hide */ - public static final String CB_OPT_OUT_DIALOG = SimInfo.CB_OPT_OUT_DIALOG; + public static final String CB_OPT_OUT_DIALOG = SimInfo.COLUMN_CB_OPT_OUT_DIALOG; /** * TelephonyProvider column name for enable Volte. @@ -636,44 +638,45 @@ public class SubscriptionManager { * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}. *@hide */ - public static final String ENHANCED_4G_MODE_ENABLED = SimInfo.ENHANCED_4G_MODE_ENABLED; + public static final String ENHANCED_4G_MODE_ENABLED = + SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED; /** * TelephonyProvider column name for enable VT (Video Telephony over IMS) *@hide */ - public static final String VT_IMS_ENABLED = SimInfo.VT_IMS_ENABLED; + public static final String VT_IMS_ENABLED = SimInfo.COLUMN_VT_IMS_ENABLED; /** * TelephonyProvider column name for enable Wifi calling *@hide */ - public static final String WFC_IMS_ENABLED = SimInfo.WFC_IMS_ENABLED; + public static final String WFC_IMS_ENABLED = SimInfo.COLUMN_WFC_IMS_ENABLED; /** * TelephonyProvider column name for Wifi calling mode *@hide */ - public static final String WFC_IMS_MODE = SimInfo.WFC_IMS_MODE; + public static final String WFC_IMS_MODE = SimInfo.COLUMN_WFC_IMS_MODE; /** * TelephonyProvider column name for Wifi calling mode in roaming *@hide */ - public static final String WFC_IMS_ROAMING_MODE = SimInfo.WFC_IMS_ROAMING_MODE; + public static final String WFC_IMS_ROAMING_MODE = SimInfo.COLUMN_WFC_IMS_ROAMING_MODE; /** * TelephonyProvider column name for enable Wifi calling in roaming *@hide */ - public static final String WFC_IMS_ROAMING_ENABLED = SimInfo.WFC_IMS_ROAMING_ENABLED; + public static final String WFC_IMS_ROAMING_ENABLED = SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED; /** * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this * subscription. * @hide */ - public static final String IMS_RCS_UCE_ENABLED = SimInfo.IMS_RCS_UCE_ENABLED; + public static final String IMS_RCS_UCE_ENABLED = SimInfo.COLUMN_IMS_RCS_UCE_ENABLED; /** * TelephonyProvider column name for whether a subscription is opportunistic, that is, @@ -682,7 +685,7 @@ public class SubscriptionManager { * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic. * @hide */ - public static final String IS_OPPORTUNISTIC = SimInfo.IS_OPPORTUNISTIC; + public static final String IS_OPPORTUNISTIC = SimInfo.COLUMN_IS_OPPORTUNISTIC; /** * TelephonyProvider column name for group ID. Subscriptions with same group ID @@ -691,7 +694,7 @@ public class SubscriptionManager { * * @hide */ - public static final String GROUP_UUID = SimInfo.GROUP_UUID; + public static final String GROUP_UUID = SimInfo.COLUMN_GROUP_UUID; /** * TelephonyProvider column name for group owner. It's the package name who created @@ -699,7 +702,7 @@ public class SubscriptionManager { * * @hide */ - public static final String GROUP_OWNER = SimInfo.GROUP_OWNER; + public static final String GROUP_OWNER = SimInfo.COLUMN_GROUP_OWNER; /** * TelephonyProvider column name for the profile class of a subscription @@ -707,7 +710,7 @@ public class SubscriptionManager { * <P>Type: INTEGER (int)</P> * @hide */ - public static final String PROFILE_CLASS = SimInfo.PROFILE_CLASS; + public static final String PROFILE_CLASS = SimInfo.COLUMN_PROFILE_CLASS; /** * Profile class of the subscription @@ -719,7 +722,6 @@ public class SubscriptionManager { SimInfo.PROFILE_CLASS_PROVISIONING, SimInfo.PROFILE_CLASS_OPERATIONAL, SimInfo.PROFILE_CLASS_UNSET, - SimInfo.PROFILE_CLASS_DEFAULT }) public @interface ProfileClass {} @@ -765,7 +767,8 @@ public class SubscriptionManager { * @hide */ @SystemApi - public static final int PROFILE_CLASS_DEFAULT = SimInfo.PROFILE_CLASS_DEFAULT; + @Deprecated + public static final int PROFILE_CLASS_DEFAULT = SimInfo.PROFILE_CLASS_UNSET; /** * IMSI (International Mobile Subscriber Identity). @@ -773,19 +776,19 @@ public class SubscriptionManager { * @hide */ //TODO: add @SystemApi - public static final String IMSI = SimInfo.IMSI; + public static final String IMSI = SimInfo.COLUMN_IMSI; /** * Whether uicc applications is set to be enabled or disabled. By default it's enabled. * @hide */ - public static final String UICC_APPLICATIONS_ENABLED = SimInfo.UICC_APPLICATIONS_ENABLED; + public static final String UICC_APPLICATIONS_ENABLED = SimInfo.COLUMN_UICC_APPLICATIONS_ENABLED; /** * Indicate which network type is allowed. By default it's enabled. * @hide */ - public static final String ALLOWED_NETWORK_TYPES = SimInfo.ALLOWED_NETWORK_TYPES; + public static final String ALLOWED_NETWORK_TYPES = SimInfo.COLUMN_ALLOWED_NETWORK_TYPES; /** * Broadcast Action: The user has changed one of the default subs related to @@ -2680,8 +2683,8 @@ public class SubscriptionManager { * @hide */ @SystemApi - public boolean canManageSubscription(@Nullable SubscriptionInfo info, - @Nullable String packageName) { + public boolean canManageSubscription(@NonNull SubscriptionInfo info, + @NonNull String packageName) { if (info == null || info.getAllAccessRules() == null || packageName == null) { return false; } @@ -3186,13 +3189,13 @@ public class SubscriptionManager { * * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required * - * @param enabled whether uicc applications are enabled or disabled. * @param subscriptionId which subscription to operate on. + * @param enabled whether uicc applications are enabled or disabled. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) - public void setUiccApplicationsEnabled(boolean enabled, int subscriptionId) { + public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) { if (VDBG) { logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled); } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index c2b4ec9d80a5..c37262c6d2cc 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -53,6 +53,7 @@ import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; @@ -69,13 +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; @@ -1030,7 +1031,7 @@ public class TelephonyManager { * or that all steps during multi-SIM change are done. To know those information you still need * to listen to SIM_STATE changes or active subscription changes. * - * See extra of {@link #EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED} for updated value. + * See extra of {@link #EXTRA_ACTIVE_SIM_SUPPORTED_COUNT} for updated value. */ public static final String ACTION_MULTI_SIM_CONFIG_CHANGED = "android.telephony.action.MULTI_SIM_CONFIG_CHANGED"; @@ -1040,6 +1041,8 @@ public class TelephonyManager { * The number of active SIM supported by current multi-SIM config. It's not related to how many * SIM/subscriptions are currently active. * + * Same value will be returned by {@link #getActiveModemCount()}. + * * For single SIM mode, it's 1. * For DSDS or DSDA mode, it's 2. * For triple-SIM mode, it's 3. @@ -1048,8 +1051,8 @@ public class TelephonyManager { * * type: integer */ - public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED = - "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED"; + public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = + "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT"; /** * @hide @@ -2300,7 +2303,12 @@ public class TelephonyManager { public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA; /** Phone is via SIP. */ public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP; - /** Phone is via IMS. */ + + /** + * Phone is via IMS. + * + * @hide + */ public static final int PHONE_TYPE_IMS = PhoneConstants.PHONE_TYPE_IMS; /** @@ -2308,7 +2316,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi public static final int PHONE_TYPE_THIRD_PARTY = PhoneConstants.PHONE_TYPE_THIRD_PARTY; /** @@ -2705,39 +2712,22 @@ public class TelephonyManager { /** * Returns the ISO-3166 country code equivalent of the MCC (Mobile Country Code) of the current * registered operator or the cell nearby, if available. - * <p> - * The ISO-3166 country code is provided in lowercase 2 character format. - * <p> - * Note: In multi-sim, this returns a shared emergency network country iso from other - * subscription if the subscription used to create the TelephonyManager doesn't camp on - * a network due to some reason (e.g. pin/puk locked), or sim is absent in the corresponding - * slot. + * * Note: Result may be unreliable on CDMA networks (use {@link #getPhoneType()} to determine * if on a CDMA network). * <p> * @return the lowercase 2 character ISO-3166 country code, or empty string if not available. */ public String getNetworkCountryIso() { - try { - ITelephony telephony = getITelephony(); - if (telephony == null) return ""; - return telephony.getNetworkCountryIsoForPhone(getPhoneId(), - null /* no permission check */, null); - } catch (RemoteException ex) { - return ""; - } + return getNetworkCountryIso(getSlotIndex()); } /** * Returns the ISO-3166 country code equivalent of the MCC (Mobile Country Code) of the current - * registered operator or the cell nearby, if available. - * <p> - * The ISO-3166 country code is provided in lowercase 2 character format. - * <p> - * Note: In multi-sim, this returns a shared emergency network country iso from other - * subscription if the subscription used to create the TelephonyManager doesn't camp on - * a network due to some reason (e.g. pin/puk locked), or sim is absent in the corresponding - * slot. + * registered operator or the cell nearby, if available. This is same as + * {@link #getNetworkCountryIso()} but allowing specifying the SIM slot index. This is used for + * accessing network country info from the SIM slot that does not have SIM inserted. + * * Note: Result may be unreliable on CDMA networks (use {@link #getPhoneType()} to determine * if on a CDMA network). * <p> @@ -2748,27 +2738,34 @@ public class TelephonyManager { * * @throws IllegalArgumentException when the slotIndex is invalid. * - * {@hide} */ - @SystemApi - @TestApi @NonNull - @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getNetworkCountryIso(int slotIndex) { try { - if (!SubscriptionManager.isValidSlotIndex(slotIndex)) { + if (slotIndex != SubscriptionManager.DEFAULT_SIM_SLOT_INDEX + && !SubscriptionManager.isValidSlotIndex(slotIndex)) { throw new IllegalArgumentException("invalid slot index " + slotIndex); } ITelephony telephony = getITelephony(); if (telephony == null) return ""; - return telephony.getNetworkCountryIsoForPhone(slotIndex, getOpPackageName(), - getFeatureId()); + return telephony.getNetworkCountryIsoForPhone(slotIndex); } catch (RemoteException ex) { return ""; } } + /** + * @hide + * @deprecated Use {@link #getNetworkCountryIso(int)} instead. + */ + @Deprecated + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@link #getNetworkCountryIso(int)} instead.") + public String getNetworkCountryIsoForPhone(int phoneId) { + return getNetworkCountryIso(phoneId); + } + /* * When adding a network type to the list below, make sure to add the correct icon to * MobileSignalController.mapIconSets() as well as NETWORK_TYPES @@ -3013,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 @@ -4877,7 +4816,7 @@ public class TelephonyManager { ITelephony telephony = getITelephony(); if (telephony != null) { telephony.sendVisualVoicemailSmsForSubscriber( - mContext.getOpPackageName(), subId, number, port, text, sentIntent); + mContext.getOpPackageName(), null, subId, number, port, text, sentIntent); } } catch (RemoteException ex) { } @@ -7935,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); } @@ -8691,7 +8628,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public PinResult supplyPinReportPinResult(@NonNull String pin) { @@ -8716,7 +8652,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public PinResult supplyPukReportPinResult(@NonNull String puk, @NonNull String pin) { @@ -8908,7 +8843,10 @@ public class TelephonyManager { } /** - * Shut down all the live radios over all the slot index. + * Shut down all the live radios over all the slot indexes. + * + * <p>To know when the radio has completed powering off, use + * {@link PhoneStateListener#LISTEN_SERVICE_STATE LISTEN_SERVICE_STATE}. * * @hide */ @@ -8921,7 +8859,8 @@ public class TelephonyManager { telephony.shutdownMobileRadios(); } } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#shutdownMobileRadios", e); + Log.e(TAG, "Error calling ITelephony#shutdownAllRadios", e); + e.rethrowAsRuntimeException(); } } @@ -8940,7 +8879,8 @@ public class TelephonyManager { return telephony.needMobileRadioShutdown(); } } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#needMobileRadioShutdown", e); + Log.e(TAG, "Error calling ITelephony#isAnyRadioPoweredOn", e); + e.rethrowAsRuntimeException(); } return false; } @@ -9170,7 +9110,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public @CdmaRoamingMode int getCdmaRoamingMode() { int mode = CDMA_ROAMING_MODE_RADIO_DEFAULT; @@ -9199,7 +9138,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCdmaRoamingMode(@CdmaRoamingMode int mode) { try { @@ -9225,19 +9163,16 @@ public class TelephonyManager { /** Used for CDMA subscription mode, it'll be UNKNOWN if there is no Subscription source. * @hide */ - @SystemApi public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; /** Used for CDMA subscription mode: RUIM/SIM (default) * @hide */ - @SystemApi public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; /** Used for CDMA subscription mode: NV -> non-volatile memory * @hide */ - @SystemApi public static final int CDMA_SUBSCRIPTION_NV = 1; /** @hide */ @@ -9256,7 +9191,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCdmaSubscriptionMode(@CdmaSubscription int mode) { try { @@ -9813,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(), ""); } @@ -11074,7 +10988,6 @@ public class TelephonyManager { * @param isEnabled {@code true} for enabling; {@code false} for disabling. * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAlwaysReportSignalStrength(boolean isEnabled) { try { @@ -11109,21 +11022,21 @@ public class TelephonyManager { } /** - * Checks whether cellular data connection is enabled in the device. - * - * Whether cellular data connection is enabled, meaning upon request whether will try to setup - * metered data connection considering all factors below: - * 1) User turned on data setting {@link #isDataEnabled}. - * 2) Carrier allows data to be on. - * 3) Network policy. - * And possibly others. + * Checks whether cellular data connection is allowed in the device. * - * @return {@code true} if the overall data connection is capable; {@code false} if not. + * <p>Whether cellular data connection is allowed considers all factors below: + * <UL> + * <LI>User turned on data setting {@link #isDataEnabled}.</LI> + * <LI>Carrier allows data to be on.</LI> + * <LI>Network policy.</LI> + * <LI>And possibly others.</LI> + * </UL> + * @return {@code true} if the overall data connection is allowed; {@code false} if not. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public boolean isDataConnectionEnabled() { + public boolean isDataConnectionAllowed() { boolean retVal = false; try { int subId = getSubId(SubscriptionManager.getDefaultDataSubscriptionId()); @@ -11131,8 +11044,7 @@ public class TelephonyManager { if (telephony != null) retVal = telephony.isDataEnabled(subId); } catch (RemoteException e) { - Log.e(TAG, "Error isDataConnectionEnabled", e); - } catch (NullPointerException e) { + Log.e(TAG, "Error isDataConnectionAllowed", e); } return retVal; } @@ -11502,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 * @@ -11563,11 +11524,9 @@ public class TelephonyManager { } /** - * Override the file path for testing OTA emergency number database in a file partition. + * Override the file path for OTA emergency number database in a file partition. * - * @param otaFilePath The test OTA emergency number database file path; - * if "RESET", recover the original database file partition. - * Format: <root file folder>@<file path> + * @param otaParcelFileDescriptor parcelable file descriptor for OTA emergency number database. * * <p> Requires permission: * {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} @@ -11577,16 +11536,42 @@ public class TelephonyManager { @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) @SystemApi @TestApi - public void updateTestOtaEmergencyNumberDbFilePath(@NonNull String otaFilePath) { + public void updateOtaEmergencyNumberDbFilePath( + @NonNull ParcelFileDescriptor otaParcelFileDescriptor) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - telephony.updateTestOtaEmergencyNumberDbFilePath(otaFilePath); + telephony.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor); } else { throw new IllegalStateException("telephony service is null."); } } catch (RemoteException ex) { - Log.e(TAG, "notifyOtaEmergencyNumberDatabaseInstalled RemoteException", ex); + Log.e(TAG, "updateOtaEmergencyNumberDbFilePath RemoteException", ex); + ex.rethrowAsRuntimeException(); + } + } + + /** + * Reset the file path to default for OTA emergency number database in a file partition. + * + * <p> Requires permission: + * {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + @SystemApi + @TestApi + public void resetOtaEmergencyNumberDbFilePath() { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + telephony.resetOtaEmergencyNumberDbFilePath(); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + Log.e(TAG, "resetOtaEmergencyNumberDbFilePath RemoteException", ex); ex.rethrowAsRuntimeException(); } } @@ -11790,7 +11775,7 @@ public class TelephonyManager { } /** - * A test API to return the emergency number db version. + * Returns the emergency number database version. * * <p>Requires Permission: * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} @@ -11799,6 +11784,7 @@ public class TelephonyManager { */ @TestApi @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion() { try { ITelephony telephony = getITelephony(); @@ -12171,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 @@ -12342,7 +12339,7 @@ public class TelephonyManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public int getCarrierPrivilegeStatus(int uid) { + public @CarrierPrivilegeStatus int getCarrierPrivilegeStatus(int uid) { try { ITelephony telephony = getITelephony(); if (telephony != null) { @@ -12588,7 +12585,6 @@ public class TelephonyManager { } /** -<<<<<<< HEAD * Gets the voice call forwarding info {@link CallForwardingInfo}, given the call forward * reason. * @@ -12608,7 +12604,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @NonNull public CallForwardingInfo getCallForwarding(@CallForwardingReason int callForwardingReason) { @@ -12655,7 +12650,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallForwarding(@NonNull CallForwardingInfo callForwardingInfo) { if (callForwardingInfo == null) { @@ -12696,7 +12690,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi public static final int CALL_WAITING_STATUS_ACTIVE = 1; /** @@ -12704,7 +12697,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi public static final int CALL_WAITING_STATUS_INACTIVE = 2; /** @@ -12712,7 +12704,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; /** @@ -12720,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. @@ -12731,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 { @@ -12757,7 +12761,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallWaitingStatus(boolean isEnable) { try { @@ -12788,7 +12791,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setDataAllowedDuringVoiceCall(boolean allow) { try { @@ -12817,7 +12819,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataAllowedInVoiceCall() { try { @@ -12864,7 +12865,6 @@ public class TelephonyManager { * The IccLock state or password was changed successfully. * @hide */ - @SystemApi public static final int CHANGE_ICC_LOCK_SUCCESS = Integer.MAX_VALUE; /** @@ -12877,7 +12877,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @WorkerThread @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isIccLockEnabled() { @@ -12914,7 +12913,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setIccLockEnabled(boolean enabled, @NonNull String password) { checkNotNull(password, "setIccLockEnabled password can't be null."); @@ -12948,7 +12946,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int changeIccLockPassword(@NonNull String oldPassword, @NonNull String newPassword) { checkNotNull(oldPassword, "changeIccLockPassword oldPassword can't be null."); diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index 6e630e3a7024..158ada94e3c6 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -18,7 +18,6 @@ package android.telephony.data; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.content.ContentValues; import android.database.Cursor; import android.hardware.radio.V1_5.ApnTypes; @@ -125,6 +124,15 @@ public class ApnSetting implements Parcelable { /** Authentication type for PAP or CHAP. */ public static final int AUTH_TYPE_PAP_OR_CHAP = 3; + /** @hide */ + @IntDef({ + Telephony.Carriers.SKIP_464XLAT_DEFAULT, + Telephony.Carriers.SKIP_464XLAT_DISABLE, + Telephony.Carriers.SKIP_464XLAT_ENABLE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Skip464XlatStatus {} + /** * APN types for data connections. These are usage categories for an APN * entry. One APN entry may support multiple APN types, eg, a single APN @@ -138,7 +146,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_ALL_STRING = "*"; /** @@ -146,7 +153,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_DEFAULT_STRING = "default"; @@ -155,7 +161,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_MMS_STRING = "mms"; @@ -164,7 +169,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_SUPL_STRING = "supl"; /** @@ -172,7 +176,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_DUN_STRING = "dun"; /** @@ -180,7 +183,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_HIPRI_STRING = "hipri"; /** @@ -188,7 +190,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_FOTA_STRING = "fota"; /** @@ -196,7 +197,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_IMS_STRING = "ims"; /** @@ -204,7 +204,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_CBS_STRING = "cbs"; /** @@ -212,7 +211,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_IA_STRING = "ia"; /** @@ -221,7 +219,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_EMERGENCY_STRING = "emergency"; /** @@ -229,7 +226,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_MCX_STRING = "mcx"; /** @@ -237,7 +233,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_XCAP_STRING = "xcap"; @@ -741,7 +736,7 @@ public class ApnSetting implements Parcelable { * @return SKIP_464XLAT_DEFAULT, SKIP_464XLAT_DISABLE or SKIP_464XLAT_ENABLE * @hide */ - @Carriers.Skip464XlatStatus + @Skip464XlatStatus public int getSkip464Xlat() { return mSkip464Xlat; } @@ -1412,7 +1407,6 @@ public class ApnSetting implements Parcelable { * @return comma delimited list of APN types. * @hide */ - @SystemApi @NonNull public static String getApnTypesStringFromBitmask(int apnTypeBitmask) { List<String> types = new ArrayList<>(); @@ -2061,7 +2055,7 @@ public class ApnSetting implements Parcelable { * @param skip464xlat skip464xlat for this APN * @hide */ - public Builder setSkip464Xlat(@Carriers.Skip464XlatStatus int skip464xlat) { + public Builder setSkip464Xlat(@Skip464XlatStatus int skip464xlat) { this.mSkip464Xlat = skip464xlat; return this; } diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java index 6c4e7ce51ebf..f56bbe13051c 100644 --- a/telephony/java/android/telephony/data/DataService.java +++ b/telephony/java/android/telephony/data/DataService.java @@ -458,6 +458,9 @@ public abstract class DataService extends Service { * this method to facilitate the creation of {@link DataServiceProvider} instances. The system * will call this method after binding the data service for each active SIM slot id. * + * This methead is guaranteed to be invoked in {@link DataService}'s internal handler thread + * whose looper can be retrieved with {@link Looper.myLooper()} when override this method. + * * @param slotIndex SIM slot id the data service associated with. * @return Data service object. Null if failed to create the provider (e.g. invalid slot index) */ diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index ccd28f433e40..44b0968eaa90 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -249,13 +249,69 @@ public class EuiccManager { * Key for an extra set on {@link PendingIntent} result callbacks providing a detailed result * code. * - * <p>This code is an implementation detail of the embedded subscription manager and is only - * intended for logging or debugging purposes. + * <p>The value of this key is an integer and contains two portions. The first byte is + * OperationCode and the reaming three bytes is the ErrorCode. + * + * OperationCode is the first byte of the result code and is a categorization which defines what + * type of operation took place when an error occurred. e.g {@link #OPERATION_DOWNLOAD} means + * the error is related to download.Since the OperationCode only uses at most one byte, the + * maximum allowed quantity is 255(0xFF). + * + * ErrorCode is the remaining three bytes of the result code, and it denotes what happened. + * e.g a combination of {@link #OPERATION_DOWNLOAD} and {@link #ERROR_TIME_OUT} will suggest the + * download operation has timed out. The only exception here is + * {@link #OPERATION_SMDX_SUBJECT_REASON_CODE}, where instead of ErrorCode, SubjectCode[5.2.6.1 + * from GSMA (SGP.22 v2.2) and ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2) are encoded. @see + * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE} and + * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE} + * + * In the case where ErrorCode contains a value of 0, it means it's an unknown error. E.g Intent + * only contains {@link #OPERATION_DOWNLOAD} and ErrorCode is 0 implies this is an unknown + * Download error. + * + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE} + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE} + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE} + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE} */ public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE"; /** + * Key for an extra set on {@link PendingIntent} result callbacks providing a + * OperationCode of {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}, + * value will be an int. + */ + public static final String EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE = + "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_OPERATION_CODE"; + + /** + * Key for an extra set on {@link PendingIntent} result callbacks providing a + * ErrorCode of {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}, + * value will be an int. + */ + public static final String EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE = + "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_ERROR_CODE"; + + /** + * Key for an extra set on {@link PendingIntent} result callbacks providing a + * SubjectCode[5.2.6.1] from GSMA (SGP.22 v2.2) decoded from + * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}. + * The value of this extra will be a String. + */ + public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE = + "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE"; + + /** + * Key for an extra set on {@link PendingIntent} result callbacks providing a + * ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2) decoded from + * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}. + * The value of this extra will be a String. + */ + public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE = + "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE"; + + /** * Key for an extra set on {@code #getDownloadableSubscriptionMetadata} PendingIntent result * callbacks providing the downloadable subscription metadata. */ @@ -494,6 +550,259 @@ public class EuiccManager { @SystemApi public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; + /** + * List of OperationCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}'s + * value, an integer. @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"OPERATION_"}, value = { + OPERATION_SYSTEM, + OPERATION_SIM_SLOT, + OPERATION_EUICC_CARD, + OPERATION_SWITCH, + OPERATION_DOWNLOAD, + OPERATION_METADATA, + OPERATION_EUICC_GSMA, + OPERATION_APDU, + OPERATION_SMDX, + OPERATION_HTTP, + OPERATION_SMDX_SUBJECT_REASON_CODE, + }) + public @interface OperationCode { + } + + /** + * Internal system error. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_SYSTEM = 1; + + /** + * SIM slot error. Failed to switch slot, failed to access the physical slot etc. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_SIM_SLOT = 2; + + /** + * eUICC card error. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_EUICC_CARD = 3; + + /** + * Generic switching profile error + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_SWITCH = 4; + + /** + * Download profile error. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_DOWNLOAD = 5; + + /** + * Subscription's metadata error + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_METADATA = 6; + + /** + * eUICC returned an error defined in GSMA (SGP.22 v2.2) while running one of the ES10x + * functions. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_EUICC_GSMA = 7; + + /** + * The exception of failing to execute an APDU command. It can be caused by an error + * happening on opening the basic or logical channel, or the response of the APDU command is + * not success (0x9000). + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_APDU = 8; + + /** + * SMDX(SMDP/SMDS) error + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_SMDX = 9; + + /** + * SubjectCode[5.2.6.1] and ReasonCode[5.2.6.2] error from GSMA (SGP.22 v2.2) + * When {@link #OPERATION_SMDX_SUBJECT_REASON_CODE} is used as the + * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}, the remaining three bytes of the integer + * result from {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be used to stored the + * SubjectCode and ReasonCode from the GSMA spec and NOT ErrorCode. + * + * The encoding will follow the format of: + * 1. The first byte of the result will be 255(0xFF). + * 2. Remaining three bytes(24 bits) will be split into six sections, 4 bits in each section. + * 3. A SubjectCode/ReasonCode will take 12 bits each. + * 4. The maximum number can be represented per section is 15, as that is the maximum number + * allowed to be stored into 4 bits + * 5. Maximum supported nested category from GSMA is three layers. E.g 8.11.1.2 is not + * supported. + * + * E.g given SubjectCode(8.11.1) and ReasonCode(5.1) + * + * Base10: 0 10 8 11 1 0 5 1 + * Base2: 0000 1010 1000 1011 0001 0000 0101 0001 + * Base16: 0 A 8 B 1 0 5 1 + * + * Thus the integer stored in {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} is + * 0xA8B1051(176885841) + * + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_SMDX_SUBJECT_REASON_CODE = 10; + + /** + * HTTP error + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int OPERATION_HTTP = 11; + + /** + * List of ErrorCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"ERROR_"}, value = { + ERROR_CARRIER_LOCKED, + ERROR_INVALID_ACTIVATION_CODE, + ERROR_INVALID_CONFIRMATION_CODE, + ERROR_INCOMPATIBLE_CARRIER, + ERROR_EUICC_INSUFFICIENT_MEMORY, + ERROR_TIME_OUT, + ERROR_EUICC_MISSING, + ERROR_UNSUPPORTED_VERSION, + ERROR_SIM_MISSING, + ERROR_INSTALL_PROFILE, + ERROR_DISALLOWED_BY_PPR, + ERROR_ADDRESS_MISSING, + ERROR_CERTIFICATE_ERROR, + ERROR_NO_PROFILES_AVAILABLE, + ERROR_CONNECTION_ERROR, + ERROR_INVALID_RESPONSE, + ERROR_OPERATION_BUSY, + }) + public @interface ErrorCode{} + + /** + * Operation such as downloading/switching to another profile failed due to device being + * carrier locked. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_CARRIER_LOCKED = 10000; + + /** + * The activation code(SGP.22 v2.2 section[4.1]) is invalid. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_INVALID_ACTIVATION_CODE = 10001; + + /** + * The confirmation code(SGP.22 v2.2 section[4.7]) is invalid. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_INVALID_CONFIRMATION_CODE = 10002; + + /** + * The profile's carrier is incompatible with the LPA. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_INCOMPATIBLE_CARRIER = 10003; + + /** + * There is no more space available on the eUICC for new profiles. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_EUICC_INSUFFICIENT_MEMORY = 10004; + + /** + * Timed out while waiting for an operation to complete. i.e restart, disable, + * switch reset etc. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_TIME_OUT = 10005; + + /** + * eUICC is missing or defective on the device. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_EUICC_MISSING = 10006; + + /** + * The eUICC card(hardware) version is incompatible with the software + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_UNSUPPORTED_VERSION = 10007; + + /** + * No SIM card is available in the device. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_SIM_MISSING = 10008; + + /** + * Failure to load the profile onto the eUICC card. e.g + * 1. iccid of the profile already exists on the eUICC. + * 2. GSMA(.22 v2.2) Profile Install Result - installFailedDueToDataMismatch + * 3. operation was interrupted + * 4. SIMalliance error in PEStatus(SGP.22 v2.2 section 2.5.6.1) + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_INSTALL_PROFILE = 10009; + + /** + * Failed to load profile onto eUICC due to Profile Poicly Rules. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_DISALLOWED_BY_PPR = 10010; + + + /** + * Address is missing e.g SMDS/SMDP address is missing. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_ADDRESS_MISSING = 10011; + + /** + * Certificate needed for authentication is not valid or missing. E.g SMDP/SMDS authentication + * failed. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_CERTIFICATE_ERROR = 10012; + + + /** + * No profiles available. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_NO_PROFILES_AVAILABLE = 10013; + + /** + * Failure to create a connection. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_CONNECTION_ERROR = 10014; + + /** + * Response format is invalid. e.g SMDP/SMDS response contains invalid json, header or/and ASN1. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_INVALID_RESPONSE = 10015; + + /** + * The operation is currently busy, try again later. + * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details + */ + public static final int ERROR_OPERATION_BUSY = 10016; + private final Context mContext; private int mCardId; diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index a7d553b60abf..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; @@ -182,6 +181,25 @@ public final class ImsCallProfile implements Parcelable { * {@link ImsCallProfile#DIALSTRING_USSD} */ public static final String EXTRA_DIALSTRING = "dialstring"; + /** + * This extra holds call fail cause because of which redial is attempted. + * see {@link android.telephony.ims.ImsReasonInfo} {@code CODE_*} + * for possible values this extra can hold. + * + * @hide + */ + public static final String EXTRA_RETRY_CALL_FAIL_REASON = + "android.telephony.ims.extra.RETRY_CALL_FAIL_REASON"; + /** + * This extra holds call network type on which lower layers + * may try attempting redial. + * See {@link TelephonyManager} {@code NETWORK_TYPE_*} + * for possible values this extra can hold. + * + * @hide + */ + public static final String EXTRA_RETRY_CALL_FAIL_NETWORKTYPE = + "android.telephony.ims.extra.RETRY_CALL_FAIL_NETWORKTYPE"; /** * Values for EXTRA_OIR / EXTRA_CNAP @@ -702,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 6974420dbaf4..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"; @@ -139,7 +136,7 @@ public class RcsUceAdapter { * UCE. * @hide */ - public static final int PUBLISH_STATE_200_OK = 1; + public static final int PUBLISH_STATE_OK = 1; /** * The hasn't published its capabilities since boot or hasn't gotten any publish response yet. @@ -179,7 +176,7 @@ public class RcsUceAdapter { /**@hide*/ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "PUBLISH_STATE_", value = { - PUBLISH_STATE_200_OK, + PUBLISH_STATE_OK, PUBLISH_STATE_NOT_PUBLISHED, PUBLISH_STATE_VOLTE_PROVISION_ERROR, PUBLISH_STATE_RCS_PROVISION_ERROR, @@ -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", @@ -303,7 +303,7 @@ public class RcsUceAdapter { * Gets the last publish result from the UCE service if the device is using an RCS presence * server. * @return The last publish result from the UCE service. If the device is using SIP OPTIONS, - * this method will return {@link #PUBLISH_STATE_200_OK} as well. + * this method will return {@link #PUBLISH_STATE_OK} as well. * @throws ImsException if the subscription associated with this instance of * {@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 @@ -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/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl index c07a1711b32e..88da3c94748b 100644 --- a/telephony/java/com/android/internal/telephony/ISms.aidl +++ b/telephony/java/com/android/internal/telephony/ISms.aidl @@ -86,37 +86,9 @@ interface ISms { * raw pdu of the status report is in the extended data ("pdu"). * @param subId the subId id. */ - void sendDataForSubscriber(int subId, String callingPkg, in String destAddr, - in String scAddr, in int destPort, in byte[] data, in PendingIntent sentIntent, - in PendingIntent deliveryIntent); - - /** - * Send a data SMS. Only for use internally. - * - * @param smsc the SMSC to send the message through, or NULL for the - * default SMSC - * @param data the body of the message to send - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is sucessfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applicaitons, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - * @param subId the subId id. - */ - void sendDataForSubscriberWithSelfPermissions(int subId, String callingPkg, in String destAddr, - in String scAddr, in int destPort, in byte[] data, in PendingIntent sentIntent, - in PendingIntent deliveryIntent); + void sendDataForSubscriber(int subId, String callingPkg, String callingattributionTag, + in String destAddr, in String scAddr, in int destPort,in byte[] data, + in PendingIntent sentIntent, in PendingIntent deliveryIntent); /** * Send an SMS. @@ -146,37 +118,9 @@ interface ISms { * by a non-default SMS app. Currently only the carrier app can set this * parameter to false to skip auto message persistence. */ - void sendTextForSubscriber(in int subId, String callingPkg, in String destAddr, - in String scAddr, in String text, in PendingIntent sentIntent, - in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp); - - /** - * Send an SMS. Internal use only. - * - * @param smsc the SMSC to send the message through, or NULL for the - * default SMSC - * @param text the body of the message to send - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is sucessfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - * @param subId the subId on which the SMS has to be sent. - */ - void sendTextForSubscriberWithSelfPermissions(in int subId, String callingPkg, + void sendTextForSubscriber(in int subId, String callingPkg, String callingAttributionTag, in String destAddr, in String scAddr, in String text, in PendingIntent sentIntent, - in PendingIntent deliveryIntent, in boolean persistMessage); + in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp); /** * Send an SMS with options using Subscription Id. @@ -224,10 +168,11 @@ interface ISms { * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). * Any Other values included Negative considered as Invalid Validity Period of the message. */ - void sendTextForSubscriberWithOptions(in int subId, String callingPkg, in String destAddr, - in String scAddr, in String text, in PendingIntent sentIntent, - in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp, - in int priority, in boolean expectMore, in int validityPeriod); + void sendTextForSubscriberWithOptions(in int subId, String callingPkg, + String callingAttributionTag, in String destAddr, in String scAddr, in String text, + in PendingIntent sentIntent, in PendingIntent deliveryIntent, + in boolean persistMessageForNonDefaultSmsApp, in int priority, in boolean expectMore, + in int validityPeriod); /** * Inject an SMS PDU into the android platform. @@ -272,7 +217,7 @@ interface ISms { * parameter to false to skip auto message persistence. */ void sendMultipartTextForSubscriber(in int subId, String callingPkg, - in String destinationAddress, in String scAddress, + String callingAttributionTag, in String destinationAddress, in String scAddress, in List<String> parts, in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp); @@ -321,10 +266,10 @@ interface ISms { * Any Other values included Negative considered as Invalid Validity Period of the message. */ void sendMultipartTextForSubscriberWithOptions(in int subId, String callingPkg, - in String destinationAddress, in String scAddress, in List<String> parts, - in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents, - in boolean persistMessageForNonDefaultSmsApp, in int priority, in boolean expectMore, - in int validityPeriod); + String callingAttributionTag, in String destinationAddress, in String scAddress, + in List<String> parts, in List<PendingIntent> sentIntents, + in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp, + in int priority, in boolean expectMore, in int validityPeriod); /** * Enable reception of cell broadcast (SMS-CB) messages with the given @@ -482,6 +427,7 @@ interface ISms { * * @param subId the SIM id. * @param callingPkg the package name of the calling app + * @param callingAttributionTag the attribution tag of calling context * @param messageUri the URI of the stored message * @param scAddress is the service center address or null to use the current default SMSC * @param sentIntent if not NULL this <code>PendingIntent</code> is @@ -501,8 +447,9 @@ interface ISms { * broadcast when the message is delivered to the recipient. The * raw pdu of the status report is in the extended data ("pdu"). */ - void sendStoredText(int subId, String callingPkg, in Uri messageUri, String scAddress, - in PendingIntent sentIntent, in PendingIntent deliveryIntent); + void sendStoredText(int subId, String callingPkg, String callingAttributionTag, + in Uri messageUri, String scAddress, in PendingIntent sentIntent, + in PendingIntent deliveryIntent); /** * Send a system stored multi-part text message. @@ -514,6 +461,7 @@ interface ISms { * * @param subId the SIM id. * @param callingPkg the package name of the calling app + * @param callingAttributeTag the attribute tag of the calling context * @param messageUri the URI of the stored message * @param scAddress is the service center address or null to use * the current default SMSC @@ -537,8 +485,8 @@ interface ISms { * to the recipient. The raw pdu of the status report is in the * extended data ("pdu"). */ - void sendStoredMultipartText(int subId, String callingPkg, in Uri messageUri, - String scAddress, in List<PendingIntent> sentIntents, + void sendStoredMultipartText(int subId, String callingPkg, String callingAttributeTag, + in Uri messageUri, String scAddress, in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents); /** diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java index ddd3457b3b4d..51af6de78627 100644 --- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java +++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java @@ -45,38 +45,25 @@ public class ISmsImplBase extends ISms.Stub { } @Override - public void sendDataForSubscriber(int subId, String callingPkg, String destAddr, - String scAddr, int destPort, byte[] data, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - throw new UnsupportedOperationException(); - } - - @Override - public void sendDataForSubscriberWithSelfPermissions(int subId, String callingPkg, + public void sendDataForSubscriber(int subId, String callingPkg, String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { throw new UnsupportedOperationException(); } @Override - public void sendTextForSubscriber(int subId, String callingPkg, String destAddr, - String scAddr, String text, PendingIntent sentIntent, - PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp) { - throw new UnsupportedOperationException(); - } - - @Override - public void sendTextForSubscriberWithSelfPermissions(int subId, String callingPkg, + public void sendTextForSubscriber(int subId, String callingPkg, String callingAttributionTag, String destAddr, String scAddr, String text, PendingIntent sentIntent, - PendingIntent deliveryIntent, boolean persistMessage) { + PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp) { throw new UnsupportedOperationException(); } @Override - public void sendTextForSubscriberWithOptions(int subId, String callingPkg, String destAddr, - String scAddr, String text, PendingIntent sentIntent, - PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, - int priority, boolean expectMore, int validityPeriod) { + public void sendTextForSubscriberWithOptions(int subId, String callingPkg, + String callingAttributionTag, String destAddr, String scAddr, String text, + PendingIntent sentIntent, PendingIntent deliveryIntent, + boolean persistMessageForNonDefaultSmsApp, int priority, boolean expectMore, + int validityPeriod) { throw new UnsupportedOperationException(); } @@ -88,7 +75,7 @@ public class ISmsImplBase extends ISms.Stub { @Override public void sendMultipartTextForSubscriber(int subId, String callingPkg, - String destinationAddress, String scAddress, + String callingAttributionTag, String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp) { throw new UnsupportedOperationException(); @@ -96,7 +83,7 @@ public class ISmsImplBase extends ISms.Stub { @Override public void sendMultipartTextForSubscriberWithOptions(int subId, String callingPkg, - String destinationAddress, String scAddress, + String callingAttributionTag, String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp, int priority, boolean expectMore, int validityPeriod) { @@ -173,14 +160,15 @@ public class ISmsImplBase extends ISms.Stub { } @Override - public void sendStoredText(int subId, String callingPkg, Uri messageUri, String scAddress, - PendingIntent sentIntent, PendingIntent deliveryIntent) { + public void sendStoredText(int subId, String callingPkg, String callingAttributionTag, + Uri messageUri, String scAddress, PendingIntent sentIntent, + PendingIntent deliveryIntent) { throw new UnsupportedOperationException(); } @Override - public void sendStoredMultipartText(int subId, String callingPkg, Uri messageUri, - String scAddress, List<PendingIntent> sentIntents, + public void sendStoredMultipartText(int subId, String callingPkg, String callingAttributionTag, + Uri messageUri, String scAddress, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { throw new UnsupportedOperationException(); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 123096c3e741..1face6c4f4cd 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -22,6 +22,7 @@ import android.content.IntentSender; import android.os.Bundle; import android.os.IBinder; import android.os.Messenger; +import android.os.ParcelFileDescriptor; import android.os.ResultReceiver; import android.os.WorkSource; import android.net.NetworkStats; @@ -281,7 +282,7 @@ interface ITelephony { * operator's MCC (Mobile Country Code). * @see android.telephony.TelephonyManager#getNetworkCountryIso */ - String getNetworkCountryIsoForPhone(int phoneId, String callingPkg, String callingFeatureId); + String getNetworkCountryIsoForPhone(int phoneId); /** * Returns the neighboring cell information of the device. @@ -472,8 +473,8 @@ interface ITelephony { * Send a visual voicemail SMS. Internal use only. * Requires caller to be the default dialer and have SEND_SMS permission */ - void sendVisualVoicemailSmsForSubscriber(in String callingPackage, in int subId, - in String number, in int port, in String text, in PendingIntent sentIntent); + void sendVisualVoicemailSmsForSubscriber(in String callingPackage, String callingAttributeTag, + in int subId, in String number, in int port, in String text, in PendingIntent sentIntent); // Send the special dialer code. The IPC caller must be the current default dialer. void sendDialerSpecialCode(String callingPackageName, String inputCode); @@ -2121,9 +2122,14 @@ interface ITelephony { void notifyOtaEmergencyNumberDbInstalled(); /** - * Override the file partition name for testing OTA emergency number database. + * Override a customized file partition name for OTA emergency number database. */ - void updateTestOtaEmergencyNumberDbFilePath(String otaFilePath); + void updateOtaEmergencyNumberDbFilePath(in ParcelFileDescriptor otaParcelFileDescriptor); + + /** + * Reset file partition to default for OTA emergency number database. + */ + void resetOtaEmergencyNumberDbFilePath(); /** * Enable or disable a logical modem stack associated with the slotIndex. @@ -2198,7 +2204,8 @@ interface ITelephony { * Enqueue a pending sms Consumer, which will answer with the user specified selection for an * outgoing SmsManager operation. */ - oneway void enqueueSmsPickResult(String callingPackage, IIntegerConsumer subIdResult); + oneway void enqueueSmsPickResult(String callingPackage, String callingAttributeTag, + IIntegerConsumer subIdResult); /** * Returns the MMS user agent. diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 53ad70a07563..6fdc13e6a31b 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -492,6 +492,7 @@ public interface RILConstants { int RIL_REQUEST_ENABLE_UICC_APPLICATIONS = 208; int RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT = 209; int RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS = 210; + int RIL_REQUEST_GET_BARRING_INFO = 211; /* Responses begin */ int RIL_RESPONSE_ACKNOWLEDGEMENT = 800; @@ -557,4 +558,5 @@ public interface RILConstants { int RIL_UNSOL_EMERGENCY_NUMBER_LIST = 1102; int RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED = 1103; int RIL_UNSOL_REGISTRATION_FAILED = 1104; + int RIL_UNSOL_BARRING_INFO_CHANGED = 1105; } diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java index 95b8f6700c76..8b182b7f8780 100644 --- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java +++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java @@ -71,6 +71,7 @@ public class AppLaunch extends InstrumentationTestCase { // with the app launch private static final String KEY_REQUIRED_ACCOUNTS = "required_accounts"; private static final String KEY_APPS = "apps"; + private static final String KEY_IORAP_TRIAL_LAUNCH = "iorap_trial_launch"; private static final String KEY_TRIAL_LAUNCH = "trial_launch"; private static final String KEY_LAUNCH_ITERATIONS = "launch_iterations"; private static final String KEY_LAUNCH_ORDER = "launch_order"; @@ -98,6 +99,9 @@ public class AppLaunch extends InstrumentationTestCase { private static final int BEFORE_KILL_APP_SLEEP_TIMEOUT = 1000; // 1s before killing private static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 3000; // 3s between launching apps private static final int PROFILE_SAVE_SLEEP_TIMEOUT = 1000; // Allow 1s for the profile to save + private static final int IORAP_TRACE_DURATION_TIMEOUT = 7000; // Allow 7s for trace to complete. + private static final int IORAP_TRIAL_LAUNCH_ITERATIONS = 3; // min 3 launches to merge traces. + private static final int IORAP_COMPILE_CMD_TIMEOUT = 600; // in seconds: 10 minutes private static final String LAUNCH_SUB_DIRECTORY = "launch_logs"; private static final String LAUNCH_FILE = "applaunch.txt"; private static final String TRACE_SUB_DIRECTORY = "atrace_logs"; @@ -106,6 +110,9 @@ public class AppLaunch extends InstrumentationTestCase { private static final String DEFAULT_TRACE_BUFFER_SIZE = "20000"; private static final String DEFAULT_TRACE_DUMP_INTERVAL = "10"; private static final String TRIAL_LAUNCH = "TRIAL_LAUNCH"; + private static final String IORAP_TRIAL_LAUNCH = "IORAP_TRIAL_LAUNCH"; + private static final String IORAP_TRIAL_LAUNCH_FIRST = "IORAP_TRIAL_LAUNCH_FIRST"; + private static final String IORAP_TRIAL_LAUNCH_LAST = "IORAP_TRIAL_LAUNCH_LAST"; private static final String DELIMITER = ","; private static final String DROP_CACHE_SCRIPT = "/data/local/tmp/dropCache.sh"; private static final String APP_LAUNCH_CMD = "am start -W -n"; @@ -119,6 +126,10 @@ public class AppLaunch extends InstrumentationTestCase { private static final String LAUNCH_ORDER_CYCLIC = "cyclic"; private static final String LAUNCH_ORDER_SEQUENTIAL = "sequential"; private static final String COMPILE_CMD = "cmd package compile -f -m %s %s"; + private static final String IORAP_COMPILE_CMD = "cmd jobscheduler run -f android 283673059"; + private static final String IORAP_MAINTENANCE_CMD = + "iorap.cmd.maintenance --purge-package %s /data/misc/iorapd/sqlite.db"; + private static final String IORAP_DUMPSYS_CMD = "dumpsys iorapd"; private static final String SPEED_PROFILE_FILTER = "speed-profile"; private static final String VERIFY_FILTER = "verify"; private static final String LAUNCH_SCRIPT_NAME = "appLaunch"; @@ -138,6 +149,7 @@ public class AppLaunch extends InstrumentationTestCase { private Bundle mResult = new Bundle(); private Set<String> mRequiredAccounts; private boolean mTrialLaunch = false; + private boolean mIorapTrialLaunch = false; private BufferedWriter mBufferedWriter = null; private boolean mSimplePerfAppOnly = false; private String[] mCompilerFilters = null; @@ -145,6 +157,13 @@ public class AppLaunch extends InstrumentationTestCase { private boolean mCycleCleanUp = false; private boolean mTraceAll = false; private boolean mIterationCycle = false; + + enum IorapStatus { + UNDEFINED, + ENABLED, + DISABLED + } + private IorapStatus mIorapStatus = IorapStatus.UNDEFINED; private long mCycleTime = 0; private StringBuilder mCycleTimes = new StringBuilder(); @@ -243,7 +262,10 @@ public class AppLaunch extends InstrumentationTestCase { setLaunchOrder(); for (LaunchOrder launch : mLaunchOrderList) { - dropCache(); + toggleIorapStatus(launch.getIorapEnabled()); + dropCache(/*override*/false); + + Log.v(TAG, "Launch reason: " + launch.getLaunchReason()); // App launch times for trial launch will not be used for final // launch time calculations. @@ -289,6 +311,43 @@ public class AppLaunch extends InstrumentationTestCase { compileApp(launch.getCompilerFilter(), appPkgName)); } } + else if (launch.getLaunchReason().startsWith(IORAP_TRIAL_LAUNCH)) { + mIterationCycle = false; + + // In the "applaunch.txt" file, iorap-trial launches is referenced using + // "IORAP_TRIAL_LAUNCH" or "IORAP_TRIAL_LAUNCH_LAST" + Intent startIntent = mNameToIntent.get(launch.getApp()); + if (startIntent == null) { + Log.w(TAG, "App does not exist: " + launch.getApp()); + mResult.putString(mNameToResultKey.get(launch.getApp()), + "App does not exist"); + continue; + } + String appPkgName = startIntent.getComponent().getPackageName(); + + if (launch.getLaunchReason().equals(IORAP_TRIAL_LAUNCH_FIRST)) { + // delete any iorap-traces associated with this package. + purgeIorapPackage(appPkgName); + } + dropCache(/*override*/true); // iorap-trial runs must have drop cache. + + AppLaunchResult launchResult = + startApp(launch.getApp(), launch.getLaunchReason()); + if (launchResult.mLaunchTime < 0) { + addLaunchResult(launch, new AppLaunchResult()); + // simply pass the app if launch isn't successful + // error should have already been logged by startApp + continue; + } + // wait for slightly more than 5s (iorapd.perfetto.trace_duration_ms) for the trace buffers to complete. + sleep(IORAP_TRACE_DURATION_TIMEOUT); + + if (launch.getLaunchReason().equals(IORAP_TRIAL_LAUNCH_LAST)) { + // run the iorap job scheduler and wait for iorap to compile fully. + assertTrue(String.format("Not able to iorap-compile the app : %s", appPkgName), + compileAppForIorap(appPkgName)); + } + } // App launch times used for final calculation else if (launch.getLaunchReason().contains(LAUNCH_ITERATION_PREFIX)) { @@ -438,6 +497,74 @@ public class AppLaunch extends InstrumentationTestCase { } /** + * Compile the app package using compilerFilter and return true or false + * based on status of the compilation command. + */ + private boolean compileAppForIorap(String appPkgName) throws IOException { + getInstrumentation().getUiAutomation(). + executeShellCommand(IORAP_COMPILE_CMD); + + for (int i = 0; i < IORAP_COMPILE_CMD_TIMEOUT; ++i) { + IorapCompilationStatus status = waitForIorapCompiled(appPkgName); + if (status == IorapCompilationStatus.COMPLETE) { + return true; + } else if (status == IorapCompilationStatus.INSUFFICIENT_TRACES) { + return false; + } // else INCOMPLETE. keep asking iorapd if it's done yet. + sleep(1000); + } + + return false; + } + + enum IorapCompilationStatus { + INCOMPLETE, + COMPLETE, + INSUFFICIENT_TRACES, + } + private IorapCompilationStatus waitForIorapCompiled(String appPkgName) throws IOException { + try (ParcelFileDescriptor result = getInstrumentation().getUiAutomation(). + executeShellCommand(IORAP_DUMPSYS_CMD); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( + new FileInputStream(result.getFileDescriptor())))) { + String line; + String prevLine = ""; + while ((line = bufferedReader.readLine()) != null) { + // Match the indented VersionedComponentName string. + // " com.google.android.deskclock/com.android.deskclock.DeskClock@62000712" + // Note: spaces are meaningful here. + if (prevLine.contains(" " + appPkgName) && prevLine.contains("@")) { + // pre-requisite: + // Compiled Status: Raw traces pending compilation (3) + if (line.contains("Compiled Status: Usable compiled trace")) { + return IorapCompilationStatus.COMPLETE; + } else if (line.contains("Compiled Status: ") && + line.contains("more traces for compilation")) { + // Compiled Status: Need 1 more traces for compilation + // No amount of waiting will help here because there were + // insufficient traces made. + return IorapCompilationStatus.INSUFFICIENT_TRACES; + } + } + + prevLine = line; + } + return IorapCompilationStatus.INCOMPLETE; + } + } + + private String makeReasonForIorapTrialLaunch(int launchCount) { + String reason = IORAP_TRIAL_LAUNCH; + if (launchCount == 0) { + reason = IORAP_TRIAL_LAUNCH_FIRST; + } + if (launchCount == IORAP_TRIAL_LAUNCH_ITERATIONS - 1) { + reason = IORAP_TRIAL_LAUNCH_LAST; + } + return reason; + } + + /** * If launch order is "cyclic" then apps will be launched one after the * other for each iteration count. * If launch order is "sequential" then each app will be launched for given number @@ -448,20 +575,31 @@ public class AppLaunch extends InstrumentationTestCase { for (String compilerFilter : mCompilerFilters) { if (mTrialLaunch) { for (String app : mNameToResultKey.keySet()) { - mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH)); + mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH, /*iorapEnabled*/false)); + } + } + if (mIorapTrialLaunch) { + for (int launchCount = 0; launchCount < IORAP_TRIAL_LAUNCH_ITERATIONS; ++launchCount) { + for (String app : mNameToResultKey.keySet()) { + String reason = makeReasonForIorapTrialLaunch(launchCount); + mLaunchOrderList.add( + new LaunchOrder(app, compilerFilter, + reason, + /*iorapEnabled*/true)); + } } } for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) { for (String app : mNameToResultKey.keySet()) { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, - String.format(LAUNCH_ITERATION, launchCount))); + String.format(LAUNCH_ITERATION, launchCount), mIorapTrialLaunch)); } } if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) { for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) { for (String app : mNameToResultKey.keySet()) { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, - String.format(TRACE_ITERATION, traceCount))); + String.format(TRACE_ITERATION, traceCount), mIorapTrialLaunch)); } } } @@ -470,16 +608,25 @@ public class AppLaunch extends InstrumentationTestCase { for (String compilerFilter : mCompilerFilters) { for (String app : mNameToResultKey.keySet()) { if (mTrialLaunch) { - mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH)); + mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH, /*iorapEnabled*/false)); + } + if (mIorapTrialLaunch) { + for (int launchCount = 0; launchCount < IORAP_TRIAL_LAUNCH_ITERATIONS; ++launchCount) { + String reason = makeReasonForIorapTrialLaunch(launchCount); + mLaunchOrderList.add( + new LaunchOrder(app, compilerFilter, + reason, + /*iorapEnabled*/true)); + } } for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, - String.format(LAUNCH_ITERATION, launchCount))); + String.format(LAUNCH_ITERATION, launchCount), mIorapTrialLaunch)); } if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) { for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, - String.format(TRACE_ITERATION, traceCount))); + String.format(TRACE_ITERATION, traceCount), mIorapTrialLaunch)); } } } @@ -489,14 +636,92 @@ public class AppLaunch extends InstrumentationTestCase { } } - private void dropCache() { - if (mDropCache) { + private void dropCache(boolean override) { + if (mDropCache || override) { assertNotNull("Issue in dropping the cache", getInstrumentation().getUiAutomation() .executeShellCommand(DROP_CACHE_SCRIPT)); } } + // [[ $(adb shell whoami) == "root" ]] + private boolean checkIfRoot() throws IOException { + String total = ""; + try (ParcelFileDescriptor result = getInstrumentation().getUiAutomation(). + executeShellCommand("whoami"); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( + new FileInputStream(result.getFileDescriptor())))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + total = total + line; + } + } + return total.contains("root"); + } + + // Delete all db rows and files associated with a package in iorapd. + // Effectively deletes any raw or compiled trace files, unoptimizing the package in iorap. + private void purgeIorapPackage(String packageName) { + try { + if (!checkIfRoot()) { + throw new AssertionError("must be root to toggle iorapd; try adb root?"); + } + } catch (IOException e) { + throw new AssertionError(e); + } + + getInstrumentation().getUiAutomation() + .executeShellCommand("stop iorapd"); + sleep(100); // give iorapd enough time to stop. + getInstrumentation().getUiAutomation() + .executeShellCommand(String.format(IORAP_MAINTENANCE_CMD, packageName)); + Log.v(TAG, "Executed: " + String.format(IORAP_MAINTENANCE_CMD, packageName)); + getInstrumentation().getUiAutomation() + .executeShellCommand("start iorapd"); + sleep(2000); // give iorapd enough time to start up. + } + + /** + * Toggle iorapd-based readahead and trace-collection. + * If iorapd is already enabled and enable is true, does nothing. + * If iorapd is already disabled and enable is false, does nothing. + */ + private void toggleIorapStatus(boolean enable) { + boolean currentlyEnabled = false; + Log.v(TAG, "toggleIorapStatus " + Boolean.toString(enable)); + + // Do nothing if we are already enabled or disabled. + if (mIorapStatus == IorapStatus.ENABLED && enable) { + return; + } else if (mIorapStatus == IorapStatus.DISABLED && !enable) { + return; + } + + try { + if (!checkIfRoot()) { + throw new AssertionError("must be root to toggle iorapd; try adb root?"); + } + } catch (IOException e) { + throw new AssertionError(e); + } + + getInstrumentation().getUiAutomation() + .executeShellCommand("stop iorapd"); + getInstrumentation().getUiAutomation() + .executeShellCommand(String.format("setprop iorapd.perfetto.enable %b", enable)); + getInstrumentation().getUiAutomation() + .executeShellCommand(String.format("setprop iorapd.readahead.enable %b", enable)); + getInstrumentation().getUiAutomation() + .executeShellCommand("start iorapd"); + sleep(2000); // give enough time for iorapd to start back up. + + if (enable) { + mIorapStatus = IorapStatus.ENABLED; + } else { + mIorapStatus = IorapStatus.DISABLED; + } + } + private void parseArgs(Bundle args) { mNameToResultKey = new LinkedHashMap<String, String>(); mNameToLaunchTime = new HashMap<>(); @@ -560,6 +785,8 @@ public class AppLaunch extends InstrumentationTestCase { mCycleCleanUp = Boolean.parseBoolean(args.getString(KEY_CYCLE_CLEAN)); mTraceAll = Boolean.parseBoolean(args.getString(KEY_TRACE_ALL)); mTrialLaunch = mTrialLaunch || Boolean.parseBoolean(args.getString(KEY_TRIAL_LAUNCH)); + mIorapTrialLaunch = mIorapTrialLaunch || + Boolean.parseBoolean(args.getString(KEY_IORAP_TRIAL_LAUNCH)); if (mSimplePerfCmd != null && mSimplePerfAppOnly) { Log.w(TAG, String.format("Passing both %s and %s is not supported, ignoring %s", @@ -738,11 +965,13 @@ public class AppLaunch extends InstrumentationTestCase { private String mApp; private String mCompilerFilter; private String mLaunchReason; + private boolean mIorapEnabled; - LaunchOrder(String app, String compilerFilter, String launchReason){ + LaunchOrder(String app, String compilerFilter, String launchReason, boolean iorapEnabled) { mApp = app; mCompilerFilter = compilerFilter; mLaunchReason = launchReason; + mIorapEnabled = iorapEnabled; } public String getApp() { @@ -764,6 +993,14 @@ public class AppLaunch extends InstrumentationTestCase { public void setLaunchReason(String launchReason) { mLaunchReason = launchReason; } + + public void setIorapEnabled(boolean iorapEnabled) { + mIorapEnabled = iorapEnabled; + } + + public boolean getIorapEnabled() { + return mIorapEnabled; + } } private class AppLaunchResult { diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml index 480b12be91c8..009f817af407 100644 --- a/tests/net/AndroidManifest.xml +++ b/tests/net/AndroidManifest.xml @@ -47,6 +47,7 @@ <uses-permission android:name="android.permission.NETWORK_STACK" /> <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" /> <uses-permission android:name="android.permission.NETWORK_FACTORY" /> + <uses-permission android:name="android.permission.NETWORK_STATS_PROVIDER" /> <application> <uses-library android:name="android.test.runner" /> diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp index e44d46088c43..46d680fc4511 100644 --- a/tests/net/common/Android.bp +++ b/tests/net/common/Android.bp @@ -20,6 +20,7 @@ java_library { name: "FrameworksNetCommonTests", srcs: ["java/**/*.java", "java/**/*.kt"], static_libs: [ + "androidx.core_core", "androidx.test.rules", "junit", "mockito-target-minus-junit4", diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java index 48b65e592f39..8de27e8eb281 100644 --- a/tests/net/common/java/android/net/LinkPropertiesTest.java +++ b/tests/net/common/java/android/net/LinkPropertiesTest.java @@ -29,12 +29,19 @@ import static org.junit.Assert.fail; import android.net.LinkProperties.ProvisioningChange; import android.net.util.LinkPropertiesUtils.CompareResult; +import android.os.Build; import android.system.OsConstants; import android.util.ArraySet; +import androidx.core.os.BuildCompat; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.testutils.DevSdkIgnoreRule; +import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; + +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,6 +57,9 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) @SmallTest public class LinkPropertiesTest { + @Rule + public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); + private static final InetAddress ADDRV4 = address("75.208.6.1"); private static final InetAddress ADDRV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); private static final InetAddress DNS1 = address("75.208.7.1"); @@ -76,13 +86,23 @@ public class LinkPropertiesTest { private static final LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128); private static final LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64"); private static final Uri CAPPORT_API_URL = Uri.parse("https://test.example.com/capportapi"); - private static final CaptivePortalData CAPPORT_DATA = new CaptivePortalData.Builder() - .setVenueInfoUrl(Uri.parse("https://test.example.com/venue")).build(); + + // CaptivePortalData cannot be in a constant as it does not exist on Q. + // The test runner also crashes when scanning for tests if it is a return type. + private static Object getCaptivePortalData() { + return new CaptivePortalData.Builder() + .setVenueInfoUrl(Uri.parse("https://test.example.com/venue")).build(); + } private static InetAddress address(String addrString) { return InetAddresses.parseNumericAddress(addrString); } + private static boolean isAtLeastR() { + // BuildCompat.isAtLeastR is documented to return false on release SDKs (including R) + return Build.VERSION.SDK_INT > Build.VERSION_CODES.Q || BuildCompat.isAtLeastR(); + } + private void checkEmpty(final LinkProperties lp) { assertEquals(0, lp.getAllInterfaceNames().size()); assertEquals(0, lp.getAllAddresses().size()); @@ -98,14 +118,17 @@ public class LinkPropertiesTest { assertNull(lp.getHttpProxy()); assertNull(lp.getTcpBufferSizes()); assertNull(lp.getNat64Prefix()); - assertNull(lp.getDhcpServerAddress()); assertFalse(lp.isProvisioned()); assertFalse(lp.isIpv4Provisioned()); assertFalse(lp.isIpv6Provisioned()); assertFalse(lp.isPrivateDnsActive()); - assertFalse(lp.isWakeOnLanSupported()); - assertNull(lp.getCaptivePortalApiUrl()); - assertNull(lp.getCaptivePortalData()); + + if (isAtLeastR()) { + assertNull(lp.getDhcpServerAddress()); + assertFalse(lp.isWakeOnLanSupported()); + assertNull(lp.getCaptivePortalApiUrl()); + assertNull(lp.getCaptivePortalData()); + } } private LinkProperties makeTestObject() { @@ -127,10 +150,12 @@ public class LinkPropertiesTest { lp.setMtu(MTU); lp.setTcpBufferSizes(TCP_BUFFER_SIZES); lp.setNat64Prefix(new IpPrefix("2001:db8:0:64::/96")); - lp.setDhcpServerAddress(DHCPSERVER); - lp.setWakeOnLanSupported(true); - lp.setCaptivePortalApiUrl(CAPPORT_API_URL); - lp.setCaptivePortalData(CAPPORT_DATA); + if (isAtLeastR()) { + lp.setDhcpServerAddress(DHCPSERVER); + lp.setWakeOnLanSupported(true); + lp.setCaptivePortalApiUrl(CAPPORT_API_URL); + lp.setCaptivePortalData((CaptivePortalData) getCaptivePortalData()); + } return lp; } @@ -169,14 +194,19 @@ public class LinkPropertiesTest { assertTrue(source.isIdenticalTcpBufferSizes(target)); assertTrue(target.isIdenticalTcpBufferSizes(source)); - assertTrue(source.isIdenticalWakeOnLan(target)); - assertTrue(target.isIdenticalWakeOnLan(source)); + if (isAtLeastR()) { + assertTrue(source.isIdenticalDhcpServerAddress(target)); + assertTrue(source.isIdenticalDhcpServerAddress(source)); - assertTrue(source.isIdenticalCaptivePortalApiUrl(target)); - assertTrue(target.isIdenticalCaptivePortalApiUrl(source)); + assertTrue(source.isIdenticalWakeOnLan(target)); + assertTrue(target.isIdenticalWakeOnLan(source)); - assertTrue(source.isIdenticalCaptivePortalData(target)); - assertTrue(target.isIdenticalCaptivePortalData(source)); + assertTrue(source.isIdenticalCaptivePortalApiUrl(target)); + assertTrue(target.isIdenticalCaptivePortalApiUrl(source)); + + assertTrue(source.isIdenticalCaptivePortalData(target)); + assertTrue(target.isIdenticalCaptivePortalData(source)); + } // Check result of equals(). assertTrue(source.equals(target)); @@ -415,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)); @@ -450,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()); @@ -457,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()); @@ -464,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()); @@ -483,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")); } @@ -906,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), @@ -943,8 +989,7 @@ public class LinkPropertiesTest { assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed))); } - @Test - public void testLinkPropertiesParcelable() throws Exception { + private static LinkProperties makeLinkPropertiesForParceling() { LinkProperties source = new LinkProperties(); source.setInterfaceName(NAME); @@ -978,17 +1023,29 @@ public class LinkPropertiesTest { source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96")); - source.setWakeOnLanSupported(true); - source.setCaptivePortalApiUrl(CAPPORT_API_URL); - source.setCaptivePortalData(CAPPORT_DATA); - - source.setDhcpServerAddress((Inet4Address) GATEWAY1); - final LinkProperties stacked = new LinkProperties(); stacked.setInterfaceName("test-stacked"); source.addStackedLink(stacked); - assertParcelSane(source.makeSensitiveFieldsParcelingCopy(), 18 /* fieldCount */); + return source; + } + + @Test @IgnoreAfter(Build.VERSION_CODES.Q) + public void testLinkPropertiesParcelable_Q() throws Exception { + final LinkProperties source = makeLinkPropertiesForParceling(); + assertParcelSane(source, 14 /* fieldCount */); + } + + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testLinkPropertiesParcelable() throws Exception { + final LinkProperties source = makeLinkPropertiesForParceling(); + + source.setWakeOnLanSupported(true); + source.setCaptivePortalApiUrl(CAPPORT_API_URL); + source.setCaptivePortalData((CaptivePortalData) getCaptivePortalData()); + source.setDhcpServerAddress((Inet4Address) GATEWAY1); + assertParcelSane(new LinkProperties(source, true /* parcelSensitiveFields */), + 18 /* fieldCount */); // Verify that without using a sensitiveFieldsParcelingCopy, sensitive fields are cleared. final LinkProperties sanitized = new LinkProperties(source); @@ -997,7 +1054,8 @@ public class LinkPropertiesTest { assertEquals(sanitized, parcelingRoundTrip(source)); } - @Test + // Parceling of the scope was broken until Q-QPR2 + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) public void testLinkLocalDnsServerParceling() throws Exception { final String strAddress = "fe80::1%lo"; final LinkProperties lp = new LinkProperties(); @@ -1120,7 +1178,7 @@ public class LinkPropertiesTest { assertFalse(lp.isPrivateDnsActive()); } - @Test + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) public void testDhcpServerAddress() { final LinkProperties lp = makeTestObject(); assertEquals(DHCPSERVER, lp.getDhcpServerAddress()); @@ -1129,7 +1187,7 @@ public class LinkPropertiesTest { assertNull(lp.getDhcpServerAddress()); } - @Test + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) public void testWakeOnLanSupported() { final LinkProperties lp = makeTestObject(); assertTrue(lp.isWakeOnLanSupported()); @@ -1138,7 +1196,7 @@ public class LinkPropertiesTest { assertFalse(lp.isWakeOnLanSupported()); } - @Test + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) public void testCaptivePortalApiUrl() { final LinkProperties lp = makeTestObject(); assertEquals(CAPPORT_API_URL, lp.getCaptivePortalApiUrl()); @@ -1147,12 +1205,56 @@ public class LinkPropertiesTest { assertNull(lp.getCaptivePortalApiUrl()); } - @Test + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) public void testCaptivePortalData() { final LinkProperties lp = makeTestObject(); - assertEquals(CAPPORT_DATA, lp.getCaptivePortalData()); + assertEquals(getCaptivePortalData(), lp.getCaptivePortalData()); 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/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt index 173dbd1271f8..de65ba24972b 100644 --- a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt +++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt @@ -22,6 +22,9 @@ import androidx.test.runner.AndroidJUnit4 import com.android.testutils.DevSdkIgnoreRule import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo import com.android.testutils.assertParcelSane +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -43,4 +46,27 @@ class NetworkAgentConfigTest { }.build() assertParcelSane(config, 9) } + + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + fun testBuilder() { + val config = NetworkAgentConfig.Builder().apply { + setExplicitlySelected(true) + setLegacyType(ConnectivityManager.TYPE_ETHERNET) + setSubscriberId("MySubId") + setPartialConnectivityAcceptable(false) + setUnvalidatedConnectivityAcceptable(true) + setLegacyTypeName("TEST_NETWORK") + disableNat64Detection() + disableProvisioningNotification() + }.build() + + assertTrue(config.isExplicitlySelected()) + assertEquals(ConnectivityManager.TYPE_ETHERNET, config.getLegacyType()) + assertEquals("MySubId", config.getSubscriberId()) + assertFalse(config.isPartialConnectivityAcceptable()) + assertTrue(config.isUnvalidatedConnectivityAcceptable()) + assertEquals("TEST_NETWORK", config.getLegacyTypeName()) + assertFalse(config.isNat64DetectionEnabled()) + assertFalse(config.isProvisioningNotificationEnabled()) + } } diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java index efea91ab91f0..916c33981171 100644 --- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java +++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java @@ -48,9 +48,11 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.os.Build; import android.test.suitebuilder.annotation.SmallTest; import android.util.ArraySet; +import androidx.core.os.BuildCompat; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; @@ -64,6 +66,13 @@ public class NetworkCapabilitiesTest { private static final String TEST_SSID = "TEST_SSID"; private static final String DIFFERENT_TEST_SSID = "DIFFERENT_TEST_SSID"; + private boolean isAtLeastR() { + // BuildCompat.isAtLeastR() is used to check the Android version before releasing Android R. + // Build.VERSION.SDK_INT > Build.VERSION_CODES.Q is used to check the Android version after + // releasing Android R. + return BuildCompat.isAtLeastR() || Build.VERSION.SDK_INT > Build.VERSION_CODES.Q; + } + @Test public void testMaybeMarkCapabilitiesRestricted() { // verify EIMS is restricted @@ -269,25 +278,36 @@ public class NetworkCapabilitiesTest { .setUids(uids) .addCapability(NET_CAPABILITY_EIMS) .addCapability(NET_CAPABILITY_NOT_METERED); - netCap.setOwnerUid(123); + if (isAtLeastR()) { + netCap.setOwnerUid(123); + } assertParcelingIsLossless(netCap); netCap.setSSID(TEST_SSID); - assertParcelSane(netCap, 15); + testParcelSane(netCap); } @Test public void testParcelNetworkCapabilitiesWithRequestorUidAndPackageName() { final NetworkCapabilities netCap = new NetworkCapabilities() .addCapability(NET_CAPABILITY_INTERNET) - .setRequestorUid(9304) - .setRequestorPackageName("com.android.test") .addCapability(NET_CAPABILITY_EIMS) .addCapability(NET_CAPABILITY_NOT_METERED); + if (isAtLeastR()) { + netCap.setRequestorPackageName("com.android.test"); + netCap.setRequestorUid(9304); + } assertParcelingIsLossless(netCap); netCap.setSSID(TEST_SSID); - assertParcelSane(netCap, 15); + testParcelSane(netCap); } + private void testParcelSane(NetworkCapabilities cap) { + if (isAtLeastR()) { + assertParcelSane(cap, 15); + } else { + assertParcelSane(cap, 11); + } + } @Test public void testOemPaid() { @@ -443,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); @@ -581,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/common/java/android/net/util/SocketUtilsTest.kt b/tests/net/common/java/android/net/util/SocketUtilsTest.kt index 9c7cfb0c716e..aaf97f36889b 100644 --- a/tests/net/common/java/android/net/util/SocketUtilsTest.kt +++ b/tests/net/common/java/android/net/util/SocketUtilsTest.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package android.net.util; +package android.net.util +import android.os.Build import android.system.NetlinkSocketAddress import android.system.Os import android.system.OsConstants.AF_INET @@ -26,18 +27,26 @@ import android.system.OsConstants.SOCK_DGRAM import android.system.PacketSocketAddress import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 +import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Assert.fail +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith private const val TEST_INDEX = 123 private const val TEST_PORT = 555 +private const val FF_BYTE = 0xff.toByte() + @RunWith(AndroidJUnit4::class) @SmallTest class SocketUtilsTest { + @Rule @JvmField + val ignoreRule = DevSdkIgnoreRule() + @Test fun testMakeNetlinkSocketAddress() { val nlAddress = SocketUtils.makeNetlinkSocketAddress(TEST_PORT, RTMGRP_NEIGH) @@ -50,16 +59,21 @@ class SocketUtilsTest { } @Test - fun testMakePacketSocketAddress() { + fun testMakePacketSocketAddress_Q() { val pkAddress = SocketUtils.makePacketSocketAddress(ETH_P_ALL, TEST_INDEX) assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress) - val ff = 0xff.toByte() - val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX, - byteArrayOf(ff, ff, ff, ff, ff, ff)) + val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX, ByteArray(6) { FF_BYTE }) assertTrue("Not PacketSocketAddress object", pkAddress2 is PacketSocketAddress) } + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + fun testMakePacketSocketAddress() { + val pkAddress = SocketUtils.makePacketSocketAddress( + ETH_P_ALL, TEST_INDEX, ByteArray(6) { FF_BYTE }) + assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress) + } + @Test fun testCloseSocket() { // Expect no exception happening with null object. diff --git a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java b/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java index 8eb5cfa48c1a..1d6c10766792 100644 --- a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java +++ b/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java @@ -304,12 +304,12 @@ public class ConnectivityDiagnosticsManagerTest { } @Test - public void testConnectivityDiagnosticsCallbackOnConnectivityReport() { - mBinder.onConnectivityReport(createSampleConnectivityReport()); + public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() { + mBinder.onConnectivityReportAvailable(createSampleConnectivityReport()); // The callback will be invoked synchronously by inline executor. Immediately check the // latch without waiting. - verify(mCb).onConnectivityReport(eq(createSampleConnectivityReport())); + verify(mCb).onConnectivityReportAvailable(eq(createSampleConnectivityReport())); } @Test diff --git a/tests/net/java/android/net/IpMemoryStoreTest.java b/tests/net/java/android/net/IpMemoryStoreTest.java index b81ca36429ff..442ac5605e90 100644 --- a/tests/net/java/android/net/IpMemoryStoreTest.java +++ b/tests/net/java/android/net/IpMemoryStoreTest.java @@ -35,6 +35,7 @@ import android.net.ipmemorystore.IOnStatusListener; import android.net.ipmemorystore.NetworkAttributes; import android.net.ipmemorystore.NetworkAttributesParcelable; import android.net.ipmemorystore.Status; +import android.net.networkstack.ModuleNetworkStackClient; import android.os.RemoteException; import androidx.test.filters.SmallTest; @@ -67,7 +68,7 @@ public class IpMemoryStoreTest { @Mock Context mMockContext; @Mock - NetworkStackClient mNetworkStackClient; + ModuleNetworkStackClient mModuleNetworkStackClient; @Mock IIpMemoryStore mMockService; @Mock @@ -90,14 +91,14 @@ public class IpMemoryStoreTest { ((IIpMemoryStoreCallbacks) invocation.getArgument(0)) .onIpMemoryStoreFetched(mMockService); return null; - }).when(mNetworkStackClient).fetchIpMemoryStore(any()); + }).when(mModuleNetworkStackClient).fetchIpMemoryStore(any()); } else { - doNothing().when(mNetworkStackClient).fetchIpMemoryStore(mCbCaptor.capture()); + doNothing().when(mModuleNetworkStackClient).fetchIpMemoryStore(mCbCaptor.capture()); } mStore = new IpMemoryStore(mMockContext) { @Override - protected NetworkStackClient getNetworkStackClient() { - return mNetworkStackClient; + protected ModuleNetworkStackClient getModuleNetworkStackClient(Context ctx) { + return mModuleNetworkStackClient; } }; } diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java index 33d77d288e15..e71d5995255d 100644 --- a/tests/net/java/android/net/NetworkStatsTest.java +++ b/tests/net/java/android/net/NetworkStatsTest.java @@ -64,15 +64,15 @@ public class NetworkStatsTest { @Test public void testFindIndex() throws Exception { final NetworkStats stats = new NetworkStats(TEST_START, 5) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11) - .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12) - .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, + .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12); assertEquals(4, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, @@ -94,21 +94,21 @@ public class NetworkStatsTest { @Test public void testFindIndexHinted() { final NetworkStats stats = new NetworkStats(TEST_START, 3) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11) - .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12) - .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1024L, 8L, 0L, 0L, 10) - .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11) - .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, + .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11) - .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12) - .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, + .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12); // verify that we correctly find across regardless of hinting @@ -143,27 +143,27 @@ public class NetworkStatsTest { assertEquals(0, stats.size()); assertEquals(4, stats.internalSize()); - stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 1L, 1L, 2L, 2L, 3); - stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 2L, 2L, 2L, 2L, 4); - stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 3L, 3L, 2L, 2L, 5); - stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, + stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_NO, 3L, 3L, 2L, 2L, 5); assertEquals(4, stats.size()); assertEquals(4, stats.internalSize()); - stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4L, 40L, 4L, 40L, 7); - stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 5L, 50L, 4L, 40L, 8); - stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 6L, 60L, 5L, 50L, 10); - stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 7L, 70L, 5L, 50L, 11); - stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, + stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_NO, 7L, 70L, 5L, 50L, 11); assertEquals(9, stats.size()); @@ -193,8 +193,8 @@ public class NetworkStatsTest { public void testCombineExisting() throws Exception { final NetworkStats stats = new NetworkStats(TEST_START, 10); - stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10); - stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2); + stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10); + stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2); stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L, -128L, -1L, -1); @@ -215,12 +215,12 @@ public class NetworkStatsTest { @Test public void testSubtractIdenticalData() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats after = new NetworkStats(TEST_START, 2) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats result = after.subtract(before); @@ -234,12 +234,12 @@ public class NetworkStatsTest { @Test public void testSubtractIdenticalRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats after = new NetworkStats(TEST_START, 2) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20); final NetworkStats result = after.subtract(before); @@ -253,13 +253,13 @@ public class NetworkStatsTest { @Test public void testSubtractNewRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats after = new NetworkStats(TEST_START, 3) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12) - .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12) + .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20); final NetworkStats result = after.subtract(before); @@ -275,11 +275,11 @@ public class NetworkStatsTest { @Test public void testSubtractMissingRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0) - .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0); + .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0) + .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0); final NetworkStats after = new NetworkStats(TEST_START, 1) - .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0); + .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0); final NetworkStats result = after.subtract(before); @@ -293,40 +293,40 @@ public class NetworkStatsTest { @Test public void testTotalBytes() throws Exception { final NetworkStats iface = new NetworkStats(TEST_START, 2) - .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L); + .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L); assertEquals(384L, iface.getTotalBytes()); final NetworkStats uidSet = new NetworkStats(TEST_START, 3) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L); assertEquals(96L, uidSet.getTotalBytes()); final NetworkStats uidTag = new NetworkStats(TEST_START, 6) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L); assertEquals(64L, uidTag.getTotalBytes()); final NetworkStats uidMetered = new NetworkStats(TEST_START, 3) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); assertEquals(96L, uidMetered.getTotalBytes()); final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); assertEquals(96L, uidRoaming.getTotalBytes()); } @@ -343,11 +343,11 @@ public class NetworkStatsTest { @Test public void testGroupedByIfaceAll() throws Exception { final NetworkStats uidStats = new NetworkStats(TEST_START, 3) - .addEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L) - .addEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, + .insertEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 128L, 8L, 0L, 2L, 20L) - .addEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES, + .insertEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L); final NetworkStats grouped = uidStats.groupedByIface(); @@ -361,19 +361,19 @@ public class NetworkStatsTest { @Test public void testGroupedByIface() throws Exception { final NetworkStats uidStats = new NetworkStats(TEST_START, 7) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L); final NetworkStats grouped = uidStats.groupedByIface(); @@ -390,19 +390,19 @@ public class NetworkStatsTest { @Test public void testAddAllValues() { final NetworkStats first = new NetworkStats(TEST_START, 5) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, + .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); final NetworkStats second = new NetworkStats(TEST_START, 2) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, + .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L); first.combineAllValues(second); @@ -421,19 +421,19 @@ public class NetworkStatsTest { @Test public void testGetTotal() { final NetworkStats stats = new NetworkStats(TEST_START, 7) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 512L,32L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L); assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L); @@ -459,7 +459,7 @@ public class NetworkStatsTest { assertEquals(0, after.size()); // Test 1 item stats. - before.addEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L); + before.insertEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L); after = before.clone(); after.removeUids(new int[0]); assertEquals(1, after.size()); @@ -469,12 +469,12 @@ public class NetworkStatsTest { assertEquals(0, after.size()); // Append remaining test items. - before.addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L) - .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L) - .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L); + before.insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L) + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L) + .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L); assertEquals(7, before.size()); // Test remove with empty uid list. @@ -505,12 +505,12 @@ public class NetworkStatsTest { @Test public void testClone() throws Exception { final NetworkStats original = new NetworkStats(TEST_START, 5) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); // make clone and mutate original final NetworkStats clone = original.clone(); - original.addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L); + original.insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L); assertEquals(3, original.size()); assertEquals(2, clone.size()); @@ -523,8 +523,8 @@ public class NetworkStatsTest { public void testAddWhenEmpty() throws Exception { final NetworkStats red = new NetworkStats(TEST_START, -1); final NetworkStats blue = new NetworkStats(TEST_START, 5) - .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) - .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); + .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) + .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L); // We're mostly checking that we don't crash red.combineAllValues(blue); @@ -537,37 +537,37 @@ public class NetworkStatsTest { final String underlyingIface = "wlan0"; final int testTag1 = 8888; NetworkStats delta = new NetworkStats(TEST_START, 17) - .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 39605L, 46L, 12259L, 55L, 0L) - .addEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) - .addEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 72667L, 197L, 43909L, 241L, 0L) - .addEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 9297L, 17L, 4128L, 21L, 0L) // VPN package also uses some traffic through unprotected network. - .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 4983L, 10L, 1801L, 12L, 0L) - .addEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) // Tag entries - .addEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 21691L, 41L, 13820L, 51L, 0L) - .addEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1281L, 2L, 665L, 2L, 0L) // Irrelevant entries - .addEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1685L, 5L, 2070L, 6L, 0L) // Underlying Iface entries - .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 5178L, 8L, 2139L, 11L, 0L) - .addEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) - .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, + ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L) + .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 149873L, 287L, 59217L /* smaller than sum(tun0) */, 299L /* smaller than sum(tun0) */, 0L) - .addEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, - DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); + .insertEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, + ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface}); assertEquals(20, delta.size()); @@ -635,19 +635,19 @@ public class NetworkStatsTest { final String underlyingIface = "wlan0"; NetworkStats delta = new NetworkStats(TEST_START, 9) // 2 different apps sent/receive data via tun0. - .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L) - .addEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 500L, 2L, 200L, 5L, 0L) // VPN package resends data through the tunnel (with exaggerated overhead) - .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 240000, 100L, 120000L, 60L, 0L) // 1 app already has some traffic on the underlying interface, the other doesn't yet - .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1000L, 10L, 2000L, 20L, 0L) // Traffic through the underlying interface via the vpn app. // This test should redistribute this data correctly. - .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L); delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface}); @@ -697,9 +697,9 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 3) - .addEntry(entry1) - .addEntry(entry2) - .addEntry(entry3); + .insertEntry(entry1) + .insertEntry(entry2) + .insertEntry(entry3); stats.filter(UID_ALL, INTERFACES_ALL, TAG_ALL); assertEquals(3, stats.size()); @@ -724,9 +724,9 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 3) - .addEntry(entry1) - .addEntry(entry2) - .addEntry(entry3); + .insertEntry(entry1) + .insertEntry(entry2) + .insertEntry(entry3); stats.filter(testUid, INTERFACES_ALL, TAG_ALL); assertEquals(2, stats.size()); @@ -755,10 +755,10 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 4) - .addEntry(entry1) - .addEntry(entry2) - .addEntry(entry3) - .addEntry(entry4); + .insertEntry(entry1) + .insertEntry(entry2) + .insertEntry(entry3) + .insertEntry(entry4); stats.filter(UID_ALL, new String[] { testIf1, testIf2 }, TAG_ALL); assertEquals(3, stats.size()); @@ -778,8 +778,8 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 3) - .addEntry(entry1) - .addEntry(entry2); + .insertEntry(entry1) + .insertEntry(entry2); stats.filter(UID_ALL, new String[] { }, TAG_ALL); assertEquals(0, stats.size()); @@ -802,9 +802,9 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 3) - .addEntry(entry1) - .addEntry(entry2) - .addEntry(entry3); + .insertEntry(entry1) + .insertEntry(entry2) + .insertEntry(entry3); stats.filter(UID_ALL, INTERFACES_ALL, testTag); assertEquals(2, stats.size()); @@ -831,10 +831,10 @@ public class NetworkStatsTest { DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L); NetworkStats stats = new NetworkStats(TEST_START, 4) - .addEntry(entry1) - .addEntry(entry2) - .addEntry(entry3) - .addEntry(entry4); + .insertEntry(entry1) + .insertEntry(entry2) + .insertEntry(entry3) + .insertEntry(entry4); stats.filterDebugEntries(); @@ -891,14 +891,14 @@ public class NetworkStatsTest { 0 /* operations */); final NetworkStats statsXt = new NetworkStats(TEST_START, 3) - .addEntry(appEntry) - .addEntry(xtRootUidEntry) - .addEntry(otherEntry); + .insertEntry(appEntry) + .insertEntry(xtRootUidEntry) + .insertEntry(otherEntry); final NetworkStats statsEbpf = new NetworkStats(TEST_START, 3) - .addEntry(appEntry) - .addEntry(ebpfRootUidEntry) - .addEntry(otherEntry); + .insertEntry(appEntry) + .insertEntry(ebpfRootUidEntry) + .insertEntry(otherEntry); statsXt.apply464xlatAdjustments(stackedIface, false); statsEbpf.apply464xlatAdjustments(stackedIface, true); @@ -945,8 +945,8 @@ public class NetworkStatsTest { 0 /* operations */); NetworkStats stats = new NetworkStats(TEST_START, 2) - .addEntry(firstEntry) - .addEntry(secondEntry); + .insertEntry(firstEntry) + .insertEntry(secondEntry); // Empty map: no adjustment stats.apply464xlatAdjustments(new ArrayMap<>(), false); diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt new file mode 100644 index 000000000000..5dd0fda4da28 --- /dev/null +++ b/tests/net/java/android/net/NetworkTemplateTest.kt @@ -0,0 +1,155 @@ +/* + * 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.content.Context +import android.net.ConnectivityManager.TYPE_MOBILE +import android.net.ConnectivityManager.TYPE_WIFI +import android.net.NetworkIdentity.SUBTYPE_COMBINED +import android.net.NetworkIdentity.buildNetworkIdentity +import android.net.NetworkStats.DEFAULT_NETWORK_ALL +import android.net.NetworkStats.METERED_ALL +import android.net.NetworkStats.ROAMING_ALL +import android.net.NetworkTemplate.MATCH_MOBILE +import android.net.NetworkTemplate.MATCH_WIFI +import android.net.NetworkTemplate.NETWORK_TYPE_ALL +import android.net.NetworkTemplate.buildTemplateMobileWithRatType +import android.telephony.TelephonyManager +import com.android.testutils.assertParcelSane +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.mockito.Mockito.doReturn +import org.mockito.Mockito.mock +import org.mockito.MockitoAnnotations +import kotlin.test.assertFalse +import kotlin.test.assertNotEquals +import kotlin.test.assertTrue + +private const val TEST_IMSI1 = "imsi1" +private const val TEST_IMSI2 = "imsi2" +private const val TEST_SSID1 = "ssid1" + +@RunWith(JUnit4::class) +class NetworkTemplateTest { + private val mockContext = mock(Context::class.java) + + private fun buildMobileNetworkState(subscriberId: String): NetworkState = + buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId) + private fun buildWifiNetworkState(ssid: String): NetworkState = + buildNetworkState(TYPE_WIFI, ssid = ssid) + + private fun buildNetworkState( + type: Int, + subscriberId: String? = null, + ssid: String? = null + ): NetworkState { + val info = mock(NetworkInfo::class.java) + doReturn(type).`when`(info).type + doReturn(NetworkInfo.State.CONNECTED).`when`(info).state + val lp = LinkProperties() + val caps = NetworkCapabilities().apply { + setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false) + setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true) + } + return NetworkState(info, lp, caps, mock(Network::class.java), subscriberId, ssid) + } + + private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) = + assertTrue(matches(ident), "$this does not match $ident") + + private fun NetworkTemplate.assertDoesNotMatch(ident: NetworkIdentity) = + assertFalse(matches(ident), "$this should match $ident") + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + } + + @Test + fun testRatTypeGroupMatches() { + val stateMobile = buildMobileNetworkState(TEST_IMSI1) + // Build UMTS template that matches mobile identities with RAT in the same + // group with any IMSI. See {@link NetworkTemplate#getCollapsedRatType}. + val templateUmts = buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS) + // Build normal template that matches mobile identities with any RAT and IMSI. + val templateAll = buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL) + // Build template with UNKNOWN RAT that matches mobile identities with RAT that + // cannot be determined. + val templateUnknown = + buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN) + + val identUmts = buildNetworkIdentity( + mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_UMTS) + val identHsdpa = buildNetworkIdentity( + mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_HSDPA) + val identLte = buildNetworkIdentity( + mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_LTE) + val identCombined = buildNetworkIdentity( + mockContext, stateMobile, false, SUBTYPE_COMBINED) + val identImsi2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2), + false, TelephonyManager.NETWORK_TYPE_UMTS) + val identWifi = buildNetworkIdentity( + mockContext, buildWifiNetworkState(TEST_SSID1), true, 0) + + // Assert that identity with the same RAT matches. + templateUmts.assertMatches(identUmts) + templateAll.assertMatches(identUmts) + templateUnknown.assertDoesNotMatch(identUmts) + // Assert that identity with the RAT within the same group matches. + templateUmts.assertMatches(identHsdpa) + templateAll.assertMatches(identHsdpa) + templateUnknown.assertDoesNotMatch(identHsdpa) + // Assert that identity with the RAT out of the same group only matches template with + // NETWORK_TYPE_ALL. + templateUmts.assertDoesNotMatch(identLte) + templateAll.assertMatches(identLte) + templateUnknown.assertDoesNotMatch(identLte) + // Assert that identity with combined RAT only matches with template with NETWORK_TYPE_ALL + // and NETWORK_TYPE_UNKNOWN. + templateUmts.assertDoesNotMatch(identCombined) + templateAll.assertMatches(identCombined) + templateUnknown.assertMatches(identCombined) + // Assert that identity with different IMSI matches. + templateUmts.assertMatches(identImsi2) + templateAll.assertMatches(identImsi2) + templateUnknown.assertDoesNotMatch(identImsi2) + // Assert that wifi identity does not match. + templateUmts.assertDoesNotMatch(identWifi) + templateAll.assertDoesNotMatch(identWifi) + templateUnknown.assertDoesNotMatch(identWifi) + } + + @Test + fun testParcelUnparcel() { + val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL, + ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE) + val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL, + ROAMING_ALL, DEFAULT_NETWORK_ALL, 0) + assertParcelSane(templateMobile, 8) + assertParcelSane(templateWifi, 8) + } + + // Verify NETWORK_TYPE_ALL does not conflict with TelephonyManager#NETWORK_TYPE_* constants. + @Test + fun testNetworkTypeAll() { + for (ratType in TelephonyManager.getAllNetworkTypes()) { + assertNotEquals(NETWORK_TYPE_ALL, ratType) + } + } +} 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/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index c1999dba6903..83399b8076af 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -25,7 +25,6 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; -import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; import static android.net.ConnectivityManager.NETID_UNSET; @@ -175,6 +174,7 @@ import android.net.NetworkUtils; import android.net.ProxyInfo; import android.net.ResolverParamsParcel; import android.net.RouteInfo; +import android.net.RouteInfoParcel; import android.net.SocketKeepalive; import android.net.UidRange; import android.net.Uri; @@ -307,6 +307,8 @@ public class ConnectivityServiceTest { private static final long TIMESTAMP = 1234L; + private static final int NET_ID = 110; + private static final String CLAT_PREFIX = "v4-"; private static final String MOBILE_IFNAME = "test_rmnet_data0"; private static final String WIFI_IFNAME = "test_wlan0"; @@ -427,7 +429,6 @@ public class ConnectivityServiceTest { public Object getSystemService(String name) { if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager; - if (Context.NETWORK_STACK_SERVICE.equals(name)) return mNetworkStack; if (Context.USER_SERVICE.equals(name)) return mUserManager; if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager; if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager; @@ -1016,6 +1017,7 @@ public class ConnectivityServiceTest { private int mVpnType = VpnManager.TYPE_VPN_SERVICE; private VpnInfo mVpnInfo; + private Network[] mUnderlyingNetworks; public MockVpn(int userId) { super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService, @@ -1105,9 +1107,21 @@ public class ConnectivityServiceTest { return super.getVpnInfo(); } - private void setVpnInfo(VpnInfo vpnInfo) { + private synchronized void setVpnInfo(VpnInfo vpnInfo) { mVpnInfo = vpnInfo; } + + @Override + public synchronized Network[] getUnderlyingNetworks() { + if (mUnderlyingNetworks != null) return mUnderlyingNetworks; + + return super.getUnderlyingNetworks(); + } + + /** Don't override behavior for {@link Vpn#setUnderlyingNetworks}. */ + private synchronized void overrideUnderlyingNetworks(Network[] underlyingNetworks) { + mUnderlyingNetworks = underlyingNetworks; + } } private void mockVpn(int uid) { @@ -1374,7 +1388,6 @@ public class ConnectivityServiceTest { @NonNull final Predicate<Intent> filter) { final ConditionVariable cv = new ConditionVariable(); final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); - intentFilter.addAction(CONNECTIVITY_ACTION_SUPL); final BroadcastReceiver receiver = new BroadcastReceiver() { private int remaining = count; public void onReceive(Context context, Intent intent) { @@ -1422,56 +1435,28 @@ public class ConnectivityServiceTest { final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); - // Send request and check that the legacy broadcast for SUPL is sent correctly. + // File request, withdraw it and make sure no broadcast is sent + final ConditionVariable cv2 = registerConnectivityBroadcast(1); final TestNetworkCallback callback = new TestNetworkCallback(); - final ConditionVariable cv2 = registerConnectivityBroadcastThat(1, - intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); mCm.requestNetwork(legacyRequest, callback); callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); - waitFor(cv2); - - // File another request, withdraw it and make sure no broadcast is sent - final ConditionVariable cv3 = registerConnectivityBroadcast(1); - final TestNetworkCallback callback2 = new TestNetworkCallback(); - mCm.requestNetwork(legacyRequest, callback2); - callback2.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); - mCm.unregisterNetworkCallback(callback2); - assertFalse(cv3.block(800)); // 800ms long enough to at least flake if this is sent + mCm.unregisterNetworkCallback(callback); + assertFalse(cv2.block(800)); // 800ms long enough to at least flake if this is sent // As the broadcast did not fire, the receiver was not unregistered. Do this now. mServiceContext.clearRegisteredReceivers(); - // Withdraw the request and check that the broadcast for disconnection is sent. - final ConditionVariable cv4 = registerConnectivityBroadcastThat(1, intent -> - !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected() - && intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); - mCm.unregisterNetworkCallback(callback); - waitFor(cv4); - - // Re-file the request and expect the connected broadcast again - final ConditionVariable cv5 = registerConnectivityBroadcastThat(1, - intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); - final TestNetworkCallback callback3 = new TestNetworkCallback(); - mCm.requestNetwork(legacyRequest, callback3); - callback3.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); - waitFor(cv5); - - // Disconnect the network and expect two disconnected broadcasts, one for SUPL and one - // for mobile. Use a small hack to check that both have been sent, but the order is - // not contractual. + // Disconnect the network and expect mobile disconnected broadcast. Use a small hack to + // check that has been sent. final AtomicBoolean vanillaAction = new AtomicBoolean(false); - final AtomicBoolean suplAction = new AtomicBoolean(false); - final ConditionVariable cv6 = registerConnectivityBroadcastThat(2, intent -> { + final ConditionVariable cv3 = registerConnectivityBroadcastThat(1, intent -> { if (intent.getAction().equals(CONNECTIVITY_ACTION)) { vanillaAction.set(true); - } else if (intent.getAction().equals(CONNECTIVITY_ACTION_SUPL)) { - suplAction.set(true); } return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected(); }); mCellNetworkAgent.disconnect(); - waitFor(cv6); + waitFor(cv3); assertTrue(vanillaAction.get()); - assertTrue(suplAction.get()); } @Test @@ -2425,7 +2410,7 @@ public class ConnectivityServiceTest { assertEquals(expectedRequestCount, testFactory.getMyRequestCount()); assertTrue(testFactory.getMyStartRequested()); - testFactory.unregister(); + testFactory.terminate(); if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback); handlerThread.quit(); } @@ -2451,6 +2436,38 @@ public class ConnectivityServiceTest { } @Test + public void testNetworkFactoryUnregister() throws Exception { + final NetworkCapabilities filter = new NetworkCapabilities(); + filter.clearAll(); + + final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); + handlerThread.start(); + + // Checks that calling setScoreFilter on a NetworkFactory immediately before closing it + // does not crash. + for (int i = 0; i < 100; i++) { + final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), + mServiceContext, "testFactory", filter); + // Register the factory and don't be surprised when the default request arrives. + testFactory.expectAddRequestsWithScores(0); + testFactory.register(); + testFactory.waitForNetworkRequests(1); + + testFactory.setScoreFilter(42); + testFactory.terminate(); + + if (i % 2 == 0) { + try { + testFactory.register(); + fail("Re-registering terminated NetworkFactory should throw"); + } catch (IllegalStateException expected) { + } + } + } + handlerThread.quit(); + } + + @Test public void testNoMutableNetworkRequests() throws Exception { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0); NetworkRequest request1 = new NetworkRequest.Builder() @@ -2750,9 +2767,6 @@ public class ConnectivityServiceTest { // Expect NET_CAPABILITY_VALIDATED onAvailable callback. validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); - // Expect no notification to be shown when captive portal disappears by itself - verify(mNotificationManager, never()).notifyAsUser( - anyString(), eq(NotificationType.LOGGED_IN.eventId), any(), any()); // Break network connectivity. // Expect NET_CAPABILITY_VALIDATED onLost callback. @@ -2814,8 +2828,6 @@ public class ConnectivityServiceTest { mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent); captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); - verify(mNotificationManager, times(1)).notifyAsUser(anyString(), - eq(NotificationType.LOGGED_IN.eventId), any(), eq(UserHandle.ALL)); mCm.unregisterNetworkCallback(validatedCallback); mCm.unregisterNetworkCallback(captivePortalCallback); @@ -3487,7 +3499,7 @@ public class ConnectivityServiceTest { cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); assertLength(1, mCm.getAllNetworks()); - testFactory.unregister(); + testFactory.terminate(); mCm.unregisterNetworkCallback(cellNetworkCallback); handlerThread.quit(); } @@ -3728,7 +3740,7 @@ public class ConnectivityServiceTest { mCm.requestNetwork(nr, networkCallback, timeoutMs); // pass timeout and validate that UNAVAILABLE is called - networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, null); + networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); // create a network satisfying request - validate that request not triggered mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); @@ -3819,7 +3831,7 @@ public class ConnectivityServiceTest { // Simulate the factory releasing the request as unfulfillable and expect onUnavailable! testFactory.triggerUnfulfillable(requests.get(newRequestId)); - networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, null); + networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); testFactory.waitForRequests(); // unregister network callback - a no-op (since already freed by the @@ -3827,7 +3839,7 @@ public class ConnectivityServiceTest { mCm.unregisterNetworkCallback(networkCallback); } - testFactory.unregister(); + testFactory.terminate(); handlerThread.quit(); } @@ -6037,6 +6049,7 @@ public class ConnectivityServiceTest { verify(mBatteryStatsService).noteNetworkInterfaceType(stackedLp.getInterfaceName(), TYPE_MOBILE); } + reset(mMockNetd); // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked // linkproperties are cleaned up. @@ -6088,7 +6101,6 @@ public class ConnectivityServiceTest { networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent); verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString()); - // Clat iface comes up. Expect stacked link to be added. clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true); networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, @@ -6674,17 +6686,45 @@ public class ConnectivityServiceTest { } } + private void assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel) { + assertEquals(route.getDestination().toString(), parcel.destination); + assertEquals(route.getInterface(), parcel.ifName); + assertEquals(route.getMtu(), parcel.mtu); + + switch (route.getType()) { + case RouteInfo.RTN_UNICAST: + if (route.hasGateway()) { + assertEquals(route.getGateway().getHostAddress(), parcel.nextHop); + } else { + assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); + } + break; + case RouteInfo.RTN_UNREACHABLE: + assertEquals(INetd.NEXTHOP_UNREACHABLE, parcel.nextHop); + break; + case RouteInfo.RTN_THROW: + assertEquals(INetd.NEXTHOP_THROW, parcel.nextHop); + break; + default: + assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop); + break; + } + } + private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception { - InOrder inOrder = inOrder(mNetworkManagementService); + ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); + verify(mMockNetd, times(routes.length)).networkAddRouteParcel(eq(netId), captor.capture()); for (int i = 0; i < routes.length; i++) { - inOrder.verify(mNetworkManagementService).addRoute(eq(netId), eq(routes[i])); + assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); } } private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception { - InOrder inOrder = inOrder(mNetworkManagementService); + ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); + verify(mMockNetd, times(routes.length)).networkRemoveRouteParcel(eq(netId), + captor.capture()); for (int i = 0; i < routes.length; i++) { - inOrder.verify(mNetworkManagementService).removeRoute(eq(netId), eq(routes[i])); + assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i)); } } @@ -6762,6 +6802,22 @@ public class ConnectivityServiceTest { } @Test + public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { + final NetworkAgentInfo naiWithoutUid = + new NetworkAgentInfo( + null, null, null, null, null, new NetworkCapabilities(), 0, + mServiceContext, null, null, mService, null, null, null, 0); + + mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); + + assertFalse( + "Mismatched uid/package name should not pass the location permission check", + mService.checkConnectivityDiagnosticsPermissions( + Process.myPid() + 1, Process.myUid() + 1, naiWithoutUid, + mContext.getOpPackageName())); + } + + @Test public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception { final NetworkAgentInfo naiWithoutUid = new NetworkAgentInfo( @@ -6779,9 +6835,10 @@ public class ConnectivityServiceTest { @Test public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception { + final Network network = new Network(NET_ID); final NetworkAgentInfo naiWithoutUid = new NetworkAgentInfo( - null, null, null, null, null, new NetworkCapabilities(), 0, + null, null, network, null, null, new NetworkCapabilities(), 0, mServiceContext, null, null, mService, null, null, null, 0); setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, @@ -6794,17 +6851,25 @@ public class ConnectivityServiceTest { info.ownerUid = Process.myUid(); info.vpnIface = "interface"; mMockVpn.setVpnInfo(info); + mMockVpn.overrideUnderlyingNetworks(new Network[] {network}); assertTrue( "Active VPN permission not applied", mService.checkConnectivityDiagnosticsPermissions( Process.myPid(), Process.myUid(), naiWithoutUid, mContext.getOpPackageName())); + + mMockVpn.overrideUnderlyingNetworks(null); + assertFalse( + "VPN shouldn't receive callback on non-underlying network", + mService.checkConnectivityDiagnosticsPermissions( + Process.myPid(), Process.myUid(), naiWithoutUid, + mContext.getOpPackageName())); } @Test public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception { final NetworkCapabilities nc = new NetworkCapabilities(); - nc.setAdministratorUids(Arrays.asList(Process.myUid())); + nc.setAdministratorUids(new int[] {Process.myUid()}); final NetworkAgentInfo naiWithUid = new NetworkAgentInfo( null, null, null, null, null, nc, 0, mServiceContext, null, null, @@ -6826,7 +6891,7 @@ public class ConnectivityServiceTest { public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception { final NetworkCapabilities nc = new NetworkCapabilities(); nc.setOwnerUid(Process.myUid()); - nc.setAdministratorUids(Arrays.asList(Process.myUid())); + nc.setAdministratorUids(new int[] {Process.myUid()}); final NetworkAgentInfo naiWithUid = new NetworkAgentInfo( null, null, null, null, null, nc, 0, mServiceContext, null, null, @@ -6867,18 +6932,19 @@ public class ConnectivityServiceTest { } @Test - public void testConnectivityDiagnosticsCallbackOnConnectivityReport() throws Exception { + public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() + throws Exception { setUpConnectivityDiagnosticsCallback(); // Block until all other events are done processing. HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS); // Verify onConnectivityReport fired - verify(mConnectivityDiagnosticsCallback).onConnectivityReport( + verify(mConnectivityDiagnosticsCallback).onConnectivityReportAvailable( argThat(report -> { final NetworkCapabilities nc = report.getNetworkCapabilities(); return nc.getUids() == null - && nc.getAdministratorUids().isEmpty() + && nc.getAdministratorUids().length == 0 && nc.getOwnerUid() == Process.INVALID_UID; })); } @@ -6899,7 +6965,7 @@ public class ConnectivityServiceTest { argThat(report -> { final NetworkCapabilities nc = report.getNetworkCapabilities(); return nc.getUids() == null - && nc.getAdministratorUids().isEmpty() + && nc.getAdministratorUids().length == 0 && nc.getOwnerUid() == Process.INVALID_UID; })); } @@ -6929,4 +6995,60 @@ public class ConnectivityServiceTest { verify(mConnectivityDiagnosticsCallback) .onNetworkConnectivityReported(eq(n), eq(noConnectivity)); } + + @Test + public void testRouteAddDeleteUpdate() throws Exception { + final NetworkRequest request = new NetworkRequest.Builder().build(); + final TestNetworkCallback networkCallback = new TestNetworkCallback(); + mCm.registerNetworkCallback(request, networkCallback); + mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); + reset(mMockNetd); + mCellNetworkAgent.connect(false); + networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); + final int netId = mCellNetworkAgent.getNetwork().netId; + + final String iface = "rmnet_data0"; + final InetAddress gateway = InetAddress.getByName("fe80::5678"); + RouteInfo direct = RouteInfo.makeHostRoute(gateway, iface); + RouteInfo rio1 = new RouteInfo(new IpPrefix("2001:db8:1::/48"), gateway, iface); + RouteInfo rio2 = new RouteInfo(new IpPrefix("2001:db8:2::/48"), gateway, iface); + RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, gateway, iface); + RouteInfo defaultWithMtu = new RouteInfo(null, gateway, iface, RouteInfo.RTN_UNICAST, + 1280 /* mtu */); + + // Send LinkProperties and check that we ask netd to add routes. + LinkProperties lp = new LinkProperties(); + lp.setInterfaceName(iface); + lp.addRoute(direct); + lp.addRoute(rio1); + lp.addRoute(defaultRoute); + mCellNetworkAgent.sendLinkProperties(lp); + networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, x -> x.getRoutes().size() == 3); + + assertRoutesAdded(netId, direct, rio1, defaultRoute); + reset(mMockNetd); + + // Send updated LinkProperties and check that we ask netd to add, remove, update routes. + assertTrue(lp.getRoutes().contains(defaultRoute)); + lp.removeRoute(rio1); + lp.addRoute(rio2); + lp.addRoute(defaultWithMtu); + // Ensure adding the same route with a different MTU replaces the previous route. + assertFalse(lp.getRoutes().contains(defaultRoute)); + assertTrue(lp.getRoutes().contains(defaultWithMtu)); + + mCellNetworkAgent.sendLinkProperties(lp); + networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, + x -> x.getRoutes().contains(rio2)); + + assertRoutesRemoved(netId, rio1); + assertRoutesAdded(netId, rio2); + + ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class); + verify(mMockNetd).networkUpdateRouteParcel(eq(netId), captor.capture()); + assertRouteInfoParcelMatches(defaultWithMtu, captor.getValue()); + + + mCm.unregisterNetworkCallback(networkCallback); + } } 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()); diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java index d57f2250fc5c..47db5d431671 100644 --- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java @@ -238,20 +238,6 @@ public class NetworkNotificationManagerTest { } @Test - public void testSameLevelNotifications() { - final int id = 101; - final String tag = NetworkNotificationManager.tagFor(id); - - mManager.showNotification(id, LOGGED_IN, mWifiNai, mCellNai, null, false); - verify(mNotificationManager, times(1)) - .notifyAsUser(eq(tag), eq(LOGGED_IN.eventId), any(), any()); - - mManager.showNotification(id, LOST_INTERNET, mWifiNai, mCellNai, null, false); - verify(mNotificationManager, times(1)) - .notifyAsUser(eq(tag), eq(LOST_INTERNET.eventId), any(), any()); - } - - @Test public void testClearNotificationByType() { final int id = 101; final String tag = NetworkNotificationManager.tagFor(id); @@ -259,31 +245,25 @@ public class NetworkNotificationManagerTest { // clearNotification(int id, NotificationType notifyType) will check if given type is equal // to previous type or not. If they are equal then clear the notification; if they are not // equal then return. - - mManager.showNotification(id, LOGGED_IN, mWifiNai, mCellNai, null, false); + mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false); verify(mNotificationManager, times(1)) - .notifyAsUser(eq(tag), eq(LOGGED_IN.eventId), any(), any()); + .notifyAsUser(eq(tag), eq(NO_INTERNET.eventId), any(), any()); - // Previous notification is LOGGED_IN and given type is LOGGED_IN too. The notification + // Previous notification is NO_INTERNET and given type is NO_INTERNET too. The notification // should be cleared. - mManager.clearNotification(id, LOGGED_IN); + mManager.clearNotification(id, NO_INTERNET); verify(mNotificationManager, times(1)) - .cancelAsUser(eq(tag), eq(LOGGED_IN.eventId), any()); - - mManager.showNotification(id, LOGGED_IN, mWifiNai, mCellNai, null, false); - verify(mNotificationManager, times(2)) - .notifyAsUser(eq(tag), eq(LOGGED_IN.eventId), any(), any()); + .cancelAsUser(eq(tag), eq(NO_INTERNET.eventId), any()); - // LOST_INTERNET notification popup after LOGGED_IN notification. - mManager.showNotification(id, LOST_INTERNET, mWifiNai, mCellNai, null, false); + // SIGN_IN is popped-up. + mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false); verify(mNotificationManager, times(1)) - .notifyAsUser(eq(tag), eq(LOST_INTERNET.eventId), any(), any()); + .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any()); - // Previous notification is LOST_INTERNET and given type is LOGGED_IN. The notification - // shouldn't be cleared. - mManager.clearNotification(id, LOGGED_IN); - // LOST_INTERNET shouldn't be cleared. + // The notification type is not matching previous one, PARTIAL_CONNECTIVITY won't be + // cleared. + mManager.clearNotification(id, PARTIAL_CONNECTIVITY); verify(mNotificationManager, never()) - .cancelAsUser(eq(tag), eq(LOST_INTERNET.eventId), any()); + .cancelAsUser(eq(tag), eq(PARTIAL_CONNECTIVITY.eventId), any()); } } diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java index 8f90f13ce7ef..551498f2c0cc 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java @@ -319,33 +319,33 @@ public class NetworkStatsCollectionTest { assertEntry(18322, 75, 15031, 75, history.getValues(i++, null)); assertEntry(527798, 761, 78570, 652, history.getValues(i++, null)); assertEntry(527797, 760, 78570, 651, history.getValues(i++, null)); - assertEntry(10747, 50, 16838, 55, history.getValues(i++, null)); - assertEntry(10747, 49, 16838, 54, history.getValues(i++, null)); + assertEntry(10747, 50, 16839, 55, history.getValues(i++, null)); + assertEntry(10747, 49, 16837, 54, history.getValues(i++, null)); assertEntry(89191, 151, 18021, 140, history.getValues(i++, null)); assertEntry(89190, 150, 18020, 139, history.getValues(i++, null)); - assertEntry(3821, 22, 4525, 26, history.getValues(i++, null)); - assertEntry(3820, 22, 4524, 26, history.getValues(i++, null)); - assertEntry(91686, 159, 18575, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18575, 146, history.getValues(i++, null)); - assertEntry(8289, 35, 6863, 38, history.getValues(i++, null)); - assertEntry(8289, 35, 6863, 38, history.getValues(i++, null)); + assertEntry(3821, 23, 4525, 26, history.getValues(i++, null)); + assertEntry(3820, 21, 4524, 26, history.getValues(i++, null)); + assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); + assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); + assertEntry(8289, 36, 6864, 39, history.getValues(i++, null)); + assertEntry(8289, 34, 6862, 37, history.getValues(i++, null)); assertEntry(113914, 174, 18364, 157, history.getValues(i++, null)); assertEntry(113913, 173, 18364, 157, history.getValues(i++, null)); - assertEntry(11378, 49, 9261, 49, history.getValues(i++, null)); - assertEntry(11377, 48, 9261, 49, history.getValues(i++, null)); - assertEntry(201765, 328, 41808, 291, history.getValues(i++, null)); - assertEntry(201765, 328, 41807, 290, history.getValues(i++, null)); - assertEntry(106106, 218, 39917, 201, history.getValues(i++, null)); - assertEntry(106105, 217, 39917, 201, history.getValues(i++, null)); + assertEntry(11378, 49, 9261, 50, history.getValues(i++, null)); + assertEntry(11377, 48, 9261, 48, history.getValues(i++, null)); + assertEntry(201766, 328, 41808, 291, history.getValues(i++, null)); + assertEntry(201764, 328, 41807, 290, history.getValues(i++, null)); + assertEntry(106106, 219, 39918, 202, history.getValues(i++, null)); + assertEntry(106105, 216, 39916, 200, history.getValues(i++, null)); assertEquals(history.size(), i); // Slice from middle should be untouched history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS, TIME_B + HOUR_IN_MILLIS); i = 0; - assertEntry(3821, 22, 4525, 26, history.getValues(i++, null)); - assertEntry(3820, 22, 4524, 26, history.getValues(i++, null)); - assertEntry(91686, 159, 18575, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18575, 146, history.getValues(i++, null)); + assertEntry(3821, 23, 4525, 26, history.getValues(i++, null)); + assertEntry(3820, 21, 4524, 26, history.getValues(i++, null)); + assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); + assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); assertEquals(history.size(), i); } @@ -373,25 +373,25 @@ public class NetworkStatsCollectionTest { assertEntry(527797, 760, 78570, 651, history.getValues(i++, null)); // Cycle point; start data normalization assertEntry(7507, 0, 11763, 0, history.getValues(i++, null)); - assertEntry(7507, 0, 11763, 0, history.getValues(i++, null)); + assertEntry(7507, 0, 11762, 0, history.getValues(i++, null)); assertEntry(62309, 0, 12589, 0, history.getValues(i++, null)); assertEntry(62309, 0, 12588, 0, history.getValues(i++, null)); assertEntry(2669, 0, 3161, 0, history.getValues(i++, null)); assertEntry(2668, 0, 3160, 0, history.getValues(i++, null)); // Anchor point; end data normalization - assertEntry(91686, 159, 18575, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18575, 146, history.getValues(i++, null)); - assertEntry(8289, 35, 6863, 38, history.getValues(i++, null)); - assertEntry(8289, 35, 6863, 38, history.getValues(i++, null)); + assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); + assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); + assertEntry(8289, 36, 6864, 39, history.getValues(i++, null)); + assertEntry(8289, 34, 6862, 37, history.getValues(i++, null)); assertEntry(113914, 174, 18364, 157, history.getValues(i++, null)); assertEntry(113913, 173, 18364, 157, history.getValues(i++, null)); // Cycle point - assertEntry(11378, 49, 9261, 49, history.getValues(i++, null)); - assertEntry(11377, 48, 9261, 49, history.getValues(i++, null)); - assertEntry(201765, 328, 41808, 291, history.getValues(i++, null)); - assertEntry(201765, 328, 41807, 290, history.getValues(i++, null)); - assertEntry(106106, 218, 39917, 201, history.getValues(i++, null)); - assertEntry(106105, 217, 39917, 201, history.getValues(i++, null)); + assertEntry(11378, 49, 9261, 50, history.getValues(i++, null)); + assertEntry(11377, 48, 9261, 48, history.getValues(i++, null)); + assertEntry(201766, 328, 41808, 291, history.getValues(i++, null)); + assertEntry(201764, 328, 41807, 290, history.getValues(i++, null)); + assertEntry(106106, 219, 39918, 202, history.getValues(i++, null)); + assertEntry(106105, 216, 39916, 200, history.getValues(i++, null)); assertEquals(history.size(), i); // Slice from middle should be augmented @@ -399,8 +399,8 @@ public class NetworkStatsCollectionTest { TIME_B + HOUR_IN_MILLIS); i = 0; assertEntry(2669, 0, 3161, 0, history.getValues(i++, null)); assertEntry(2668, 0, 3160, 0, history.getValues(i++, null)); - assertEntry(91686, 159, 18575, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18575, 146, history.getValues(i++, null)); + assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); + assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); assertEquals(history.size(), i); } @@ -427,34 +427,34 @@ public class NetworkStatsCollectionTest { assertEntry(527798, 761, 78570, 652, history.getValues(i++, null)); assertEntry(527797, 760, 78570, 651, history.getValues(i++, null)); // Cycle point; start data normalization - assertEntry(15015, 0, 23526, 0, history.getValues(i++, null)); - assertEntry(15015, 0, 23526, 0, history.getValues(i++, null)); + assertEntry(15015, 0, 23527, 0, history.getValues(i++, null)); + assertEntry(15015, 0, 23524, 0, history.getValues(i++, null)); assertEntry(124619, 0, 25179, 0, history.getValues(i++, null)); assertEntry(124618, 0, 25177, 0, history.getValues(i++, null)); assertEntry(5338, 0, 6322, 0, history.getValues(i++, null)); assertEntry(5337, 0, 6320, 0, history.getValues(i++, null)); // Anchor point; end data normalization - assertEntry(91686, 159, 18575, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18575, 146, history.getValues(i++, null)); - assertEntry(8289, 35, 6863, 38, history.getValues(i++, null)); - assertEntry(8289, 35, 6863, 38, history.getValues(i++, null)); + assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); + assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); + assertEntry(8289, 36, 6864, 39, history.getValues(i++, null)); + assertEntry(8289, 34, 6862, 37, history.getValues(i++, null)); assertEntry(113914, 174, 18364, 157, history.getValues(i++, null)); assertEntry(113913, 173, 18364, 157, history.getValues(i++, null)); // Cycle point - assertEntry(11378, 49, 9261, 49, history.getValues(i++, null)); - assertEntry(11377, 48, 9261, 49, history.getValues(i++, null)); - assertEntry(201765, 328, 41808, 291, history.getValues(i++, null)); - assertEntry(201765, 328, 41807, 290, history.getValues(i++, null)); - assertEntry(106106, 218, 39917, 201, history.getValues(i++, null)); - assertEntry(106105, 217, 39917, 201, history.getValues(i++, null)); + assertEntry(11378, 49, 9261, 50, history.getValues(i++, null)); + assertEntry(11377, 48, 9261, 48, history.getValues(i++, null)); + assertEntry(201766, 328, 41808, 291, history.getValues(i++, null)); + assertEntry(201764, 328, 41807, 290, history.getValues(i++, null)); + assertEntry(106106, 219, 39918, 202, history.getValues(i++, null)); + assertEntry(106105, 216, 39916, 200, history.getValues(i++, null)); // Slice from middle should be augmented history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS, TIME_B + HOUR_IN_MILLIS); i = 0; assertEntry(5338, 0, 6322, 0, history.getValues(i++, null)); assertEntry(5337, 0, 6320, 0, history.getValues(i++, null)); - assertEntry(91686, 159, 18575, 146, history.getValues(i++, null)); - assertEntry(91685, 159, 18575, 146, history.getValues(i++, null)); + assertEntry(91686, 159, 18576, 146, history.getValues(i++, null)); + assertEntry(91685, 159, 18574, 146, history.getValues(i++, null)); assertEquals(history.size(), i); } } diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java index f0e5774a5dea..a6f7a36ff01b 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java @@ -240,7 +240,7 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) - .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); + .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); NetworkStats uidSnapshot = null; mStatsObservers.updateStats( @@ -264,14 +264,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) - .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); + .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); NetworkStats uidSnapshot = null; mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) - .addIfaceValues(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L); + .insertEntry(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); waitForObserverToIdle(); @@ -294,14 +294,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) - .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); + .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); NetworkStats uidSnapshot = null; mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */) - .addIfaceValues(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L, + .insertEntry(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L, BASE_BYTES + THRESHOLD_BYTES, 22L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); @@ -326,14 +326,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = null; NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); mStatsObservers.updateStats( @@ -359,14 +359,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = null; NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); mStatsObservers.updateStats( @@ -391,14 +391,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = null; NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); mStatsObservers.updateStats( @@ -424,14 +424,14 @@ public class NetworkStatsObserversTest { // Baseline NetworkStats xtSnapshot = null; NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) - .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, + .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); mStatsObservers.updateStats( xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START); // Delta uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) - .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, + .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); mStatsObservers.updateStats( diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index 36deca3e37b7..6e6331312eac 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -42,6 +42,7 @@ import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL; import static android.net.NetworkTemplate.buildTemplateMobileAll; +import static android.net.NetworkTemplate.buildTemplateMobileWithRatType; import static android.net.NetworkTemplate.buildTemplateWifiWildcard; import static android.net.TrafficStats.MB_IN_BYTES; import static android.net.TrafficStats.UID_REMOVED; @@ -60,11 +61,13 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.AlarmManager; import android.app.usage.NetworkStatsManager; import android.content.Context; @@ -92,6 +95,8 @@ import android.os.Message; import android.os.Messenger; import android.os.PowerManager; import android.os.SimpleClock; +import android.telephony.PhoneStateListener; +import android.telephony.ServiceState; import android.telephony.TelephonyManager; import androidx.test.InstrumentationRegistry; @@ -163,11 +168,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { private @Mock NetworkStatsSettings mSettings; private @Mock IBinder mBinder; private @Mock AlarmManager mAlarmManager; + private @Mock TelephonyManager mTelephonyManager; private HandlerThread mHandlerThread; private NetworkStatsService mService; private INetworkStatsSession mSession; private INetworkManagementEventObserver mNetworkObserver; + @Nullable + private PhoneStateListener mPhoneStateListener; private final Clock mClock = new SimpleClock(ZoneOffset.UTC) { @Override @@ -195,7 +203,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { mHandlerThread = new HandlerThread("HandlerThread"); final NetworkStatsService.Dependencies deps = makeDependencies(); mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock, - mClock, mServiceContext.getSystemService(TelephonyManager.class), mSettings, + mClock, mTelephonyManager, mSettings, mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps); mElapsedRealtime = 0L; @@ -216,6 +224,12 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { ArgumentCaptor.forClass(INetworkManagementEventObserver.class); verify(mNetManager).registerObserver(networkObserver.capture()); mNetworkObserver = networkObserver.getValue(); + + // Capture the phone state listener that created by service. + final ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor = + ArgumentCaptor.forClass(PhoneStateListener.class); + verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(), anyInt()); + mPhoneStateListener = phoneStateListenerCaptor.getValue(); } @NonNull @@ -263,7 +277,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { incrementCurrentTime(HOUR_IN_MILLIS); expectDefaultSettings(); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L)); + .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L)); expectNetworkStatsUidDetail(buildEmptyStats()); forcePollAndWaitForIdle(); @@ -276,7 +290,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { incrementCurrentTime(DAY_IN_MILLIS); expectDefaultSettings(); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L)); + .insertEntry(TEST_IFACE, 4096L, 4L, 8192L, 8L)); expectNetworkStatsUidDetail(buildEmptyStats()); forcePollAndWaitForIdle(); @@ -306,13 +320,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { incrementCurrentTime(HOUR_IN_MILLIS); expectDefaultSettings(); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L)); + .insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L) - .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L)); mService.setUidForeground(UID_RED, false); mService.incrementOperationCount(UID_RED, 0xFAAD, 4); mService.setUidForeground(UID_RED, true); @@ -375,7 +389,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { incrementCurrentTime(2 * HOUR_IN_MILLIS); expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L)); + .insertEntry(TEST_IFACE, 512L, 4L, 512L, 4L)); expectNetworkStatsUidDetail(buildEmptyStats()); forcePollAndWaitForIdle(); @@ -415,11 +429,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { incrementCurrentTime(HOUR_IN_MILLIS); expectDefaultSettings(); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L)); + .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) + .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 10); forcePollAndWaitForIdle(); @@ -437,11 +451,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); states = new NetworkState[] {buildMobile3gState(IMSI_2)}; expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L)); + .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) + .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]); forcePollAndWaitForIdle(); @@ -451,12 +465,12 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { incrementCurrentTime(HOUR_IN_MILLIS); expectDefaultSettings(); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L)); + .insertEntry(TEST_IFACE, 2176L, 17L, 1536L, 12L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L) - .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) + .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L) + .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L)); mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10); forcePollAndWaitForIdle(); @@ -488,12 +502,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { incrementCurrentTime(HOUR_IN_MILLIS); expectDefaultSettings(); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L)); + .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) - .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L) - .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, + 4096L, 258L, 512L, 32L, 0L) + .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); mService.incrementOperationCount(UID_RED, 0xFAAD, 10); forcePollAndWaitForIdle(); @@ -509,12 +524,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // special "removed" bucket. expectDefaultSettings(); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L)); + .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L)); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) - .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L) - .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, + 4096L, 258L, 512L, 32L, 0L) + .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); final Intent intent = new Intent(ACTION_UID_REMOVED); intent.putExtra(EXTRA_UID, UID_BLUE); mServiceContext.sendBroadcast(intent); @@ -532,7 +548,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { } @Test - public void testUid3g4gCombinedByTemplate() throws Exception { + public void testUid3gWimaxCombinedByTemplate() throws Exception { // pretend that network comes online expectDefaultSettings(); NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)}; @@ -546,8 +562,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 5); forcePollAndWaitForIdle(); @@ -556,14 +572,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5); - // now switch over to 4g network + // now switch over to wimax network incrementCurrentTime(HOUR_IN_MILLIS); expectDefaultSettings(); - states = new NetworkState[] {buildMobile4gState(TEST_IFACE2)}; + states = new NetworkState[] {buildWimaxState(TEST_IFACE2)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]); forcePollAndWaitForIdle(); @@ -574,10 +590,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) - .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) - .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) + .insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) + .insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L)); mService.incrementOperationCount(UID_RED, 0xFAAD, 5); forcePollAndWaitForIdle(); @@ -587,6 +603,89 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { } @Test + public void testMobileStatsByRatType() throws Exception { + final NetworkTemplate template3g = + buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS); + final NetworkTemplate template4g = + buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_LTE); + final NetworkTemplate template5g = + buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_NR); + final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)}; + + // 3G network comes online. + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + + setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS); + mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), + new VpnInfo[0]); + + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 12L, 18L, 14L, 1L, 0L))); + forcePollAndWaitForIdle(); + + // Verify 3g templates gets stats. + assertUidTotal(sTemplateImsi1, UID_RED, 12L, 18L, 14L, 1L, 0); + assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); + assertUidTotal(template4g, UID_RED, 0L, 0L, 0L, 0L, 0); + assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0); + + // 4G network comes online. + incrementCurrentTime(MINUTE_IN_MILLIS); + setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + // Append more traffic on existing 3g stats entry. + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 16L, 22L, 17L, 2L, 0L)) + // Add entry that is new on 4g. + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, + 33L, 27L, 8L, 10L, 1L))); + forcePollAndWaitForIdle(); + + // Verify ALL_MOBILE template gets all. 3g template counters do not increase. + assertUidTotal(sTemplateImsi1, UID_RED, 49L, 49L, 25L, 12L, 1); + assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); + // Verify 4g template counts appended stats on existing entry and newly created entry. + assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1); + // Verify 5g template doesn't get anything since no traffic is generated on 5g. + assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0); + + // 5g network comes online. + incrementCurrentTime(MINUTE_IN_MILLIS); + setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + // Existing stats remains. + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 16L, 22L, 17L, 2L, 0L)) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, + 33L, 27L, 8L, 10L, 1L)) + // Add some traffic on 5g. + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 5L, 13L, 31L, 9L, 2L))); + forcePollAndWaitForIdle(); + + // Verify ALL_MOBILE template gets all. + assertUidTotal(sTemplateImsi1, UID_RED, 54L, 62L, 56L, 21L, 3); + // 3g/4g template counters do not increase. + assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); + assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1); + // Verify 5g template gets the 5g count. + assertUidTotal(template5g, UID_RED, 5L, 13L, 31L, 9L, 2); + } + + // TODO: support per IMSI state + private void setMobileRatTypeAndWaitForIdle(int ratType) { + final ServiceState mockSs = mock(ServiceState.class); + when(mockSs.getDataNetworkType()).thenReturn(ratType); + mPhoneStateListener.onServiceStateChanged(mockSs); + + HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT); + } + + @Test public void testSummaryForAllUid() throws Exception { // pretend that network comes online expectDefaultSettings(); @@ -601,9 +700,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) - .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 1); forcePollAndWaitForIdle(); @@ -618,9 +717,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) - .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, + 2048L, 16L, 1024L, 8L, 0L)); forcePollAndWaitForIdle(); // first verify entire history present @@ -664,9 +764,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) - .addEntry(entry1) - .addEntry(entry2) - .addEntry(entry3)); + .insertEntry(entry1) + .insertEntry(entry2) + .insertEntry(entry3)); mService.incrementOperationCount(UID_RED, 0xF00D, 1); NetworkStats stats = mService.getDetailedUidStats(INTERFACES_ALL); @@ -714,11 +814,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { .thenReturn(augmentedIfaceFilter); when(mStatsFactory.readNetworkStatsDetail(eq(UID_ALL), any(), eq(TAG_ALL))) .thenReturn(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(uidStats)); + .insertEntry(uidStats)); when(mNetManager.getNetworkStatsTethering(STATS_PER_UID)) .thenReturn(new NetworkStats(getElapsedRealtime(), 2) - .addEntry(tetheredStats1) - .addEntry(tetheredStats2)); + .insertEntry(tetheredStats1) + .insertEntry(tetheredStats2)); NetworkStats stats = mService.getDetailedUidStats(ifaceFilter); @@ -755,8 +855,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 1); forcePollAndWaitForIdle(); @@ -770,10 +870,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectDefaultSettings(); expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L)); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L) + .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L)); mService.setUidForeground(UID_RED, true); mService.incrementOperationCount(UID_RED, 0xFAAD, 1); @@ -814,9 +914,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer. // We layer them on top by inspecting the iface properties. expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L)); mService.incrementOperationCount(UID_RED, 0xF00D, 1); @@ -853,9 +953,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it // on top by inspecting the iface properties. expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO, + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L)); forcePollAndWaitForIdle(); @@ -888,17 +988,17 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // Traffic seen by kernel counters (includes software tethering). final NetworkStats ifaceStats = new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 1536L, 12L, 384L, 3L); + .insertEntry(TEST_IFACE, 1536L, 12L, 384L, 3L); // Hardware tethering traffic, not seen by kernel counters. final NetworkStats tetherStatsHardware = new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 512L, 4L, 128L, 1L); + .insertEntry(TEST_IFACE, 512L, 4L, 128L, 1L); // Traffic for UID_RED. final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L); + .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L); // All tethering traffic, both hardware and software. final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1) - .addEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, + .insertEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L); expectNetworkStatsSummary(ifaceStats, tetherStatsHardware); @@ -957,7 +1057,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { incrementCurrentTime(HOUR_IN_MILLIS); expectDefaultSettings(); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L)); + .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L)); expectNetworkStatsUidDetail(buildEmptyStats()); forcePollAndWaitForIdle(); @@ -972,7 +1072,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { incrementCurrentTime(DAY_IN_MILLIS); expectDefaultSettings(); expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) - .addIfaceValues(TEST_IFACE, 4096000L, 4L, 8192000L, 8L)); + .insertEntry(TEST_IFACE, 4096000L, 4L, 8192000L, 8L)); expectNetworkStatsUidDetail(buildEmptyStats()); forcePollAndWaitForIdle(); @@ -1026,18 +1126,18 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); // Verifies that one requestStatsUpdate will be called during iface update. - provider.expectStatsUpdate(0 /* unused */); + provider.expectOnRequestStatsUpdate(0 /* unused */); // Create some initial traffic and report to the service. incrementCurrentTime(HOUR_IN_MILLIS); final NetworkStats expectedStats = new NetworkStats(0L, 1) - .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L)) - .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L)); - cb.onStatsUpdated(0 /* unused */, expectedStats, expectedStats); + cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats); // Make another empty mutable stats object. This is necessary since the new NetworkStats // object will be used to compare with the old one in NetworkStatsRecoder, two of them @@ -1047,8 +1147,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { forcePollAndWaitForIdle(); // Verifies that one requestStatsUpdate and setAlert will be called during polling. - provider.expectStatsUpdate(0 /* unused */); - provider.expectSetAlert(MB_IN_BYTES); + provider.expectOnRequestStatsUpdate(0 /* unused */); + provider.expectOnSetAlert(MB_IN_BYTES); // Verifies that service recorded history, does not verify uid tag part. assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1); @@ -1082,13 +1182,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { assertNotNull(cb); // Simulates alert quota of the provider has been reached. - cb.onAlertReached(); + cb.notifyAlertReached(); HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT); // Verifies that polling is triggered by alert reached. - provider.expectStatsUpdate(0 /* unused */); + provider.expectOnRequestStatsUpdate(0 /* unused */); // Verifies that global alert will be re-armed. - provider.expectSetAlert(MB_IN_BYTES); + provider.expectOnSetAlert(MB_IN_BYTES); } private static File getBaseDir(File statsDir) { @@ -1194,6 +1294,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { when(mSettings.getPollInterval()).thenReturn(HOUR_IN_MILLIS); when(mSettings.getPollDelay()).thenReturn(0L); when(mSettings.getSampleEnabled()).thenReturn(true); + when(mSettings.getCombineSubtypeEnabled()).thenReturn(false); final Config config = new Config(bucketDuration, deleteAge, deleteAge); when(mSettings.getDevConfig()).thenReturn(config); @@ -1239,6 +1340,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { final NetworkCapabilities capabilities = new NetworkCapabilities(); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true); + capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); return new NetworkState(info, prop, capabilities, WIFI_NETWORK, null, TEST_SSID); } @@ -1256,10 +1358,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { final NetworkCapabilities capabilities = new NetworkCapabilities(); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming); + capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); return new NetworkState(info, prop, capabilities, MOBILE_NETWORK, subscriberId, null); } - private static NetworkState buildMobile4gState(String iface) { + private static NetworkState buildWimaxState(@NonNull String iface) { final NetworkInfo info = new NetworkInfo(TYPE_WIMAX, 0, null, null); info.setDetailedState(DetailedState.CONNECTED, null, null); final LinkProperties prop = new LinkProperties(); diff --git a/tools/aapt/ConfigDescription.h b/tools/aapt/ConfigDescription.h index b4ea624524b3..6e9dc3d9456a 100644 --- a/tools/aapt/ConfigDescription.h +++ b/tools/aapt/ConfigDescription.h @@ -34,8 +34,8 @@ struct ConfigDescription : public android::ResTable_config { size = sizeof(android::ResTable_config); } - ConfigDescription(const ConfigDescription&o) { - *static_cast<android::ResTable_config*>(this) = o; + ConfigDescription(const ConfigDescription&o) + : android::ResTable_config(o) { } ConfigDescription& operator=(const android::ResTable_config& o) { |