diff options
464 files changed, 8309 insertions, 4005 deletions
diff --git a/Android.bp b/Android.bp index bf6c99d0cf29..23cd1a10f8c0 100644 --- a/Android.bp +++ b/Android.bp @@ -35,22 +35,96 @@ filegroup { } // These are subset of framework-core-sources that are needed by the -// android.test.mock library. Ideally, the library should use public APIs only, -// but unfortunately its API signature has some references to these private APIs. +// android.test.mock library. The implementation of android.test.mock references +// private members of various components to allow mocking of classes that cannot +// be mocked without access to those internal implementation details. filegroup { name: "framework-core-sources-for-test-mock", srcs: [ + "core/java/android/accounts/AccountManagerCallback.java", + "core/java/android/accounts/AccountManagerFuture.java", + "core/java/android/accounts/AccountManager.java", + "core/java/android/accounts/AccountsException.java", + "core/java/android/accounts/AuthenticatorException.java", + "core/java/android/accounts/OperationCanceledException.java", + "core/java/android/annotation/AnimatorRes.java", + "core/java/android/annotation/AnimRes.java", + "core/java/android/annotation/AnyRes.java", + "core/java/android/annotation/ArrayRes.java", + "core/java/android/annotation/AttrRes.java", + "core/java/android/annotation/BoolRes.java", + "core/java/android/annotation/BroadcastBehavior.java", + "core/java/android/annotation/CallbackExecutor.java", + "core/java/android/annotation/CallSuper.java", + "core/java/android/annotation/CheckResult.java", + "core/java/android/annotation/ColorInt.java", + "core/java/android/annotation/ColorRes.java", + "core/java/android/annotation/DimenRes.java", + "core/java/android/annotation/DrawableRes.java", + "core/java/android/annotation/FontRes.java", + "core/java/android/annotation/FractionRes.java", + "core/java/android/annotation/IntDef.java", + "core/java/android/annotation/IntegerRes.java", + "core/java/android/annotation/IntRange.java", + "core/java/android/annotation/LayoutRes.java", + "core/java/android/annotation/NonNull.java", + "core/java/android/annotation/Nullable.java", + "core/java/android/annotation/PluralsRes.java", + "core/java/android/annotation/RawRes.java", + "core/java/android/annotation/RequiresPermission.java", + "core/java/android/annotation/SdkConstant.java", + "core/java/android/annotation/Size.java", + "core/java/android/annotation/StringDef.java", + "core/java/android/annotation/StringRes.java", + "core/java/android/annotation/StyleableRes.java", + "core/java/android/annotation/StyleRes.java", + "core/java/android/annotation/SuppressLint.java", + "core/java/android/annotation/SystemApi.java", + "core/java/android/annotation/SystemService.java", + "core/java/android/annotation/TestApi.java", + "core/java/android/annotation/UserIdInt.java", + "core/java/android/annotation/XmlRes.java", + "core/java/android/app/Application.java", "core/java/android/app/IApplicationThread.aidl", "core/java/android/app/IServiceConnection.aidl", + "core/java/android/app/PackageDeleteObserver.java", + "core/java/android/content/ComponentCallbacks2.java", + "core/java/android/content/ComponentCallbacks.java", + "core/java/android/content/ContentInterface.java", + "core/java/android/content/ContentProvider.java", + "core/java/android/content/ContentProviderNative.java", + "core/java/android/content/ContentResolver.java", + "core/java/android/content/Context.java", + "core/java/android/content/ContextWrapper.java", + "core/java/android/content/DialogInterface.java", "core/java/android/content/IContentProvider.java", - "core/java/android/content/pm/IPackageDataObserver.aidl", + "core/java/android/content/Intent.java", + "core/java/android/content/IntentSender.java", + "core/java/android/content/OperationApplicationException.java", + "core/java/android/content/pm/ActivityInfo.java", + "core/java/android/content/pm/ApplicationInfo.java", "core/java/android/content/pm/InstantAppInfo.java", + "core/java/android/content/pm/IPackageDataObserver.aidl", "core/java/android/content/pm/KeySet.java", "core/java/android/content/pm/PackageManager.java", "core/java/android/content/pm/VerifierDeviceIdentity.java", "core/java/android/content/res/Resources.java", + "core/java/android/database/CrossProcessCursor.java", + "core/java/android/database/CrossProcessCursorWrapper.java", + "core/java/android/database/Cursor.java", + "core/java/android/database/CursorWrapper.java", + "core/java/android/os/Binder.java", + "core/java/android/os/Bundle.java", + "core/java/android/os/IBinder.java", + "core/java/android/os/IInterface.java", + "core/java/android/os/Parcelable.java", + "core/java/android/os/ParcelFileDescriptor.java", + "core/java/android/os/RemoteException.java", "core/java/android/os/storage/VolumeInfo.java", + "core/java/android/util/AndroidException.java", "core/java/android/view/DisplayAdjustments.java", + "core/java/android/view/ViewDebug.java", + "core/java/com/android/internal/annotations/VisibleForTesting.java", ], path: "core/java", visibility: ["//frameworks/base/test-mock"], @@ -534,6 +608,7 @@ java_library { static_libs: [ "exoplayer2-extractor", "android.hardware.wifi-V1.0-java-constants", + // Additional dependencies needed to build the ike API classes. "ike-internals", ], @@ -1036,13 +1111,13 @@ python_defaults { name: "base_default", version: { py2: { - enabled: true, - embedded_launcher: true, - }, - py3: { enabled: false, embedded_launcher: false, }, + py3: { + enabled: true, + embedded_launcher: true, + }, }, } @@ -1215,6 +1290,7 @@ metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.x "--hide MissingPermission --hide BroadcastBehavior " + "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " + "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo " + + "--error NoSettingsProvider " + "--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.* " + "--api-lint-ignore-prefix android.icu. " + "--api-lint-ignore-prefix java. " + @@ -1264,4 +1340,4 @@ java_library { filegroup { name: "framework-telephony-jarjar-rules", srcs: ["telephony/framework-telephony-jarjar-rules.txt"], -} +}
\ No newline at end of file diff --git a/Android.mk b/Android.mk index d3627e118ae3..46529eb64657 100644 --- a/Android.mk +++ b/Android.mk @@ -32,10 +32,6 @@ ifneq ($(ANDROID_BUILD_EMBEDDED),true) # ============================================================ include $(CLEAR_VARS) -# This is used by ide.mk as the list of source files that are -# always included. -INTERNAL_SDK_SOURCE_DIRS := $(addprefix $(LOCAL_PATH)/,$(dirs_to_document)) - # 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 # $(OUT_DOCS)/offline-sdk. @@ -60,7 +56,7 @@ $(SDK_METADATA): .KATI_IMPLICIT_OUTPUTS := $(filter-out $(SDK_METADATA),$(SDK_ME $(SDK_METADATA): $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/framework-doc-stubs-metadata.zip rm -rf $(SDK_METADATA_DIR) mkdir -p $(SDK_METADATA_DIR) - unzip -qo $< -d $(SDK_METADATA_DIR) + unzip -DDqo $< -d $(SDK_METADATA_DIR) .PHONY: framework-doc-stubs framework-doc-stubs: $(SDK_METADATA) diff --git a/ApiDocs.bp b/ApiDocs.bp index a81342a5160f..029699efe3b9 100644 --- a/ApiDocs.bp +++ b/ApiDocs.bp @@ -320,7 +320,7 @@ droiddoc { ":framework-doc-stubs", ], args: "-noJdkLink -links https://kotlinlang.org/api/latest/jvm/stdlib/^external/dokka/package-list " + - "-noStdlibLink", + "-noStdlibLink", proofread_file: "ds-dokka-proofread.txt", dokka_enabled: true, } @@ -340,7 +340,7 @@ java_genrule { targets: ["docs"], }, cmd: "$(location zip2zip) -i $(location :ds-docs-kt{.docs.zip}) -o $(genDir)/ds-docs-kt-moved.zip **/*:en/reference/kotlin && " + - "$(location merge_zips) $(out) $(location :ds-docs-java{.docs.zip}) $(genDir)/ds-docs-kt-moved.zip", + "$(location merge_zips) $(out) $(location :ds-docs-java{.docs.zip}) $(genDir)/ds-docs-kt-moved.zip", } java_genrule { @@ -357,11 +357,11 @@ java_genrule { dist: { targets: ["docs"], }, - cmd: "unzip $(location :ds-docs-java{.docs.zip}) -d $(genDir) && " + - "unzip $(location :ds-docs-kt{.docs.zip}) -d $(genDir)/en/reference/kotlin && " + - "SWITCHER=$$(cd $$(dirname $(location switcher4)) && pwd)/$$(basename $(location switcher4)) && " + - "(cd $(genDir)/en/reference && $$SWITCHER --work platform) && " + - "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)", + cmd: "unzip -q $(location :ds-docs-java{.docs.zip}) -d $(genDir) && " + + "unzip -q $(location :ds-docs-kt{.docs.zip}) -d $(genDir)/en/reference/kotlin && " + + "SWITCHER=$$(cd $$(dirname $(location switcher4)) && pwd)/$$(basename $(location switcher4)) && " + + "(cd $(genDir)/en/reference && $$SWITCHER --work platform) > /dev/null && " + + "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)", } droiddoc { @@ -373,7 +373,6 @@ droiddoc { hdf: [ "android.whichdoc online", ], - proofread_file: "ds-static-docs-proofrerad.txt", args: framework_docs_only_args + " -staticonly " + " -toroot / " + @@ -390,7 +389,6 @@ droiddoc { hdf: [ "android.whichdoc online", ], - proofread_file: "ds-ref-navtree-docs-proofrerad.txt", args: framework_docs_only_args + " -toroot / " + " -atLinksNavtree " + @@ -437,4 +435,3 @@ droiddoc { " -referenceonly " + " -title \"Android SDK - Including hidden APIs.\"", } - diff --git a/METADATA b/METADATA new file mode 100644 index 000000000000..d97975ca3b99 --- /dev/null +++ b/METADATA @@ -0,0 +1,3 @@ +third_party { + license_type: NOTICE +} diff --git a/StubLibraries.bp b/StubLibraries.bp index ef4e202fdfe2..a9e6e5af47f1 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -49,6 +49,7 @@ stubs_defaults { ":opt-net-voip-srcs", ":art-module-public-api-stubs-source", ":android_icu4j_public_api_files", + "**/package.html", ], // TODO(b/147699819): remove below aidl includes. aidl: { @@ -154,6 +155,9 @@ priv_apps = " " + module_libs = " " + " --show-annotation android.annotation.SystemApi\\(" + "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" + + "\\)" + + " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + "\\) " droidstubs { @@ -231,21 +235,19 @@ droidstubs { } ///////////////////////////////////////////////////////////////////// -// Following droidstubs modules are for extra APIs for modules. -// The framework currently have two more API surfaces for modules: -// @SystemApi(client=MODULE_APPS) and @SystemApi(client=MODULE_LIBRARIES) +// Following droidstubs modules are for extra APIs for modules, +// namely @SystemApi(client=MODULE_LIBRARIES) APIs. ///////////////////////////////////////////////////////////////////// -// TODO(b/146727827) remove the *-api module when we can teach metalava -// about the relationship among the API surfaces. Currently, these modules are only to generate -// the API signature files and ensure that the APIs evolve in a backwards compatible manner. -// They however are NOT used for building the API stub. - droidstubs { name: "module-lib-api", defaults: ["metalava-full-api-stubs-default"], arg_files: ["core/res/AndroidManifest.xml"], args: metalava_framework_docs_args + module_libs, + + // Do not generate stubs as they are not needed + generate_stubs: false, + check_api: { current: { api_file: "api/module-lib-current.txt", @@ -273,7 +275,7 @@ droidstubs { name: "module-lib-api-stubs-docs-non-updatable", defaults: ["metalava-non-updatable-api-stubs-default"], arg_files: ["core/res/AndroidManifest.xml"], - args: metalava_framework_docs_args + module_libs, + args: metalava_framework_docs_args + priv_apps + module_libs, check_api: { current: { api_file: "non-updatable-api/module-lib-current.txt", @@ -286,17 +288,6 @@ droidstubs { }, } -// The following droidstub module generates source files for the API stub library for -// modules. Note that it not only includes its own APIs but also other APIs that have -// narrower scope (all @SystemApis, not just the ones with 'client=MODULE_LIBRARIES'). - -droidstubs { - name: "module-lib-api-stubs-docs", - defaults: ["metalava-non-updatable-api-stubs-default"], - arg_files: ["core/res/AndroidManifest.xml"], - args: metalava_framework_docs_args + priv_apps + module_libs, -} - ///////////////////////////////////////////////////////////////////// // android_*_stubs_current modules are the stubs libraries compiled // from *-api-stubs-docs @@ -305,12 +296,15 @@ droidstubs { java_defaults { name: "android_defaults_stubs_current", libs: [ "stub-annotations" ], + static_libs: [ + // License notices from art module + "art-notices-for-framework-stubs-jar", + ], errorprone: { javacflags: [ "-XepDisableAllChecks", ], }, - java_resources: [":notices-for-framework-stubs"], sdk_version: "none", system_modules: "none", java_version: "1.8", @@ -386,7 +380,7 @@ java_library_static { java_library_static { name: "android_module_lib_stubs_current", - srcs: [ ":module-lib-api-stubs-docs" ], + srcs: [ ":module-lib-api-stubs-docs-non-updatable" ], defaults: ["android_defaults_stubs_current"], libs: ["sdk_system_29_android"], } diff --git a/apct-tests/perftests/core/jni/Android.bp b/apct-tests/perftests/core/jni/Android.bp index 4c0f2aaba145..d160d48538c3 100644 --- a/apct-tests/perftests/core/jni/Android.bp +++ b/apct-tests/perftests/core/jni/Android.bp @@ -10,4 +10,5 @@ cc_library_shared { "-Wunused", "-Wunreachable-code", ], + header_libs: ["jni_headers"], } diff --git a/apex/Android.bp b/apex/Android.bp index 992648b04ef0..41561fe72c50 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -53,6 +53,9 @@ priv_apps = " " + module_libs = " " + " --show-annotation android.annotation.SystemApi\\(" + "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" + + "\\)" + + " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + "\\) " mainline_service_stubs_args = @@ -76,6 +79,10 @@ java_defaults { // entry. shared_library: false, + // Prevent dependencies that do not specify an sdk_version from accessing the + // implementation library by default and force them to use stubs instead. + default_to_stubs: true, + // Enable api lint. This will eventually become the default for java_sdk_library // but it cannot yet be turned on because some usages have not been cleaned up. // TODO(b/156126315) - Remove when no longer needed. @@ -246,6 +253,10 @@ stubs_defaults { "metalava-manual", ], filter_packages: framework_packages_to_document, + + // Do not generate stubs as they are not needed + generate_stubs: false, + check_api: { current: { api_file: "api/module-lib-current.txt", diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp index d19faa97e223..b06f4019b480 100644 --- a/apex/statsd/framework/Android.bp +++ b/apex/statsd/framework/Android.bp @@ -31,7 +31,8 @@ java_library_static { ], visibility: [ "//cts/hostsidetests/statsd/apps:__subpackages__", - ] + "//vendor:__subpackages__", + ], } filegroup { diff --git a/api/current.txt b/api/current.txt index 952ccdad992c..8dc7ef45b277 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3712,7 +3712,7 @@ package android.app { ctor public ActionBar.LayoutParams(int); ctor public ActionBar.LayoutParams(android.app.ActionBar.LayoutParams); ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams); - field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=0xffffffff, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.NO_GRAVITY, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.TOP, to="TOP"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.BOTTOM, to="BOTTOM"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.LEFT, to="LEFT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.RIGHT, to="RIGHT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.START, to="START"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.END, to="END"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_VERTICAL, to="CENTER_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_VERTICAL, to="FILL_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_HORIZONTAL, to="CENTER_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_HORIZONTAL, to="FILL_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL, to="FILL")}) public int gravity; + field public int gravity; } public static interface ActionBar.OnMenuVisibilityListener { @@ -10092,7 +10092,7 @@ package android.content { method public final <T> T getSystemService(@NonNull Class<T>); method @Nullable public abstract String getSystemServiceName(@NonNull Class<?>); method @NonNull public final CharSequence getText(@StringRes int); - method @android.view.ViewDebug.ExportedProperty(deepExport=true) public abstract android.content.res.Resources.Theme getTheme(); + method public abstract android.content.res.Resources.Theme getTheme(); method @Deprecated public abstract android.graphics.drawable.Drawable getWallpaper(); method @Deprecated public abstract int getWallpaperDesiredMinimumHeight(); method @Deprecated public abstract int getWallpaperDesiredMinimumWidth(); @@ -11945,7 +11945,7 @@ package android.content.pm { } public abstract class PackageManager { - ctor public PackageManager(); + ctor @Deprecated public PackageManager(); method @Deprecated public abstract void addPackageToPreferred(@NonNull String); method public abstract boolean addPermission(@NonNull android.content.pm.PermissionInfo); method public abstract boolean addPermissionAsync(@NonNull android.content.pm.PermissionInfo); @@ -35809,6 +35809,7 @@ package android.os { field public static final String PRODUCT; field @Deprecated public static final String RADIO; field @Deprecated public static final String SERIAL; + field @NonNull public static final String SKU; field public static final String[] SUPPORTED_32_BIT_ABIS; field public static final String[] SUPPORTED_64_BIT_ABIS; field public static final String[] SUPPORTED_ABIS; @@ -42744,6 +42745,7 @@ package android.security.keystore { method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationType(); method public int getUserAuthenticationValidityDurationSeconds(); + method public boolean isDevicePropertiesAttestationIncluded(); method @NonNull public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); method public boolean isRandomizedEncryptionRequired(); @@ -42765,6 +42767,7 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(@NonNull java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSerialNumber(@NonNull java.math.BigInteger); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSubject(@NonNull javax.security.auth.x500.X500Principal); + method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDevicePropertiesAttestationIncluded(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDigests(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setInvalidatedByBiometricEnrollment(boolean); @@ -47001,7 +47004,7 @@ package android.telephony { public abstract class CellLocation { ctor public CellLocation(); method public static android.telephony.CellLocation getEmpty(); - method public static void requestLocationUpdate(); + method @Deprecated public static void requestLocationUpdate(); } public abstract class CellSignalStrength { @@ -47448,6 +47451,88 @@ package android.telephony { field public static final int VSNCP_TIMEOUT = 2236; // 0x8bc } + 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_CALL_OVER_WFC_NOT_AVAILABLE = 78; // 0x4e + 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 MEDIA_TIMEOUT = 77; // 0x4d + 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 WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 79; // 0x4f + field public static final int WIFI_LOST = 59; // 0x3b + } + public class IccOpenLogicalChannelResponse implements android.os.Parcelable { method public int describeContents(); method public int getChannel(); @@ -47464,12 +47549,14 @@ package android.telephony { public class MbmsDownloadSession implements java.lang.AutoCloseable { method public void addProgressListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.DownloadProgressListener); + method public void addServiceAnnouncement(@NonNull byte[]); method public void addStatusListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.DownloadStatusListener); method public void cancelDownload(@NonNull android.telephony.mbms.DownloadRequest); method public void close(); method public static android.telephony.MbmsDownloadSession create(@NonNull android.content.Context, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.MbmsDownloadSessionCallback); method @Nullable public static android.telephony.MbmsDownloadSession create(@NonNull android.content.Context, @NonNull java.util.concurrent.Executor, int, @NonNull android.telephony.mbms.MbmsDownloadSessionCallback); method public void download(@NonNull android.telephony.mbms.DownloadRequest); + method public static int getMaximumServiceAnnouncementSize(); method @Nullable public java.io.File getTempFileRootDirectory(); method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(); method public void removeProgressListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull android.telephony.mbms.DownloadProgressListener); @@ -47917,6 +48004,7 @@ package android.telephony { method public static int[] calculateLength(String, boolean); method @Deprecated public static android.telephony.SmsMessage createFromPdu(byte[]); method public static android.telephony.SmsMessage createFromPdu(byte[], String); + method @Nullable public static android.telephony.SmsMessage createSmsSubmitPdu(@NonNull byte[], boolean); method public String getDisplayMessageBody(); method public String getDisplayOriginatingAddress(); method public String getEmailBody(); @@ -47999,7 +48087,7 @@ package android.telephony { public class SubscriptionManager { method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); - method public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); + method @Deprecated public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); method public void addOnSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void addSubscriptionsIntoGroup(@NonNull java.util.List<java.lang.Integer>, @NonNull android.os.ParcelUuid); method public boolean canManageSubscription(android.telephony.SubscriptionInfo); @@ -49080,6 +49168,7 @@ package android.telephony.mbms { public static class MbmsErrors.DownloadErrors { field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191 + field public static final int ERROR_MALFORMED_SERVICE_ANNOUNCEMENT = 404; // 0x194 field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192 field public static final int ERROR_UNKNOWN_FILE_INFO = 403; // 0x193 } @@ -53838,13 +53927,13 @@ package android.view { method @Nullable public CharSequence getAccessibilityPaneTitle(); method @IdRes public int getAccessibilityTraversalAfter(); method @IdRes public int getAccessibilityTraversalBefore(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getAlpha(); + method public float getAlpha(); method public android.view.animation.Animation getAnimation(); method @Nullable public android.graphics.Matrix getAnimationMatrix(); method public android.os.IBinder getApplicationWindowToken(); method @NonNull public int[] getAttributeResolutionStack(@AttrRes int); method @NonNull public java.util.Map<java.lang.Integer,java.lang.Integer> getAttributeSourceResourceMap(); - method @android.view.ViewDebug.ExportedProperty @Nullable public String[] getAutofillHints(); + method @Nullable public String[] getAutofillHints(); method public final android.view.autofill.AutofillId getAutofillId(); method public int getAutofillType(); method @Nullable public android.view.autofill.AutofillValue getAutofillValue(); @@ -53852,8 +53941,8 @@ package android.view { method @Nullable public android.graphics.BlendMode getBackgroundTintBlendMode(); method @Nullable public android.content.res.ColorStateList getBackgroundTintList(); method @Nullable public android.graphics.PorterDuff.Mode getBackgroundTintMode(); - method @android.view.ViewDebug.ExportedProperty(category="layout") public int getBaseline(); - method @android.view.ViewDebug.CapturedViewProperty public final int getBottom(); + method public int getBaseline(); + method public final int getBottom(); method protected float getBottomFadingEdgeStrength(); method protected int getBottomPaddingOffset(); method public float getCameraDistance(); @@ -53861,10 +53950,10 @@ package android.view { method public boolean getClipBounds(android.graphics.Rect); method public final boolean getClipToOutline(); method @Nullable public final android.view.contentcapture.ContentCaptureSession getContentCaptureSession(); - method @android.view.ViewDebug.ExportedProperty(category="accessibility") public CharSequence getContentDescription(); - method @android.view.ViewDebug.CapturedViewProperty public final android.content.Context getContext(); + method public CharSequence getContentDescription(); + method public final android.content.Context getContext(); method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean getDefaultFocusHighlightEnabled(); + method public final boolean getDefaultFocusHighlightEnabled(); method public static int getDefaultSize(int, int); method public android.view.Display getDisplay(); method public final int[] getDrawableState(); @@ -53874,11 +53963,11 @@ package android.view { method @Deprecated public int getDrawingCacheQuality(); method public void getDrawingRect(android.graphics.Rect); method public long getDrawingTime(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getElevation(); + method public float getElevation(); method @StyleRes public int getExplicitStyle(); - method @android.view.ViewDebug.ExportedProperty public boolean getFilterTouchesWhenObscured(); - method @android.view.ViewDebug.ExportedProperty public boolean getFitsSystemWindows(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.NOT_FOCUSABLE, to="NOT_FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE, to="FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE_AUTO, to="FOCUSABLE_AUTO")}, category="focus") public int getFocusable(); + method public boolean getFilterTouchesWhenObscured(); + method public boolean getFitsSystemWindows(); + method public int getFocusable(); method public java.util.ArrayList<android.view.View> getFocusables(int); method public void getFocusedRect(android.graphics.Rect); method public android.graphics.drawable.Drawable getForeground(); @@ -53890,23 +53979,23 @@ package android.view { method public final boolean getGlobalVisibleRect(android.graphics.Rect); method public android.os.Handler getHandler(); method public final boolean getHasOverlappingRendering(); - method @android.view.ViewDebug.ExportedProperty(category="layout") public final int getHeight(); + method public final int getHeight(); method public void getHitRect(android.graphics.Rect); method public int getHorizontalFadingEdgeLength(); method protected int getHorizontalScrollbarHeight(); method @Nullable public android.graphics.drawable.Drawable getHorizontalScrollbarThumbDrawable(); method @Nullable public android.graphics.drawable.Drawable getHorizontalScrollbarTrackDrawable(); - method @android.view.ViewDebug.CapturedViewProperty @IdRes public int getId(); - method @android.view.ViewDebug.ExportedProperty(category="accessibility", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS, to="noHideDescendants")}) public int getImportantForAccessibility(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForAutofill(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForContentCapture(); + method @IdRes public int getId(); + method public int getImportantForAccessibility(); + method public int getImportantForAutofill(); + method public int getImportantForContentCapture(); method public boolean getKeepScreenOn(); method public android.view.KeyEvent.DispatcherState getKeyDispatcherState(); - method @android.view.ViewDebug.ExportedProperty(category="accessibility") @IdRes public int getLabelFor(); + method @IdRes public int getLabelFor(); method public int getLayerType(); - method @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.LAYOUT_DIRECTION_LTR, to="RESOLVED_DIRECTION_LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.LAYOUT_DIRECTION_RTL, to="RESOLVED_DIRECTION_RTL")}) public int getLayoutDirection(); - method @android.view.ViewDebug.ExportedProperty(deepExport=true, prefix="layout_") public android.view.ViewGroup.LayoutParams getLayoutParams(); - method @android.view.ViewDebug.CapturedViewProperty public final int getLeft(); + method public int getLayoutDirection(); + method public android.view.ViewGroup.LayoutParams getLayoutParams(); + method public final int getLeft(); method protected float getLeftFadingEdgeStrength(); method protected int getLeftPaddingOffset(); method public final boolean getLocalVisibleRect(android.graphics.Rect); @@ -53915,10 +54004,10 @@ package android.view { method public void getLocationOnScreen(@Size(2) int[]); method public android.graphics.Matrix getMatrix(); method public final int getMeasuredHeight(); - method @android.view.ViewDebug.ExportedProperty(category="measurement", flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.View.MEASURED_STATE_MASK, equals=android.view.View.MEASURED_STATE_TOO_SMALL, name="MEASURED_STATE_TOO_SMALL")}) public final int getMeasuredHeightAndState(); + method public final int getMeasuredHeightAndState(); method public final int getMeasuredState(); method public final int getMeasuredWidth(); - method @android.view.ViewDebug.ExportedProperty(category="measurement", flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.View.MEASURED_STATE_MASK, equals=android.view.View.MEASURED_STATE_TOO_SMALL, name="MEASURED_STATE_TOO_SMALL")}) public final int getMeasuredWidthAndState(); + method public final int getMeasuredWidthAndState(); method public int getMinimumHeight(); method public int getMinimumWidth(); method @IdRes public int getNextClusterForwardId(); @@ -53941,51 +54030,51 @@ package android.view { method public int getPaddingTop(); method public final android.view.ViewParent getParent(); method public android.view.ViewParent getParentForAccessibility(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getPivotX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getPivotY(); + method public float getPivotX(); + method public float getPivotY(); method public android.view.PointerIcon getPointerIcon(); method public android.content.res.Resources getResources(); method public final boolean getRevealOnFocusHint(); - method @android.view.ViewDebug.CapturedViewProperty public final int getRight(); + method public final int getRight(); method protected float getRightFadingEdgeStrength(); method protected int getRightPaddingOffset(); method public android.view.View getRootView(); method public android.view.WindowInsets getRootWindowInsets(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotation(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotationX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotationY(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getScaleX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getScaleY(); + method public float getRotation(); + method public float getRotationX(); + method public float getRotationY(); + method public float getScaleX(); + method public float getScaleY(); method public int getScrollBarDefaultDelayBeforeFade(); method public int getScrollBarFadeDuration(); method public int getScrollBarSize(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_INSIDE_OVERLAY, to="INSIDE_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_INSIDE_INSET, to="INSIDE_INSET"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_OUTSIDE_OVERLAY, to="OUTSIDE_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_OUTSIDE_INSET, to="OUTSIDE_INSET")}) public int getScrollBarStyle(); + method public int getScrollBarStyle(); method public int getScrollIndicators(); method public final int getScrollX(); method public final int getScrollY(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") @ColorInt public int getSolidColor(); + method @ColorInt public int getSolidColor(); method @LayoutRes public int getSourceLayoutResId(); - method @android.view.ViewDebug.ExportedProperty(category="accessibility") @Nullable public final CharSequence getStateDescription(); + method @Nullable public final CharSequence getStateDescription(); method public android.animation.StateListAnimator getStateListAnimator(); method protected int getSuggestedMinimumHeight(); method protected int getSuggestedMinimumWidth(); method @NonNull public java.util.List<android.graphics.Rect> getSystemGestureExclusionRects(); method @Deprecated public int getSystemUiVisibility(); - method @android.view.ViewDebug.ExportedProperty public Object getTag(); + method public Object getTag(); method public Object getTag(int); - method @android.view.ViewDebug.ExportedProperty(category="text", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_INHERIT, to="INHERIT"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_GRAVITY, to="GRAVITY"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_TEXT_START, to="TEXT_START"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_TEXT_END, to="TEXT_END"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_VIEW_START, to="VIEW_START"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_VIEW_END, to="VIEW_END")}) public int getTextAlignment(); - method @android.view.ViewDebug.ExportedProperty(category="text", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_INHERIT, to="INHERIT"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG, to="FIRST_STRONG"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_ANY_RTL, to="ANY_RTL"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_LTR, to="LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_RTL, to="RTL"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_LOCALE, to="LOCALE"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG_LTR, to="FIRST_STRONG_LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG_RTL, to="FIRST_STRONG_RTL")}) public int getTextDirection(); + method public int getTextAlignment(); + method public int getTextDirection(); method @Nullable public CharSequence getTooltipText(); - method @android.view.ViewDebug.CapturedViewProperty public final int getTop(); + method public final int getTop(); method protected float getTopFadingEdgeStrength(); method protected int getTopPaddingOffset(); method public android.view.TouchDelegate getTouchDelegate(); method public java.util.ArrayList<android.view.View> getTouchables(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTransitionAlpha(); - method @android.view.ViewDebug.ExportedProperty public String getTransitionName(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationY(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationZ(); + method public float getTransitionAlpha(); + method public String getTransitionName(); + method public float getTranslationX(); + method public float getTranslationY(); + method public float getTranslationZ(); method public long getUniqueDrawingId(); method public int getVerticalFadingEdgeLength(); method public int getVerticalScrollbarPosition(); @@ -53993,8 +54082,8 @@ package android.view { method @Nullable public android.graphics.drawable.Drawable getVerticalScrollbarTrackDrawable(); method public int getVerticalScrollbarWidth(); method public android.view.ViewTreeObserver getViewTreeObserver(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.VISIBLE, to="VISIBLE"), @android.view.ViewDebug.IntToString(from=android.view.View.INVISIBLE, to="INVISIBLE"), @android.view.ViewDebug.IntToString(from=android.view.View.GONE, to="GONE")}) public int getVisibility(); - method @android.view.ViewDebug.ExportedProperty(category="layout") public final int getWidth(); + method public int getVisibility(); + method public final int getWidth(); method protected int getWindowAttachCount(); method public android.view.WindowId getWindowId(); method @Nullable public android.view.WindowInsetsController getWindowInsetsController(); @@ -54002,18 +54091,18 @@ package android.view { method public android.os.IBinder getWindowToken(); method public int getWindowVisibility(); method public void getWindowVisibleDisplayFrame(android.graphics.Rect); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getY(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getZ(); + method public float getX(); + method public float getY(); + method public float getZ(); method public boolean hasExplicitFocusable(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean hasFocus(); + method public boolean hasFocus(); method public boolean hasFocusable(); method public boolean hasNestedScrollingParent(); method public boolean hasOnClickListeners(); method public boolean hasOnLongClickListeners(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean hasOverlappingRendering(); + method public boolean hasOverlappingRendering(); method public boolean hasPointerCapture(); - method @android.view.ViewDebug.ExportedProperty(category="layout") public boolean hasTransientState(); + method public boolean hasTransientState(); method public boolean hasWindowFocus(); method public static android.view.View inflate(android.content.Context, @LayoutRes int, android.view.ViewGroup); method @Deprecated public void invalidate(android.graphics.Rect); @@ -54023,50 +54112,50 @@ package android.view { method public void invalidateOutline(); method public boolean isAccessibilityFocused(); method public boolean isAccessibilityHeading(); - method @android.view.ViewDebug.ExportedProperty public boolean isActivated(); + method public boolean isActivated(); method public boolean isAttachedToWindow(); - method @android.view.ViewDebug.ExportedProperty public boolean isClickable(); + method public boolean isClickable(); method public boolean isContextClickable(); method public boolean isDirty(); - method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isDrawingCacheEnabled(); + method @Deprecated public boolean isDrawingCacheEnabled(); method public boolean isDuplicateParentStateEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isEnabled(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusable(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusableInTouchMode(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean isFocused(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusedByDefault(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isForceDarkAllowed(); - method @android.view.ViewDebug.ExportedProperty public boolean isHapticFeedbackEnabled(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isHardwareAccelerated(); + method public boolean isEnabled(); + method public final boolean isFocusable(); + method public final boolean isFocusableInTouchMode(); + method public boolean isFocused(); + method public final boolean isFocusedByDefault(); + method public boolean isForceDarkAllowed(); + method public boolean isHapticFeedbackEnabled(); + method public boolean isHardwareAccelerated(); method public boolean isHorizontalFadingEdgeEnabled(); method public boolean isHorizontalScrollBarEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isHovered(); + method public boolean isHovered(); method public boolean isImportantForAccessibility(); method public final boolean isImportantForAutofill(); method public final boolean isImportantForContentCapture(); method public boolean isInEditMode(); method public boolean isInLayout(); - method @android.view.ViewDebug.ExportedProperty public boolean isInTouchMode(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isKeyboardNavigationCluster(); + method public boolean isInTouchMode(); + method public final boolean isKeyboardNavigationCluster(); method public boolean isLaidOut(); method public boolean isLayoutDirectionResolved(); method public boolean isLayoutRequested(); method public boolean isLongClickable(); method public boolean isNestedScrollingEnabled(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isOpaque(); + method public boolean isOpaque(); method protected boolean isPaddingOffsetRequired(); method public boolean isPaddingRelative(); method public boolean isPivotSet(); - method @android.view.ViewDebug.ExportedProperty public boolean isPressed(); + method public boolean isPressed(); method public boolean isSaveEnabled(); method public boolean isSaveFromParentEnabled(); method public boolean isScreenReaderFocusable(); method public boolean isScrollContainer(); method public boolean isScrollbarFadingEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isSelected(); + method public boolean isSelected(); method public final boolean isShowingLayoutBounds(); method public boolean isShown(); - method @android.view.ViewDebug.ExportedProperty public boolean isSoundEffectsEnabled(); + method public boolean isSoundEffectsEnabled(); method public final boolean isTemporarilyDetached(); method public boolean isTextAlignmentResolved(); method public boolean isTextDirectionResolved(); @@ -54357,8 +54446,8 @@ package android.view { method public void unscheduleDrawable(android.graphics.drawable.Drawable); method public final void updateDragShadow(android.view.View.DragShadowBuilder); method @CallSuper protected boolean verifyDrawable(@NonNull android.graphics.drawable.Drawable); - method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean willNotCacheDrawing(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean willNotDraw(); + method @Deprecated public boolean willNotCacheDrawing(); + method public boolean willNotDraw(); field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2 field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0 field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1 @@ -54799,9 +54888,9 @@ package android.view { method public static int getChildMeasureSpec(int, int, int); method protected boolean getChildStaticTransformation(android.view.View, android.view.animation.Transformation); method public boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean getClipChildren(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean getClipToPadding(); - method @android.view.ViewDebug.ExportedProperty(category="focus", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_BEFORE_DESCENDANTS, to="FOCUS_BEFORE_DESCENDANTS"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_AFTER_DESCENDANTS, to="FOCUS_AFTER_DESCENDANTS"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_BLOCK_DESCENDANTS, to="FOCUS_BLOCK_DESCENDANTS")}) public int getDescendantFocusability(); + method public boolean getClipChildren(); + method public boolean getClipToPadding(); + method public int getDescendantFocusability(); method public android.view.View getFocusedChild(); method public android.view.animation.LayoutAnimationController getLayoutAnimation(); method public android.view.animation.Animation.AnimationListener getLayoutAnimationListener(); @@ -54809,14 +54898,14 @@ package android.view { method public android.animation.LayoutTransition getLayoutTransition(); method public int getNestedScrollAxes(); method public android.view.ViewGroupOverlay getOverlay(); - method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_NO_CACHE, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_ANIMATION_CACHE, to="ANIMATION"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_SCROLLING_CACHE, to="SCROLLING"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_ALL_CACHES, to="ALL")}) public int getPersistentDrawingCache(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean getTouchscreenBlocksFocus(); + method @Deprecated public int getPersistentDrawingCache(); + method public boolean getTouchscreenBlocksFocus(); method public int indexOfChild(android.view.View); method @Deprecated public final void invalidateChild(android.view.View, android.graphics.Rect); method @Deprecated public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect); method @Deprecated public boolean isAlwaysDrawnWithCacheEnabled(); method @Deprecated public boolean isAnimationCacheEnabled(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") protected boolean isChildrenDrawingOrderEnabled(); + method protected boolean isChildrenDrawingOrderEnabled(); method @Deprecated protected boolean isChildrenDrawnWithCacheEnabled(); method public boolean isLayoutSuppressed(); method public boolean isMotionEventSplittingEnabled(); @@ -54907,9 +54996,9 @@ package android.view { field @Deprecated public static final int FILL_PARENT = -1; // 0xffffffff field public static final int MATCH_PARENT = -1; // 0xffffffff field public static final int WRAP_CONTENT = -2; // 0xfffffffe - field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.MATCH_PARENT, to="MATCH_PARENT"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.WRAP_CONTENT, to="WRAP_CONTENT")}) public int height; + field public int height; field public android.view.animation.LayoutAnimationController.AnimationParameters layoutAnimationParameters; - field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.MATCH_PARENT, to="MATCH_PARENT"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.WRAP_CONTENT, to="WRAP_CONTENT")}) public int width; + field public int width; } public static class ViewGroup.MarginLayoutParams extends android.view.ViewGroup.LayoutParams { @@ -54925,10 +55014,10 @@ package android.view { method public void setMarginEnd(int); method public void setMarginStart(int); method public void setMargins(int, int, int, int); - field @android.view.ViewDebug.ExportedProperty(category="layout") public int bottomMargin; - field @android.view.ViewDebug.ExportedProperty(category="layout") public int leftMargin; - field @android.view.ViewDebug.ExportedProperty(category="layout") public int rightMargin; - field @android.view.ViewDebug.ExportedProperty(category="layout") public int topMargin; + field public int bottomMargin; + field public int leftMargin; + field public int rightMargin; + field public int topMargin; } public static interface ViewGroup.OnHierarchyChangeListener { @@ -55725,11 +55814,11 @@ package android.view { field public float alpha; field public float buttonBrightness; field public float dimAmount; - field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, name="ALLOW_LOCK_WHILE_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND, equals=android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND, name="DIM_BEHIND"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND, equals=android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND, name="BLUR_BEHIND"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, name="NOT_FOCUSABLE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, name="NOT_TOUCHABLE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, name="NOT_TOUCH_MODAL"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, equals=android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, name="TOUCHABLE_WHEN_WAKING"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, name="KEEP_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, name="LAYOUT_IN_SCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, name="LAYOUT_NO_LIMITS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN, name="FULLSCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, name="FORCE_NOT_FULLSCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DITHER, equals=android.view.WindowManager.LayoutParams.FLAG_DITHER, name="DITHER"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SECURE, equals=android.view.WindowManager.LayoutParams.FLAG_SECURE, name="SECURE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SCALED, equals=android.view.WindowManager.LayoutParams.FLAG_SCALED, name="SCALED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, equals=android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, name="IGNORE_CHEEK_PRESSES"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, name="LAYOUT_INSET_DECOR"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, equals=android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, name="ALT_FOCUSABLE_IM"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, equals=android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, name="WATCH_OUTSIDE_TOUCH"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, equals=android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, name="SHOW_WHEN_LOCKED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER, equals=android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER, name="SHOW_WALLPAPER"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, name="TURN_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, equals=android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, name="DISMISS_KEYGUARD"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, equals=android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, name="SPLIT_TOUCH"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, equals=android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, name="HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN, name="LOCAL_FOCUS_MODE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, equals=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, name="TRANSLUCENT_STATUS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, equals=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, name="TRANSLUCENT_NAVIGATION"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE, equals=android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE, name="LOCAL_FOCUS_MODE"), @android.view.ViewDebug.FlagToString(mask=0x20000000, equals=0x20000000, name="FLAG_SLIPPERY"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR, name="FLAG_LAYOUT_ATTACHED_IN_DECOR"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, equals=android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, name="DRAWS_SYSTEM_BAR_BACKGROUNDS")}, formatToHexString=true) public int flags; + field public int flags; field public int format; field public int gravity; field public float horizontalMargin; - field @android.view.ViewDebug.ExportedProperty public float horizontalWeight; + field public float horizontalWeight; field public int layoutInDisplayCutoutMode; field @Deprecated public int memoryType; field public String packageName; @@ -55742,12 +55831,12 @@ package android.view { field public int softInputMode; field @Deprecated public int systemUiVisibility; field public android.os.IBinder token; - field @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION, to="BASE_APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION, to="APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING, to="APPLICATION_STARTING"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION, to="DRAWN_APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, to="APPLICATION_PANEL"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA, to="APPLICATION_MEDIA"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, to="APPLICATION_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=0x3ed, to="APPLICATION_ABOVE_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG, to="APPLICATION_ATTACHED_DIALOG"), @android.view.ViewDebug.IntToString(from=0x3ec, to="APPLICATION_MEDIA_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR, to="STATUS_BAR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR, to="SEARCH_BAR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PHONE, to="PHONE"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, to="SYSTEM_ALERT"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_TOAST, to="TOAST"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, to="SYSTEM_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE, to="PRIORITY_PHONE"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG, to="SYSTEM_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, to="KEYGUARD_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, to="SYSTEM_ERROR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD, to="INPUT_METHOD"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG, to="INPUT_METHOD_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_WALLPAPER, to="WALLPAPER"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, to="STATUS_BAR_PANEL"), @android.view.ViewDebug.IntToString(from=0x7df, to="SECURE_SYSTEM_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7e0, to="DRAG"), @android.view.ViewDebug.IntToString(from=0x7e1, to="STATUS_BAR_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=0x7e2, to="POINTER"), @android.view.ViewDebug.IntToString(from=0x7e3, to="NAVIGATION_BAR"), @android.view.ViewDebug.IntToString(from=0x7e4, to="VOLUME_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7e5, to="BOOT_PROGRESS"), @android.view.ViewDebug.IntToString(from=0x7e6, to="INPUT_CONSUMER"), @android.view.ViewDebug.IntToString(from=0x7e8, to="NAVIGATION_BAR_PANEL"), @android.view.ViewDebug.IntToString(from=0x7ea, to="DISPLAY_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7eb, to="MAGNIFICATION_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7f5, to="PRESENTATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION, to="PRIVATE_PRESENTATION"), @android.view.ViewDebug.IntToString(from=0x7ef, to="VOICE_INTERACTION"), @android.view.ViewDebug.IntToString(from=0x7f1, to="VOICE_INTERACTION_STARTING"), @android.view.ViewDebug.IntToString(from=0x7f2, to="DOCK_DIVIDER"), @android.view.ViewDebug.IntToString(from=0x7f3, to="QS_DIALOG"), @android.view.ViewDebug.IntToString(from=0x7f4, to="SCREENSHOT"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, to="APPLICATION_OVERLAY")}) public int type; + field public int type; field public float verticalMargin; - field @android.view.ViewDebug.ExportedProperty public float verticalWeight; + field public float verticalWeight; field public int windowAnimations; - field @android.view.ViewDebug.ExportedProperty public int x; - field @android.view.ViewDebug.ExportedProperty public int y; + field public int x; + field public int y; } public final class WindowMetrics { @@ -58484,21 +58573,21 @@ package android.webkit { method public void flingScroll(int, int); method @Deprecated public void freeMemory(); method @Nullable public android.net.http.SslCertificate getCertificate(); - method @android.view.ViewDebug.ExportedProperty(category="webview") public int getContentHeight(); + method public int getContentHeight(); method @Nullable public static android.content.pm.PackageInfo getCurrentWebViewPackage(); method @Nullable public android.graphics.Bitmap getFavicon(); method @NonNull public android.webkit.WebView.HitTestResult getHitTestResult(); method @Deprecated @Nullable public String[] getHttpAuthUsernamePassword(String, String); - method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getOriginalUrl(); + method @Nullable public String getOriginalUrl(); method public int getProgress(); method public boolean getRendererPriorityWaivedWhenNotVisible(); method public int getRendererRequestedPriority(); method @NonNull public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl(); - method @Deprecated @android.view.ViewDebug.ExportedProperty(category="webview") public float getScale(); + method @Deprecated public float getScale(); method @NonNull public android.webkit.WebSettings getSettings(); method @NonNull public android.view.textclassifier.TextClassifier getTextClassifier(); - method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getTitle(); - method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getUrl(); + method @Nullable public String getTitle(); + method @Nullable public String getUrl(); method @Nullable public android.webkit.WebChromeClient getWebChromeClient(); method @NonNull public static ClassLoader getWebViewClassLoader(); method @NonNull public android.webkit.WebViewClient getWebViewClient(); @@ -58700,7 +58789,7 @@ package android.widget { method public void fling(int); method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet); method @ColorInt public int getBottomEdgeEffectColor(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") @ColorInt public int getCacheColorHint(); + method @ColorInt public int getCacheColorHint(); method public int getCheckedItemCount(); method public long[] getCheckedItemIds(); method public int getCheckedItemPosition(); @@ -58710,7 +58799,7 @@ package android.widget { method public int getListPaddingLeft(); method public int getListPaddingRight(); method public int getListPaddingTop(); - method @android.view.ViewDebug.ExportedProperty public android.view.View getSelectedView(); + method public android.view.View getSelectedView(); method public android.graphics.drawable.Drawable getSelector(); method public CharSequence getTextFilter(); method @ColorInt public int getTopEdgeEffectColor(); @@ -58720,13 +58809,13 @@ package android.widget { method public void invalidateViews(); method public boolean isDrawSelectorOnTop(); method public boolean isFastScrollAlwaysVisible(); - method @android.view.ViewDebug.ExportedProperty public boolean isFastScrollEnabled(); + method public boolean isFastScrollEnabled(); method protected boolean isInFilterMode(); method public boolean isItemChecked(int); - method @android.view.ViewDebug.ExportedProperty public boolean isScrollingCacheEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isSmoothScrollbarEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isStackFromBottom(); - method @android.view.ViewDebug.ExportedProperty public boolean isTextFilterEnabled(); + method public boolean isScrollingCacheEnabled(); + method public boolean isSmoothScrollbarEnabled(); + method public boolean isStackFromBottom(); + method public boolean isTextFilterEnabled(); method protected void layoutChildren(); method public void onFilterComplete(int); method public void onGlobalLayout(); @@ -58923,7 +59012,7 @@ package android.widget { ctor public AdapterView(android.content.Context, android.util.AttributeSet, int); ctor public AdapterView(android.content.Context, android.util.AttributeSet, int, int); method public abstract T getAdapter(); - method @android.view.ViewDebug.CapturedViewProperty public int getCount(); + method public int getCount(); method public android.view.View getEmptyView(); method public int getFirstVisiblePosition(); method public Object getItemAtPosition(int); @@ -58934,8 +59023,8 @@ package android.widget { method @Nullable public final android.widget.AdapterView.OnItemSelectedListener getOnItemSelectedListener(); method public int getPositionForView(android.view.View); method public Object getSelectedItem(); - method @android.view.ViewDebug.CapturedViewProperty public long getSelectedItemId(); - method @android.view.ViewDebug.CapturedViewProperty public int getSelectedItemPosition(); + method public long getSelectedItemId(); + method public int getSelectedItemPosition(); method public abstract android.view.View getSelectedView(); method public boolean performItemClick(android.view.View, int, long); method public abstract void setAdapter(T); @@ -59236,7 +59325,7 @@ package android.widget { method @Nullable public android.graphics.BlendMode getCheckMarkTintBlendMode(); method @Nullable public android.content.res.ColorStateList getCheckMarkTintList(); method @Nullable public android.graphics.PorterDuff.Mode getCheckMarkTintMode(); - method @android.view.ViewDebug.ExportedProperty public boolean isChecked(); + method public boolean isChecked(); method public void setCheckMarkDrawable(@DrawableRes int); method public void setCheckMarkDrawable(@Nullable android.graphics.drawable.Drawable); method public void setCheckMarkTintBlendMode(@Nullable android.graphics.BlendMode); @@ -59277,7 +59366,7 @@ package android.widget { method @Nullable public android.graphics.BlendMode getButtonTintBlendMode(); method @Nullable public android.content.res.ColorStateList getButtonTintList(); method @Nullable public android.graphics.PorterDuff.Mode getButtonTintMode(); - method @android.view.ViewDebug.ExportedProperty public boolean isChecked(); + method public boolean isChecked(); method public void setButtonDrawable(@DrawableRes int); method public void setButtonDrawable(@Nullable android.graphics.drawable.Drawable); method public void setButtonTintBlendMode(@Nullable android.graphics.BlendMode); @@ -59666,7 +59755,7 @@ package android.widget { method public int getColumnWidth(); method public int getGravity(); method public int getHorizontalSpacing(); - method @android.view.ViewDebug.ExportedProperty public int getNumColumns(); + method public int getNumColumns(); method public int getRequestedColumnWidth(); method public int getRequestedHorizontalSpacing(); method public int getStretchMode(); @@ -59857,8 +59946,8 @@ package android.widget { ctor public LinearLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams); ctor public LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams); method public String debug(String); - field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=0xffffffff, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.NO_GRAVITY, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.TOP, to="TOP"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.BOTTOM, to="BOTTOM"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.LEFT, to="LEFT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.RIGHT, to="RIGHT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.START, to="START"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.END, to="END"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_VERTICAL, to="CENTER_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_VERTICAL, to="FILL_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_HORIZONTAL, to="CENTER_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_HORIZONTAL, to="FILL_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL, to="FILL")}) public int gravity; - field @android.view.ViewDebug.ExportedProperty(category="layout") public float weight; + field public int gravity; + field public float weight; } public interface ListAdapter extends android.widget.Adapter { @@ -60247,13 +60336,13 @@ package android.widget { method @Nullable public android.content.res.ColorStateList getIndeterminateTintList(); method @Nullable public android.graphics.PorterDuff.Mode getIndeterminateTintMode(); method public android.view.animation.Interpolator getInterpolator(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMax(); + method public int getMax(); method @Px public int getMaxHeight(); method @Px public int getMaxWidth(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMin(); + method public int getMin(); method @Px public int getMinHeight(); method @Px public int getMinWidth(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public int getProgress(); + method public int getProgress(); method @Nullable public android.graphics.BlendMode getProgressBackgroundTintBlendMode(); method @Nullable public android.content.res.ColorStateList getProgressBackgroundTintList(); method @Nullable public android.graphics.PorterDuff.Mode getProgressBackgroundTintMode(); @@ -60261,14 +60350,14 @@ package android.widget { method @Nullable public android.graphics.BlendMode getProgressTintBlendMode(); method @Nullable public android.content.res.ColorStateList getProgressTintList(); method @Nullable public android.graphics.PorterDuff.Mode getProgressTintMode(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public int getSecondaryProgress(); + method public int getSecondaryProgress(); method @Nullable public android.graphics.BlendMode getSecondaryProgressTintBlendMode(); method @Nullable public android.content.res.ColorStateList getSecondaryProgressTintList(); method @Nullable public android.graphics.PorterDuff.Mode getSecondaryProgressTintMode(); method public final void incrementProgressBy(int); method public final void incrementSecondaryProgressBy(int); method public boolean isAnimating(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public boolean isIndeterminate(); + method public boolean isIndeterminate(); method public void onRestoreInstanceState(android.os.Parcelable); method public android.os.Parcelable onSaveInstanceState(); method public void setIndeterminate(boolean); @@ -60419,7 +60508,7 @@ package android.widget { method public int getRule(int); method public int[] getRules(); method public void removeRule(int); - field @android.view.ViewDebug.ExportedProperty(category="layout") public boolean alignWithParent; + field public boolean alignWithParent; } public class RemoteViews implements android.view.LayoutInflater.Filter android.os.Parcelable { @@ -60978,8 +61067,8 @@ package android.widget { ctor public TableRow.LayoutParams(int); ctor public TableRow.LayoutParams(android.view.ViewGroup.LayoutParams); ctor public TableRow.LayoutParams(android.view.ViewGroup.MarginLayoutParams); - field @android.view.ViewDebug.ExportedProperty(category="layout") public int column; - field @android.view.ViewDebug.ExportedProperty(category="layout") public int span; + field public int column; + field public int span; } @android.widget.RemoteViews.RemoteView public class TextClock extends android.widget.TextView { @@ -60987,8 +61076,8 @@ package android.widget { ctor public TextClock(android.content.Context, android.util.AttributeSet); ctor public TextClock(android.content.Context, android.util.AttributeSet, int); ctor public TextClock(android.content.Context, android.util.AttributeSet, int, int); - method @android.view.ViewDebug.ExportedProperty public CharSequence getFormat12Hour(); - method @android.view.ViewDebug.ExportedProperty public CharSequence getFormat24Hour(); + method public CharSequence getFormat12Hour(); + method public CharSequence getFormat24Hour(); method public String getTimeZone(); method public boolean is24HourModeEnabled(); method public void refreshTime(); @@ -61047,7 +61136,7 @@ package android.widget { method protected boolean getDefaultEditable(); method protected android.text.method.MovementMethod getDefaultMovementMethod(); method public android.text.Editable getEditableText(); - method @android.view.ViewDebug.ExportedProperty public android.text.TextUtils.TruncateAt getEllipsize(); + method public android.text.TextUtils.TruncateAt getEllipsize(); method public CharSequence getError(); method public int getExtendedPaddingBottom(); method public int getExtendedPaddingTop(); @@ -61058,7 +61147,7 @@ package android.widget { method public boolean getFreezesText(); method public int getGravity(); method @ColorInt public int getHighlightColor(); - method @android.view.ViewDebug.CapturedViewProperty public CharSequence getHint(); + method public CharSequence getHint(); method public final android.content.res.ColorStateList getHintTextColors(); method public int getHyphenationFrequency(); method public int getImeActionId(); @@ -61094,14 +61183,14 @@ package android.widget { method public android.text.TextPaint getPaint(); method public int getPaintFlags(); method public String getPrivateImeOptions(); - method @android.view.ViewDebug.ExportedProperty(category="text") public int getSelectionEnd(); - method @android.view.ViewDebug.ExportedProperty(category="text") public int getSelectionStart(); + method public int getSelectionEnd(); + method public int getSelectionStart(); method @ColorInt public int getShadowColor(); method public float getShadowDx(); method public float getShadowDy(); method public float getShadowRadius(); method public final boolean getShowSoftInputOnFocus(); - method @android.view.ViewDebug.CapturedViewProperty public CharSequence getText(); + method public CharSequence getText(); method @NonNull public android.view.textclassifier.TextClassifier getTextClassifier(); method public final android.content.res.ColorStateList getTextColors(); method @Nullable public android.graphics.drawable.Drawable getTextCursorDrawable(); @@ -61113,7 +61202,7 @@ package android.widget { method @Nullable public android.graphics.drawable.Drawable getTextSelectHandle(); method @Nullable public android.graphics.drawable.Drawable getTextSelectHandleLeft(); method @Nullable public android.graphics.drawable.Drawable getTextSelectHandleRight(); - method @android.view.ViewDebug.ExportedProperty(category="text") public float getTextSize(); + method public float getTextSize(); method public int getTextSizeUnit(); method public int getTotalPaddingBottom(); method public int getTotalPaddingEnd(); diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index 67afc3225f7b..6f5ac7cb0c5a 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -1,24 +1,6 @@ // 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"; @@ -38,69 +20,15 @@ package android.net { 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.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.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.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback); method @Deprecated public int tether(@NonNull String); - method @RequiresPermission(anyOf={"android.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 { @@ -109,22 +37,6 @@ package android.net { 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 setShouldShowEntitlementUi(boolean); - method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress); - } - } package android.os { diff --git a/api/system-current.txt b/api/system-current.txt index f07ebaf19cb6..85583269dedf 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -8958,6 +8958,7 @@ package android.provider { field public static final String NAMESPACE_AUTOFILL = "autofill"; field public static final String NAMESPACE_BIOMETRICS = "biometrics"; field public static final String NAMESPACE_BLOBSTORE = "blobstore"; + field public static final String NAMESPACE_BLUETOOTH = "bluetooth"; field public static final String NAMESPACE_CONNECTIVITY = "connectivity"; field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; field @Deprecated public static final String NAMESPACE_DEX_BOOT = "dex_boot"; @@ -9766,7 +9767,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(@Nullable String, @Nullable String) throws java.lang.IllegalArgumentException, java.lang.NumberFormatException, java.lang.UnsupportedOperationException; + method public int encodeSmdxSubjectAndReasonCode(@Nullable String, @Nullable 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); @@ -10203,7 +10204,7 @@ package android.telecom { } public static class CallScreeningService.CallResponse.Builder { - method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean); } public abstract class Conference extends android.telecom.Conferenceable { @@ -10659,85 +10660,6 @@ package android.telephony { 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(); @@ -12513,6 +12435,7 @@ 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 addServiceAnnouncement(int, @NonNull byte[]); 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; diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt index 10c96a330bf4..9c40b6cf63ce 100644 --- a/api/system-lint-baseline.txt +++ b/api/system-lint-baseline.txt @@ -217,6 +217,13 @@ MutableBareField: android.net.wifi.WifiScanner.ScanSettings#type: NoClone: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0: + + + +NoSettingsProvider: android.provider.Settings.Global#TETHER_OFFLOAD_DISABLED: + New setting keys are not allowed. (Field: TETHER_OFFLOAD_DISABLED) +NoSettingsProvider: android.provider.Settings.Global#TETHER_SUPPORTED: + New setting keys are not allowed. (Field: TETHER_SUPPORTED) diff --git a/api/test-current.txt b/api/test-current.txt index cf97b848e80b..519bbbb9bc39 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -3859,7 +3859,7 @@ package android.telecom { } public static class CallScreeningService.CallResponse.Builder { - method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean); } public abstract class Conference extends android.telecom.Conferenceable { @@ -3927,6 +3927,7 @@ package android.telecom { method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getCurrentTtyMode(); method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getDefaultDialerPackage(@NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall(); + method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(@Nullable android.telecom.PhoneAccountHandle); field public static final int TTY_MODE_FULL = 1; // 0x1 field public static final int TTY_MODE_HCO = 2; // 0x2 @@ -4909,6 +4910,7 @@ 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 addServiceAnnouncement(int, @NonNull byte[]); 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; @@ -5210,7 +5212,7 @@ package android.view { field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000 field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40 field public CharSequence accessibilityTitle; - field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=0x1, equals=0x1, name="FAKE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x2, equals=0x2, name="FORCE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x4, equals=0x4, name="WANTS_OFFSET_NOTIFICATIONS"), @android.view.ViewDebug.FlagToString(mask=0x10, equals=0x10, name="SHOW_FOR_ALL_USERS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, equals=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, name="NO_MOVE_ANIMATION"), @android.view.ViewDebug.FlagToString(mask=0x80, equals=0x80, name="COMPATIBLE_WINDOW"), @android.view.ViewDebug.FlagToString(mask=0x100, equals=0x100, name="SYSTEM_ERROR"), @android.view.ViewDebug.FlagToString(mask=0x800, equals=0x800, name="DISABLE_WALLPAPER_TOUCH_EVENTS"), @android.view.ViewDebug.FlagToString(mask=0x1000, equals=0x1000, name="FORCE_STATUS_BAR_VISIBLE"), @android.view.ViewDebug.FlagToString(mask=0x2000, equals=0x2000, name="PRESERVE_GEOMETRY"), @android.view.ViewDebug.FlagToString(mask=0x4000, equals=0x4000, name="FORCE_DECOR_VIEW_VISIBILITY"), @android.view.ViewDebug.FlagToString(mask=0x8000, equals=0x8000, name="WILL_NOT_REPLACE_ON_RELAUNCH"), @android.view.ViewDebug.FlagToString(mask=0x10000, equals=0x10000, name="LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME"), @android.view.ViewDebug.FlagToString(mask=0x20000, equals=0x20000, name="FORCE_DRAW_STATUS_BAR_BACKGROUND"), @android.view.ViewDebug.FlagToString(mask=0x40000, equals=0x40000, name="SUSTAINED_PERFORMANCE_MODE"), @android.view.ViewDebug.FlagToString(mask=0x80000, equals=0x80000, name="HIDE_NON_SYSTEM_OVERLAY_WINDOWS"), @android.view.ViewDebug.FlagToString(mask=0x100000, equals=0x100000, name="IS_ROUNDED_CORNERS_OVERLAY"), @android.view.ViewDebug.FlagToString(mask=0x400000, equals=0x400000, name="IS_SCREEN_DECOR"), @android.view.ViewDebug.FlagToString(mask=0x800000, equals=0x800000, name="STATUS_FORCE_SHOW_NAVIGATION"), @android.view.ViewDebug.FlagToString(mask=0x1000000, equals=0x1000000, name="COLOR_SPACE_AGNOSTIC"), @android.view.ViewDebug.FlagToString(mask=0x4000000, equals=0x4000000, name="APPEARANCE_CONTROLLED"), @android.view.ViewDebug.FlagToString(mask=0x8000000, equals=0x8000000, name="BEHAVIOR_CONTROLLED"), @android.view.ViewDebug.FlagToString(mask=0x10000000, equals=0x10000000, name="FIT_INSETS_CONTROLLED")}) public int privateFlags; + field public int privateFlags; } } diff --git a/api/test-lint-baseline.txt b/api/test-lint-baseline.txt index caf8fdbeca0d..6562c7e35c73 100644 --- a/api/test-lint-baseline.txt +++ b/api/test-lint-baseline.txt @@ -2294,6 +2294,88 @@ NoClone: android.service.autofill.augmented.AugmentedAutofillService#dump(java.i NoClone: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0: NoClone: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0: + + + +NoSettingsProvider: android.provider.Settings.Global#APP_OPS_CONSTANTS: + New setting keys are not allowed (Field: APP_OPS_CONSTANTS); use getters/setters in relevant manager class +NoSettingsProvider: android.provider.Settings.Global#AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES: + +NoSettingsProvider: android.provider.Settings.Global#AUTOMATIC_POWER_SAVE_MODE: + +NoSettingsProvider: android.provider.Settings.Global#BATTERY_SAVER_CONSTANTS: + +NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD: + +NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_ENABLED: + +NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_BLACKLIST_EXEMPTIONS: + +NoSettingsProvider: android.provider.Settings.Global#HIDE_ERROR_DIALOGS: + New setting keys are not allowed (Field: HIDE_ERROR_DIALOGS); use getters/setters in relevant manager class +NoSettingsProvider: android.provider.Settings.Global#LOCATION_GLOBAL_KILL_SWITCH: + +NoSettingsProvider: android.provider.Settings.Global#LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST: + +NoSettingsProvider: android.provider.Settings.Global#LOW_POWER_MODE: + +NoSettingsProvider: android.provider.Settings.Global#LOW_POWER_MODE_STICKY: + +NoSettingsProvider: android.provider.Settings.Global#NOTIFICATION_BUBBLES: + +NoSettingsProvider: android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES: + +NoSettingsProvider: android.provider.Settings.Global#TETHER_OFFLOAD_DISABLED: + +NoSettingsProvider: android.provider.Settings.Global#USE_OPEN_WIFI_PACKAGE: + +NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED: + +NoSettingsProvider: android.provider.Settings.Secure#ACCESSIBILITY_SHORTCUT_TARGET_SERVICE: + +NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_FEATURE_FIELD_CLASSIFICATION: + +NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_SERVICE: + +NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT: + +NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE: + +NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE: + +NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MAX_VALUE_LENGTH: + +NoSettingsProvider: android.provider.Settings.Secure#AUTOFILL_USER_DATA_MIN_VALUE_LENGTH: + +NoSettingsProvider: android.provider.Settings.Secure#CONTENT_CAPTURE_ENABLED: + +NoSettingsProvider: android.provider.Settings.Secure#DISABLED_PRINT_SERVICES: + +NoSettingsProvider: android.provider.Settings.Secure#DOZE_ALWAYS_ON: + +NoSettingsProvider: android.provider.Settings.Secure#ENABLED_VR_LISTENERS: + +NoSettingsProvider: android.provider.Settings.Secure#IMMERSIVE_MODE_CONFIRMATIONS: + New setting keys are not allowed (Field: IMMERSIVE_MODE_CONFIRMATIONS); use getters/setters in relevant manager class +NoSettingsProvider: android.provider.Settings.Secure#LOCATION_ACCESS_CHECK_DELAY_MILLIS: + +NoSettingsProvider: android.provider.Settings.Secure#LOCATION_ACCESS_CHECK_INTERVAL_MILLIS: + +NoSettingsProvider: android.provider.Settings.Secure#LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS: + New setting keys are not allowed (Field: LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS); use getters/setters in relevant manager class +NoSettingsProvider: android.provider.Settings.Secure#LOCK_SCREEN_SHOW_NOTIFICATIONS: + New setting keys are not allowed (Field: LOCK_SCREEN_SHOW_NOTIFICATIONS); use getters/setters in relevant manager class +NoSettingsProvider: android.provider.Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT: + New setting keys are not allowed (Field: NFC_PAYMENT_DEFAULT_COMPONENT); use getters/setters in relevant manager class +NoSettingsProvider: android.provider.Settings.Secure#NOTIFICATION_BADGING: + +NoSettingsProvider: android.provider.Settings.Secure#POWER_MENU_LOCKED_SHOW_CONTENT: + New setting keys are not allowed (Field: POWER_MENU_LOCKED_SHOW_CONTENT); use getters/setters in relevant manager class +NoSettingsProvider: android.provider.Settings.Secure#SYNC_PARENT_SOUNDS: + +NoSettingsProvider: android.provider.Settings.Secure#USER_SETUP_COMPLETE: + +NoSettingsProvider: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE: diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp index 8be95e4659b4..07221f97c72b 100644 --- a/cmds/app_process/Android.bp +++ b/cmds/app_process/Android.bp @@ -5,11 +5,13 @@ cc_binary { multilib: { lib32: { - version_script: ":art_sigchain_version_script32.txt", + // TODO(b/142944043): Remove version script when libsigchain is a DSO. + version_script: "version-script32.txt", suffix: "32", }, lib64: { - version_script: ":art_sigchain_version_script64.txt", + // TODO(b/142944043): Remove version script when libsigchain is a DSO. + version_script: "version-script64.txt", suffix: "64", }, }, diff --git a/cmds/app_process/version-script32.txt b/cmds/app_process/version-script32.txt new file mode 100644 index 000000000000..70810e0b7173 --- /dev/null +++ b/cmds/app_process/version-script32.txt @@ -0,0 +1,15 @@ +{ +global: + EnsureFrontOfChain; + AddSpecialSignalHandlerFn; + RemoveSpecialSignalHandlerFn; + SkipAddSignalHandler; + bsd_signal; + sigaction; + sigaction64; + signal; + sigprocmask; + sigprocmask64; +local: + *; +}; diff --git a/cmds/app_process/version-script64.txt b/cmds/app_process/version-script64.txt new file mode 100644 index 000000000000..7bcd76b50f87 --- /dev/null +++ b/cmds/app_process/version-script64.txt @@ -0,0 +1,14 @@ +{ +global: + EnsureFrontOfChain; + AddSpecialSignalHandlerFn; + RemoveSpecialSignalHandlerFn; + SkipAddSignalHandler; + sigaction; + sigaction64; + signal; + sigprocmask; + sigprocmask64; +local: + *; +}; diff --git a/cmds/bootanimation/Android.bp b/cmds/bootanimation/Android.bp index befb67bcf26a..757c2b2a4cfa 100644 --- a/cmds/bootanimation/Android.bp +++ b/cmds/bootanimation/Android.bp @@ -28,6 +28,8 @@ cc_binary { name: "bootanimation", defaults: ["bootanimation_defaults"], + header_libs: ["jni_headers"], + shared_libs: [ "libOpenSLES", "libbootanimation", diff --git a/cmds/device_config/Android.bp b/cmds/device_config/Android.bp new file mode 100644 index 000000000000..67e014a20506 --- /dev/null +++ b/cmds/device_config/Android.bp @@ -0,0 +1,7 @@ +// Copyright 2018 The Android Open Source Project +// + +sh_binary { + name: "device_config", + src: "device_config", +} diff --git a/cmds/device_config/Android.mk b/cmds/device_config/Android.mk deleted file mode 100644 index 4041e01927df..000000000000 --- a/cmds/device_config/Android.mk +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright 2018 The Android Open Source Project -# -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := device_config -LOCAL_SRC_FILES := device_config -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_MODULE_TAGS := optional -include $(BUILD_PREBUILT) diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index f95b73f17222..a6c402ccc075 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -169,7 +169,7 @@ Status Idmap2Service::createIdmap(const std::string& target_apk_path, aidl::nullable<std::string>* _aidl_return) { assert(_aidl_return); SYSTRACE << "Idmap2Service::createIdmap " << target_apk_path << " " << overlay_apk_path; - _aidl_return->reset(nullptr); + _aidl_return->reset(); const PolicyBitmask policy_bitmask = ConvertAidlArgToPolicyBitmask(fulfilled_policies); diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp index 33e764988b75..e56ed39ea32e 100644 --- a/cmds/incidentd/src/Section.cpp +++ b/cmds/incidentd/src/Section.cpp @@ -33,7 +33,6 @@ #include <debuggerd/client.h> #include <dumputils/dump_utils.h> #include <log/log_event_list.h> -#include <log/log_read.h> #include <log/logprint.h> #include <private/android_logger.h> #include <sys/mman.h> diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h index bc4909dcfa2e..698cc04c160e 100644 --- a/cmds/incidentd/src/Section.h +++ b/cmds/incidentd/src/Section.h @@ -24,7 +24,7 @@ #include <map> #include <android/os/IIncidentDumpCallback.h> - +#include <log/log_read.h> #include <utils/String16.h> #include <utils/String8.h> #include <utils/Vector.h> @@ -164,8 +164,8 @@ class LogSection : public WorkerThreadSection { // global last log retrieved timestamp for each log_id_t. static map<log_id_t, log_time> gLastLogsRetrieved; - // log mode: read only & non blocking. - const static int logModeBase = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK; + // log mode: non blocking. + const static int logModeBase = ANDROID_LOG_NONBLOCK; public: LogSection(int id, const char* logID, ...); diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index 6f952f637506..322648229d0e 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -1093,36 +1093,26 @@ void StatsService::OnLogEvent(LogEvent* event) { } } -Status StatsService::getData(int64_t key, const int32_t callingUid, vector<int8_t>* output) { +Status StatsService::getData(int64_t key, const int32_t callingUid, vector<uint8_t>* output) { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::getData with Uid %i", callingUid); ConfigKey configKey(callingUid, key); - // TODO(b/149254662): Since libbinder_ndk uses int8_t instead of uint8_t, - // there are inconsistencies with internal statsd logic. Instead of - // modifying lots of files, we create a temporary output array of int8_t and - // copy its data into output. This is a bad hack, but hopefully - // libbinder_ndk will transition to using uint8_t soon: progress is tracked - // in b/144957764. Same applies to StatsService::getMetadata. - vector<uint8_t> unsignedOutput; // The dump latency does not matter here since we do not include the current bucket, we do not // need to pull any new data anyhow. mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/, - true /* erase_data */, GET_DATA_CALLED, FAST, &unsignedOutput); - *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end()); + true /* erase_data */, GET_DATA_CALLED, FAST, output); return Status::ok(); } -Status StatsService::getMetadata(vector<int8_t>* output) { +Status StatsService::getMetadata(vector<uint8_t>* output) { ENFORCE_UID(AID_SYSTEM); - vector<uint8_t> unsignedOutput; - StatsdStats::getInstance().dumpStats(&unsignedOutput, false); // Don't reset the counters. - *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end()); + StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters. return Status::ok(); } -Status StatsService::addConfiguration(int64_t key, const vector <int8_t>& config, +Status StatsService::addConfiguration(int64_t key, const vector <uint8_t>& config, const int32_t callingUid) { ENFORCE_UID(AID_SYSTEM); @@ -1133,7 +1123,7 @@ Status StatsService::addConfiguration(int64_t key, const vector <int8_t>& config } } -bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config) { +bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config) { ConfigKey configKey(uid, key); StatsdConfig cfg; if (config.size() > 0) { // If the config is empty, skip parsing. diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index b49fa1d42e66..324ffbd65e51 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -96,13 +96,13 @@ public: */ virtual Status getData(int64_t key, const int32_t callingUid, - vector<int8_t>* output) override; + vector<uint8_t>* output) override; /** * Binder call for clients to get metadata across all configs in statsd. */ - virtual Status getMetadata(vector<int8_t>* output) override; + virtual Status getMetadata(vector<uint8_t>* output) override; /** @@ -110,7 +110,7 @@ public: * should requestData for this configuration. */ virtual Status addConfiguration(int64_t key, - const vector<int8_t>& config, + const vector<uint8_t>& config, const int32_t callingUid) override; /** @@ -320,7 +320,7 @@ private: /** * Adds a configuration after checking permissions and obtaining UID from binder call. */ - bool addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config); + bool addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config); /** * Update a configuration. diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp index 783f31c7bde8..c03b9254f70d 100644 --- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp @@ -39,7 +39,7 @@ const int kCallingUid = 0; // Randomly chosen void SendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) { string str; config.SerializeToString(&str); - std::vector<int8_t> configAsVec(str.begin(), str.end()); + std::vector<uint8_t> configAsVec(str.begin(), str.end()); service->addConfiguration(kConfigKey, configAsVec, kCallingUid); } diff --git a/config/OWNERS b/config/OWNERS index 53f80e698d83..3d4924df3462 100644 --- a/config/OWNERS +++ b/config/OWNERS @@ -1,5 +1,5 @@ # compat-team@ for changes to hiddenapi files -per-file hiddenapi-* = andreionea@google.com, atrost@google.com, mathewi@google.com, satayev@google.com +per-file hiddenapi-* = andreionea@google.com, mathewi@google.com, satayev@google.com # Escalations: -per-file hiddenapi-* = bdc@google.com, narayan@google.com
\ No newline at end of file +per-file hiddenapi-* = bdc@google.com, narayan@google.com diff --git a/config/preloaded-classes b/config/preloaded-classes index 0bac2d1a7a5d..481bcb5f8b85 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -9990,8 +9990,6 @@ dalvik.system.CloseGuard$DefaultReporter dalvik.system.CloseGuard$Reporter dalvik.system.CloseGuard$Tracker dalvik.system.CloseGuard -dalvik.system.DalvikLogHandler -dalvik.system.DalvikLogging dalvik.system.DelegateLastClassLoader dalvik.system.DexClassLoader dalvik.system.DexFile$1 @@ -11952,6 +11950,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 48d579cc118e..8ab5273cd755 100644 --- a/config/preloaded-classes-blacklist +++ b/config/preloaded-classes-blacklist @@ -1,6 +1,5 @@ android.content.AsyncTaskLoader$LoadTask android.net.ConnectivityThread$Singleton -android.os.AsyncTask android.os.FileObserver android.os.NullVibrator android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask diff --git a/core/java/android/annotation/OWNERS b/core/java/android/annotation/OWNERS index 8aceb565315c..e1ef54460b56 100644 --- a/core/java/android/annotation/OWNERS +++ b/core/java/android/annotation/OWNERS @@ -1,3 +1,3 @@ tnorbye@google.com aurimas@google.com -per-file UnsupportedAppUsage.java = mathewi@google.com, dbrazdil@google.com, atrost@google.com, andreionea@google.com +per-file UnsupportedAppUsage.java = mathewi@google.com, satayev@google.com, andreionea@google.com diff --git a/core/java/android/annotation/SystemApi.java b/core/java/android/annotation/SystemApi.java index 4ac00983af13..a468439c8e74 100644 --- a/core/java/android/annotation/SystemApi.java +++ b/core/java/android/annotation/SystemApi.java @@ -23,7 +23,6 @@ import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PACKAGE; import static java.lang.annotation.ElementType.TYPE; -import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -41,7 +40,6 @@ import java.lang.annotation.Target; */ @Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE}) @Retention(RetentionPolicy.RUNTIME) -@Repeatable(SystemApi.Container.class) // TODO(b/146727827): make this non-repeatable public @interface SystemApi { enum Client { /** diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 3772755beca1..63e8638a34a4 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -220,8 +220,8 @@ import java.util.function.Consumer; * <a name="Fragments"></a> * <h3>Fragments</h3> * - * <p>The {@link android.support.v4.app.FragmentActivity} subclass - * can make use of the {@link android.support.v4.app.Fragment} class to better + * <p>The {@link androidx.fragment.app.FragmentActivity} subclass + * can make use of the {@link androidx.fragment.app.Fragment} class to better * modularize their code, build more sophisticated user interfaces for larger * screens, and help scale their application between small and large screens.</p> * @@ -1100,7 +1100,7 @@ public class Activity extends ContextThemeWrapper /** * Return the LoaderManager for this activity, creating it if needed. * - * @deprecated Use {@link android.support.v4.app.FragmentActivity#getSupportLoaderManager()} + * @deprecated Use {@link androidx.fragment.app.FragmentActivity#getSupportLoaderManager()} */ @Deprecated public LoaderManager getLoaderManager() { @@ -3159,7 +3159,7 @@ public class Activity extends ContextThemeWrapper * Return the FragmentManager for interacting with fragments associated * with this activity. * - * @deprecated Use {@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()} + * @deprecated Use {@link androidx.fragment.app.FragmentActivity#getSupportFragmentManager()} */ @Deprecated public FragmentManager getFragmentManager() { @@ -3172,7 +3172,7 @@ public class Activity extends ContextThemeWrapper * method and before {@link Fragment#onCreate Fragment.onCreate()}. * * @deprecated Use {@link - * android.support.v4.app.FragmentActivity#onAttachFragment(android.support.v4.app.Fragment)} + * androidx.fragment.app.FragmentActivity#onAttachFragment(androidx.fragment.app.Fragment)} */ @Deprecated public void onAttachFragment(Fragment fragment) { diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index ae8a2cbf5120..12ec9eb4eb73 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -34,9 +34,8 @@ import android.text.TextUtils; import android.util.Log; import android.util.proto.ProtoOutputStream; -import libcore.timezone.ZoneInfoDb; +import com.android.i18n.timezone.ZoneInfoDb; -import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; @@ -996,12 +995,7 @@ public class AlarmManager { // Reject this timezone if it isn't an Olson zone we recognize. if (mTargetSdkVersion >= Build.VERSION_CODES.M) { - boolean hasTimeZone = false; - try { - hasTimeZone = ZoneInfoDb.getInstance().hasTimeZone(timeZone); - } catch (IOException ignored) { - } - + boolean hasTimeZone = ZoneInfoDb.getInstance().hasTimeZone(timeZone); if (!hasTimeZone) { throw new IllegalArgumentException("Timezone: " + timeZone + " is not an Olson ID"); } diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index e4e5ba37ddbf..f7fb3c34ce1b 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -102,7 +102,7 @@ import java.lang.reflect.InvocationTargetException; * While the Fragment API was introduced in * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, a version of the API * at is also available for use on older platforms through - * {@link android.support.v4.app.FragmentActivity}. See the blog post + * {@link androidx.fragment.app.FragmentActivity}. See the blog post * <a href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html"> * Fragments For All</a> for more details. * @@ -258,8 +258,8 @@ import java.lang.reflect.InvocationTargetException; * pressing back will pop it to return the user to whatever previous state * the activity UI was in. * - * @deprecated Use the <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> - * {@link android.support.v4.app.Fragment} for consistent behavior across all devices + * @deprecated Use the <a href="{@docRoot}jetpack">Jetpack Fragment Library</a> + * {@link androidx.fragment.app.Fragment} for consistent behavior across all devices * and access to <a href="{@docRoot}topic/libraries/architecture/lifecycle.html">Lifecycle</a>. */ @Deprecated @@ -432,7 +432,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene * through {@link FragmentManager#saveFragmentInstanceState(Fragment) * FragmentManager.saveFragmentInstanceState}. * - * @deprecated Use {@link android.support.v4.app.Fragment.SavedState} + * @deprecated Use {@link androidx.fragment.app.Fragment.SavedState} */ @Deprecated public static class SavedState implements Parcelable { @@ -479,7 +479,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene * Thrown by {@link Fragment#instantiate(Context, String, Bundle)} when * there is an instantiation failure. * - * @deprecated Use {@link android.support.v4.app.Fragment.InstantiationException} + * @deprecated Use {@link androidx.fragment.app.Fragment.InstantiationException} */ @Deprecated static public class InstantiationException extends AndroidRuntimeException { @@ -1055,7 +1055,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene /** * Return the LoaderManager for this fragment, creating it if needed. * - * @deprecated Use {@link android.support.v4.app.Fragment#getLoaderManager()} + * @deprecated Use {@link androidx.fragment.app.Fragment#getLoaderManager()} */ @Deprecated public LoaderManager getLoaderManager() { diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index 4cba6ea74955..747789901b9d 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -20,7 +20,6 @@ import static android.app.ActivityThread.DEBUG_CONFIGURATION; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; @@ -1043,7 +1042,6 @@ public class ResourcesManager { } } - @TestApi public final boolean applyConfigurationToResources(@NonNull Configuration config, @Nullable CompatibilityInfo compat) { synchronized(this) { 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/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 29a98faf5cd1..de591bd1f103 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1812,6 +1812,7 @@ public final class BluetoothAdapter { try { mServiceLock.readLock().lock(); if (mService != null) { + if (DBG) Log.d(TAG, "removeActiveDevice, profiles: " + profiles); return mService.removeActiveDevice(profiles); } } catch (RemoteException e) { @@ -1856,6 +1857,9 @@ public final class BluetoothAdapter { try { mServiceLock.readLock().lock(); if (mService != null) { + if (DBG) { + Log.d(TAG, "setActiveDevice, device: " + device + ", profiles: " + profiles); + } return mService.setActiveDevice(device, profiles); } } catch (RemoteException e) { diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java index d2a15357aa1f..e07bc0215a6b 100644 --- a/core/java/android/bluetooth/BluetoothCodecConfig.java +++ b/core/java/android/bluetooth/BluetoothCodecConfig.java @@ -614,8 +614,9 @@ public final class BluetoothCodecConfig implements Parcelable { if (other == null && mCodecType != other.mCodecType) { return false; } - // Currently we only care about the LDAC Playback Quality at CodecSpecific1 + // Currently we only care about the AAC VBR and LDAC Playback Quality at CodecSpecific1 switch (mCodecType) { + case SOURCE_CODEC_TYPE_AAC: case SOURCE_CODEC_TYPE_LDAC: if (mCodecSpecific1 != other.mCodecSpecific1) { return false; diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 594e5ffa77a7..dc7d05300d45 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -1031,7 +1031,11 @@ public final class BluetoothDevice implements Parcelable { try { String name = service.getRemoteName(this); if (name != null) { - return name.replaceAll("[\\t\\n\\r]+", " "); + // remove whitespace characters from the name + return name + .replace('\t', ' ') + .replace('\n', ' ') + .replace('\r', ' '); } return null; } catch (RemoteException e) { diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java index 85e0e08b19c8..28363250ebda 100644 --- a/core/java/android/bluetooth/BluetoothHeadsetClient.java +++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java @@ -19,7 +19,6 @@ package android.bluetooth; import android.Manifest; import android.annotation.NonNull; import android.annotation.RequiresPermission; -import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; @@ -587,7 +586,6 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * @return true if connectionPolicy is set, false on error * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { @@ -637,7 +635,6 @@ public final class BluetoothHeadsetClient implements BluetoothProfile { * @return connection policy of the device * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH) public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java index 19240dc0bbc7..df11d3adac01 100644 --- a/core/java/android/bluetooth/BluetoothMapClient.java +++ b/core/java/android/bluetooth/BluetoothMapClient.java @@ -19,7 +19,6 @@ package android.bluetooth; import android.Manifest; import android.annotation.NonNull; import android.annotation.RequiresPermission; -import android.annotation.SystemApi; import android.app.PendingIntent; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; @@ -53,6 +52,18 @@ public final class BluetoothMapClient implements BluetoothProfile { public static final String ACTION_MESSAGE_DELIVERED_SUCCESSFULLY = "android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY"; + /** + * Action to notify read status changed + */ + public static final String ACTION_MESSAGE_READ_STATUS_CHANGED = + "android.bluetooth.mapmce.profile.action.MESSAGE_READ_STATUS_CHANGED"; + + /** + * Action to notify deleted status changed + */ + public static final String ACTION_MESSAGE_DELETED_STATUS_CHANGED = + "android.bluetooth.mapmce.profile.action.MESSAGE_DELETED_STATUS_CHANGED"; + /* Extras used in ACTION_MESSAGE_RECEIVED intent. * NOTE: HANDLE is only valid for a single session with the device. */ public static final String EXTRA_MESSAGE_HANDLE = @@ -66,6 +77,25 @@ public final class BluetoothMapClient implements BluetoothProfile { public static final String EXTRA_SENDER_CONTACT_NAME = "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_NAME"; + /** + * Used as a boolean extra in ACTION_MESSAGE_DELETED_STATUS_CHANGED + * Contains the MAP message deleted status + * Possible values are: + * true: deleted + * false: undeleted + */ + public static final String EXTRA_MESSAGE_DELETED_STATUS = + "android.bluetooth.mapmce.profile.extra.MESSAGE_DELETED_STATUS"; + + /** + * Extra used in ACTION_MESSAGE_READ_STATUS_CHANGED or ACTION_MESSAGE_DELETED_STATUS_CHANGED + * Possible values are: + * 0: failure + * 1: success + */ + public static final String EXTRA_RESULT_CODE = + "android.bluetooth.device.extra.RESULT_CODE"; + /** There was an error trying to obtain the state */ public static final int STATE_ERROR = -1; @@ -76,6 +106,12 @@ public final class BluetoothMapClient implements BluetoothProfile { private static final int UPLOADING_FEATURE_BITMASK = 0x08; + /** Parameters in setMessageStatus */ + public static final int UNREAD = 0; + public static final int READ = 1; + public static final int UNDELETED = 2; + public static final int DELETED = 3; + private BluetoothAdapter mAdapter; private final BluetoothProfileConnector<IBluetoothMapClient> mProfileConnector = new BluetoothProfileConnector(this, BluetoothProfile.MAP_CLIENT, @@ -276,7 +312,6 @@ public final class BluetoothMapClient implements BluetoothProfile { * @return true if connectionPolicy is set, false on error * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { @@ -325,7 +360,6 @@ public final class BluetoothMapClient implements BluetoothProfile { * @return connection policy of the device * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) Log.d(TAG, "getConnectionPolicy(" + device + ")"); @@ -408,6 +442,38 @@ public final class BluetoothMapClient implements BluetoothProfile { return false; } + /** + * Set message status of message on MSE + * <p> + * When read status changed, the result will be published via + * {@link #ACTION_MESSAGE_READ_STATUS_CHANGED} + * When deleted status changed, the result will be published via + * {@link #ACTION_MESSAGE_DELETED_STATUS_CHANGED} + * + * @param device Bluetooth device + * @param handle message handle + * @param status <code>UNREAD</code> for "unread", <code>READ</code> for + * "read", <code>UNDELETED</code> for "undeleted", <code>DELETED</code> for + * "deleted", otherwise return error + * @return <code>true</code> if request has been sent, <code>false</code> on error + * + */ + @RequiresPermission(Manifest.permission.READ_SMS) + public boolean setMessageStatus(BluetoothDevice device, String handle, int status) { + if (DBG) Log.d(TAG, "setMessageStatus(" + device + ", " + handle + ", " + status + ")"); + final IBluetoothMapClient service = getService(); + if (service != null && isEnabled() && isValidDevice(device) && handle != null && + (status == READ || status == UNREAD || status == UNDELETED || status == DELETED)) { + try { + return service.setMessageStatus(device, handle, status); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + return false; + } + } + return false; + } + private boolean isEnabled() { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) return true; diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java index a80f5b7f36d4..bfc28fae6e65 100644 --- a/core/java/android/bluetooth/BluetoothPan.java +++ b/core/java/android/bluetooth/BluetoothPan.java @@ -367,7 +367,7 @@ public final class BluetoothPan implements BluetoothProfile { final IBluetoothPan service = getService(); if (service != null && isEnabled()) { try { - service.setBluetoothTethering(value, pkgName); + service.setBluetoothTethering(value, pkgName, null); } catch (RemoteException e) { Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); } diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java index d3452ffb4586..f356da18fc73 100644 --- a/core/java/android/bluetooth/BluetoothPbapClient.java +++ b/core/java/android/bluetooth/BluetoothPbapClient.java @@ -19,7 +19,6 @@ package android.bluetooth; import android.Manifest; import android.annotation.NonNull; import android.annotation.RequiresPermission; -import android.annotation.SystemApi; import android.content.Context; import android.os.Binder; import android.os.IBinder; @@ -276,7 +275,6 @@ public final class BluetoothPbapClient implements BluetoothProfile { * @return true if connectionPolicy is set, false on error * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { @@ -329,7 +327,6 @@ public final class BluetoothPbapClient implements BluetoothProfile { * @return connection policy of the device * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) { if (VDBG) { diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java index 6e0348158f48..48e8c1ada255 100644 --- a/core/java/android/bluetooth/BluetoothSap.java +++ b/core/java/android/bluetooth/BluetoothSap.java @@ -18,7 +18,6 @@ package android.bluetooth; import android.Manifest; import android.annotation.RequiresPermission; -import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Binder; @@ -328,7 +327,6 @@ public final class BluetoothSap implements BluetoothProfile { * @return true if connectionPolicy is set, false on error * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(BluetoothDevice device, @ConnectionPolicy int connectionPolicy) { @@ -377,7 +375,6 @@ public final class BluetoothSap implements BluetoothProfile { * @return connection policy of the device * @hide */ - @SystemApi @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) { if (VDBG) log("getConnectionPolicy(" + device + ")"); diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java index 9a17346334d1..2888fbd8a363 100644 --- a/core/java/android/bluetooth/le/BluetoothLeScanner.java +++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java @@ -110,8 +110,9 @@ public final class BluetoothLeScanner { * off to save power. Scanning is resumed when screen is turned on again. To avoid this, use * {@link #startScan(List, ScanSettings, ScanCallback)} with desired {@link ScanFilter}. * <p> - * An app must hold - * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or + * An app must have + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission + * in order to get results. An App targeting Android Q or later must have * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission * in order to get results. * @@ -129,8 +130,9 @@ public final class BluetoothLeScanner { * resumed when screen is turned on again. To avoid this, do filetered scanning by * using proper {@link ScanFilter}. * <p> - * An app must hold - * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or + * An app must have + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission + * in order to get results. An App targeting Android Q or later must have * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission * in order to get results. * @@ -150,8 +152,9 @@ public final class BluetoothLeScanner { * the PendingIntent. Use this method of scanning if your process is not always running and it * should be started when scan results are available. * <p> - * An app must hold - * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or + * An app must have + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} permission + * in order to get results. An App targeting Android Q or later must have * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission * in order to get results. * <p> diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java index 2bdca7d87a78..fd3d48f2fd0e 100644 --- a/core/java/android/content/om/OverlayManager.java +++ b/core/java/android/content/om/OverlayManager.java @@ -21,7 +21,6 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.TestApi; import android.compat.Compatibility; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; @@ -241,7 +240,6 @@ public class OverlayManager { * * @hide */ - @TestApi @RequiresPermission(anyOf = { "android.permission.INTERACT_ACROSS_USERS", }) diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index ea4a2a0b8c35..46af6303d04d 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -3741,6 +3741,13 @@ public abstract class PackageManager { } /** + * @deprecated Do not instantiate or subclass - obtain an instance from + * {@link Context#getPackageManager} + */ + @Deprecated + public PackageManager() {} + + /** * Retrieve overall information about an application package that is * installed on the system. * diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 70e4e6cbf622..43632f5ccbe8 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -46,7 +46,6 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; -import android.annotation.TestApi; import android.apex.ApexInfo; import android.app.ActivityTaskManager; import android.app.ActivityThread; @@ -2545,7 +2544,6 @@ public class PackageParser { * not compatible with this platform * @hide Exposed for unit testing only. */ - @TestApi public static int computeTargetSdkVersion(@IntRange(from = 0) int targetVers, @Nullable String targetCode, @NonNull String[] platformSdkCodenames, @NonNull String[] outError) { @@ -2610,7 +2608,6 @@ public class PackageParser { * compatible with this platform * @hide Exposed for unit testing only. */ - @TestApi public static int computeMinSdkVersion(@IntRange(from = 1) int minVers, @Nullable String minCode, @IntRange(from = 1) int platformSdkVersion, @NonNull String[] platformSdkCodenames, @NonNull String[] outError) { @@ -4732,7 +4729,6 @@ public class PackageParser { * AndroidManifest.xml. * @hide Exposed for unit testing only. */ - @TestApi public static int getActivityConfigChanges(int configChanges, int recreateOnConfigChanges) { return configChanges | ((~recreateOnConfigChanges) & RECREATE_ON_CONFIG_CHANGES_MASK); } diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java index 0d7b695d7f1d..cbfe4fa58e40 100644 --- a/core/java/android/hardware/GeomagneticField.java +++ b/core/java/android/hardware/GeomagneticField.java @@ -16,7 +16,8 @@ package android.hardware; -import java.util.GregorianCalendar; +import java.util.Calendar; +import java.util.TimeZone; /** * Estimates magnetic field at a given point on @@ -26,7 +27,7 @@ import java.util.GregorianCalendar; * <p>This uses the World Magnetic Model produced by the United States National * Geospatial-Intelligence Agency. More details about the model can be found at * <a href="http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml">http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml</a>. - * This class currently uses WMM-2015 which is valid until 2020, but should + * This class currently uses WMM-2020 which is valid until 2025, but should * produce acceptable results for several years after that. Future versions of * Android may use a newer version of the model. */ @@ -48,69 +49,72 @@ public class GeomagneticField { static private final float EARTH_REFERENCE_RADIUS_KM = 6371.2f; // These coefficients and the formulae used below are from: - // NOAA Technical Report: The US/UK World Magnetic Model for 2015-2020 - static private final float[][] G_COEFF = new float[][] { - { 0.0f }, - { -29438.5f, -1501.1f }, - { -2445.3f, 3012.5f, 1676.6f }, - { 1351.1f, -2352.3f, 1225.6f, 581.9f }, - { 907.2f, 813.7f, 120.3f, -335.0f, 70.3f }, - { -232.6f, 360.1f, 192.4f, -141.0f, -157.4f, 4.3f }, - { 69.5f, 67.4f, 72.8f, -129.8f, -29.0f, 13.2f, -70.9f }, - { 81.6f, -76.1f, -6.8f, 51.9f, 15.0f, 9.3f, -2.8f, 6.7f }, - { 24.0f, 8.6f, -16.9f, -3.2f, -20.6f, 13.3f, 11.7f, -16.0f, -2.0f }, - { 5.4f, 8.8f, 3.1f, -3.1f, 0.6f, -13.3f, -0.1f, 8.7f, -9.1f, -10.5f }, - { -1.9f, -6.5f, 0.2f, 0.6f, -0.6f, 1.7f, -0.7f, 2.1f, 2.3f, -1.8f, -3.6f }, - { 3.1f, -1.5f, -2.3f, 2.1f, -0.9f, 0.6f, -0.7f, 0.2f, 1.7f, -0.2f, 0.4f, 3.5f }, - { -2.0f, -0.3f, 0.4f, 1.3f, -0.9f, 0.9f, 0.1f, 0.5f, -0.4f, -0.4f, 0.2f, -0.9f, 0.0f } }; - - static private final float[][] H_COEFF = new float[][] { - { 0.0f }, - { 0.0f, 4796.2f }, - { 0.0f, -2845.6f, -642.0f }, - { 0.0f, -115.3f, 245.0f, -538.3f }, - { 0.0f, 283.4f, -188.6f, 180.9f, -329.5f }, - { 0.0f, 47.4f, 196.9f, -119.4f, 16.1f, 100.1f }, - { 0.0f, -20.7f, 33.2f, 58.8f, -66.5f, 7.3f, 62.5f }, - { 0.0f, -54.1f, -19.4f, 5.6f, 24.4f, 3.3f, -27.5f, -2.3f }, - { 0.0f, 10.2f, -18.1f, 13.2f, -14.6f, 16.2f, 5.7f, -9.1f, 2.2f }, - { 0.0f, -21.6f, 10.8f, 11.7f, -6.8f, -6.9f, 7.8f, 1.0f, -3.9f, 8.5f }, - { 0.0f, 3.3f, -0.3f, 4.6f, 4.4f, -7.9f, -0.6f, -4.1f, -2.8f, -1.1f, -8.7f }, - { 0.0f, -0.1f, 2.1f, -0.7f, -1.1f, 0.7f, -0.2f, -2.1f, -1.5f, -2.5f, -2.0f, -2.3f }, - { 0.0f, -1.0f, 0.5f, 1.8f, -2.2f, 0.3f, 0.7f, -0.1f, 0.3f, 0.2f, -0.9f, -0.2f, 0.7f } }; - - static private final float[][] DELTA_G = new float[][] { - { 0.0f }, - { 10.7f, 17.9f }, - { -8.6f, -3.3f, 2.4f }, - { 3.1f, -6.2f, -0.4f, -10.4f }, - { -0.4f, 0.8f, -9.2f, 4.0f, -4.2f }, - { -0.2f, 0.1f, -1.4f, 0.0f, 1.3f, 3.8f }, - { -0.5f, -0.2f, -0.6f, 2.4f, -1.1f, 0.3f, 1.5f }, - { 0.2f, -0.2f, -0.4f, 1.3f, 0.2f, -0.4f, -0.9f, 0.3f }, - { 0.0f, 0.1f, -0.5f, 0.5f, -0.2f, 0.4f, 0.2f, -0.4f, 0.3f }, - { 0.0f, -0.1f, -0.1f, 0.4f, -0.5f, -0.2f, 0.1f, 0.0f, -0.2f, -0.1f }, - { 0.0f, 0.0f, -0.1f, 0.3f, -0.1f, -0.1f, -0.1f, 0.0f, -0.2f, -0.1f, -0.2f }, - { 0.0f, 0.0f, -0.1f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.1f, -0.1f }, - { 0.1f, 0.0f, 0.0f, 0.1f, -0.1f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }; - - static private final float[][] DELTA_H = new float[][] { - { 0.0f }, - { 0.0f, -26.8f }, - { 0.0f, -27.1f, -13.3f }, - { 0.0f, 8.4f, -0.4f, 2.3f }, - { 0.0f, -0.6f, 5.3f, 3.0f, -5.3f }, - { 0.0f, 0.4f, 1.6f, -1.1f, 3.3f, 0.1f }, - { 0.0f, 0.0f, -2.2f, -0.7f, 0.1f, 1.0f, 1.3f }, - { 0.0f, 0.7f, 0.5f, -0.2f, -0.1f, -0.7f, 0.1f, 0.1f }, - { 0.0f, -0.3f, 0.3f, 0.3f, 0.6f, -0.1f, -0.2f, 0.3f, 0.0f }, - { 0.0f, -0.2f, -0.1f, -0.2f, 0.1f, 0.1f, 0.0f, -0.2f, 0.4f, 0.3f }, - { 0.0f, 0.1f, -0.1f, 0.0f, 0.0f, -0.2f, 0.1f, -0.1f, -0.2f, 0.1f, -0.1f }, - { 0.0f, 0.0f, 0.1f, 0.0f, 0.1f, 0.0f, 0.0f, 0.1f, 0.0f, -0.1f, 0.0f, -0.1f }, - { 0.0f, 0.0f, 0.0f, -0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }; - - static private final long BASE_TIME = - new GregorianCalendar(2015, 1, 1).getTimeInMillis(); + // NOAA Technical Report: The US/UK World Magnetic Model for 2020-2025 + static private final float[][] G_COEFF = new float[][]{ + {0.0f}, + {-29404.5f, -1450.7f}, + {-2500.0f, 2982.0f, 1676.8f}, + {1363.9f, -2381.0f, 1236.2f, 525.7f}, + {903.1f, 809.4f, 86.2f, -309.4f, 47.9f}, + {-234.4f, 363.1f, 187.8f, -140.7f, -151.2f, 13.7f}, + {65.9f, 65.6f, 73.0f, -121.5f, -36.2f, 13.5f, -64.7f}, + {80.6f, -76.8f, -8.3f, 56.5f, 15.8f, 6.4f, -7.2f, 9.8f}, + {23.6f, 9.8f, -17.5f, -0.4f, -21.1f, 15.3f, 13.7f, -16.5f, -0.3f}, + {5.0f, 8.2f, 2.9f, -1.4f, -1.1f, -13.3f, 1.1f, 8.9f, -9.3f, -11.9f}, + {-1.9f, -6.2f, -0.1f, 1.7f, -0.9f, 0.6f, -0.9f, 1.9f, 1.4f, -2.4f, -3.9f}, + {3.0f, -1.4f, -2.5f, 2.4f, -0.9f, 0.3f, -0.7f, -0.1f, 1.4f, -0.6f, 0.2f, 3.1f}, + {-2.0f, -0.1f, 0.5f, 1.3f, -1.2f, 0.7f, 0.3f, 0.5f, -0.2f, -0.5f, 0.1f, -1.1f, -0.3f}}; + + static private final float[][] H_COEFF = new float[][]{ + {0.0f}, + {0.0f, 4652.9f}, + {0.0f, -2991.6f, -734.8f}, + {0.0f, -82.2f, 241.8f, -542.9f}, + {0.0f, 282.0f, -158.4f, 199.8f, -350.1f}, + {0.0f, 47.7f, 208.4f, -121.3f, 32.2f, 99.1f}, + {0.0f, -19.1f, 25.0f, 52.7f, -64.4f, 9.0f, 68.1f}, + {0.0f, -51.4f, -16.8f, 2.3f, 23.5f, -2.2f, -27.2f, -1.9f}, + {0.0f, 8.4f, -15.3f, 12.8f, -11.8f, 14.9f, 3.6f, -6.9f, 2.8f}, + {0.0f, -23.3f, 11.1f, 9.8f, -5.1f, -6.2f, 7.8f, 0.4f, -1.5f, 9.7f}, + {0.0f, 3.4f, -0.2f, 3.5f, 4.8f, -8.6f, -0.1f, -4.2f, -3.4f, -0.1f, -8.8f}, + {0.0f, 0.0f, 2.6f, -0.5f, -0.4f, 0.6f, -0.2f, -1.7f, -1.6f, -3.0f, -2.0f, -2.6f}, + {0.0f, -1.2f, 0.5f, 1.3f, -1.8f, 0.1f, 0.7f, -0.1f, 0.6f, 0.2f, -0.9f, 0.0f, 0.5f}}; + + static private final float[][] DELTA_G = new float[][]{ + {0.0f}, + {6.7f, 7.7f}, + {-11.5f, -7.1f, -2.2f}, + {2.8f, -6.2f, 3.4f, -12.2f}, + {-1.1f, -1.6f, -6.0f, 5.4f, -5.5f}, + {-0.3f, 0.6f, -0.7f, 0.1f, 1.2f, 1.0f}, + {-0.6f, -0.4f, 0.5f, 1.4f, -1.4f, 0.0f, 0.8f}, + {-0.1f, -0.3f, -0.1f, 0.7f, 0.2f, -0.5f, -0.8f, 1.0f}, + {-0.1f, 0.1f, -0.1f, 0.5f, -0.1f, 0.4f, 0.5f, 0.0f, 0.4f}, + {-0.1f, -0.2f, 0.0f, 0.4f, -0.3f, 0.0f, 0.3f, 0.0f, 0.0f, -0.4f}, + {0.0f, 0.0f, 0.0f, 0.2f, -0.1f, -0.2f, 0.0f, -0.1f, -0.2f, -0.1f, 0.0f}, + {0.0f, -0.1f, 0.0f, 0.0f, 0.0f, -0.1f, 0.0f, 0.0f, -0.1f, -0.1f, -0.1f, -0.1f}, + {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.1f}}; + + static private final float[][] DELTA_H = new float[][]{ + {0.0f}, + {0.0f, -25.1f}, + {0.0f, -30.2f, -23.9f}, + {0.0f, 5.7f, -1.0f, 1.1f}, + {0.0f, 0.2f, 6.9f, 3.7f, -5.6f}, + {0.0f, 0.1f, 2.5f, -0.9f, 3.0f, 0.5f}, + {0.0f, 0.1f, -1.8f, -1.4f, 0.9f, 0.1f, 1.0f}, + {0.0f, 0.5f, 0.6f, -0.7f, -0.2f, -1.2f, 0.2f, 0.3f}, + {0.0f, -0.3f, 0.7f, -0.2f, 0.5f, -0.3f, -0.5f, 0.4f, 0.1f}, + {0.0f, -0.3f, 0.2f, -0.4f, 0.4f, 0.1f, 0.0f, -0.2f, 0.5f, 0.2f}, + {0.0f, 0.0f, 0.1f, -0.3f, 0.1f, -0.2f, 0.1f, 0.0f, -0.1f, 0.2f, 0.0f}, + {0.0f, 0.0f, 0.1f, 0.0f, 0.2f, 0.0f, 0.0f, 0.1f, 0.0f, -0.1f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, -0.1f, 0.1f, 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, -0.1f}}; + + static private final long BASE_TIME = new Calendar.Builder() + .setTimeZone(TimeZone.getTimeZone("UTC")) + .setDate(2020, Calendar.JANUARY, 1) + .build() + .getTimeInMillis(); // The ratio between the Gauss-normalized associated Legendre functions and // the Schmid quasi-normalized ones. Compute these once staticly since they @@ -190,7 +194,7 @@ public class GeomagneticField { // We now compute the magnetic field strength given the geocentric // location. The magnetic field is the derivative of the potential // function defined by the model. See NOAA Technical Report: The US/UK - // World Magnetic Model for 2015-2020 for the derivation. + // World Magnetic Model for 2020-2025 for the derivation. float gcX = 0.0f; // Geocentric northwards component. float gcY = 0.0f; // Geocentric eastwards component. float gcZ = 0.0f; // Geocentric downwards component. @@ -203,7 +207,7 @@ public class GeomagneticField { // Negative derivative with respect to latitude, divided by // radius. This looks like the negation of the version in the - // NOAA Techincal report because that report used + // NOAA Technical report because that report used // P_n^m(sin(theta)) and we use P_n^m(cos(90 - theta)), so the // derivative with respect to theta is negated. gcX += relativeRadiusPower[n+2] 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/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index a29f8782601e..c60373c8d5b7 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2044,13 +2044,22 @@ public class ConnectivityManager { public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) { checkLegacyRoutingApiAccess(); try { - return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress()); + return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress(), + mContext.getOpPackageName(), getAttributionTag()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** + * @return the context's attribution tag + */ + // TODO: Remove method and replace with direct call once R code is pushed to AOSP + private @Nullable String getAttributionTag() { + return null; + } + + /** * Returns the value of the setting for background data usage. If false, * applications should not use the network if the application is not in the * foreground. Developers should respect this setting, and check the value @@ -2240,10 +2249,39 @@ public class ConnectivityManager { * services.jar, possibly in com.android.server.net. */ /** {@hide} */ - public static final void enforceChangePermission(Context context) { + public static final void enforceChangePermission(Context context, + String callingPkg, String callingAttributionTag) { int uid = Binder.getCallingUid(); - Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings - .getPackageNameForUid(context, uid), true /* throwException */); + checkAndNoteChangeNetworkStateOperation(context, uid, callingPkg, + callingAttributionTag, true /* throwException */); + } + + /** + * Check if the package is a allowed to change the network state. This also accounts that such + * an access happened. + * + * @return {@code true} iff the package is allowed to change the network state. + */ + // TODO: Remove method and replace with direct call once R code is pushed to AOSP + private static boolean checkAndNoteChangeNetworkStateOperation(@NonNull Context context, + int uid, @NonNull String callingPackage, @Nullable String callingAttributionTag, + boolean throwException) { + return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, callingPackage, + throwException); + } + + /** + * Check if the package is a allowed to write settings. This also accounts that such an access + * happened. + * + * @return {@code true} iff the package is allowed to write settings. + */ + // TODO: Remove method and replace with direct call once R code is pushed to AOSP + private static boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid, + @NonNull String callingPackage, @Nullable String callingAttributionTag, + boolean throwException) { + return Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPackage, + throwException); } /** @@ -3686,7 +3724,8 @@ public class ConnectivityManager { need, messenger, binder, callingPackageName); } else { request = mService.requestNetwork( - need, messenger, timeoutMs, binder, legacyType, callingPackageName); + need, messenger, timeoutMs, binder, legacyType, callingPackageName, + getAttributionTag()); } if (request != null) { sCallbacks.put(request, callback); @@ -3980,7 +4019,8 @@ public class ConnectivityManager { checkPendingIntentNotNull(operation); try { mService.pendingRequestForNetwork( - request.networkCapabilities, operation, mContext.getOpPackageName()); + request.networkCapabilities, operation, mContext.getOpPackageName(), + getAttributionTag()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (ServiceSpecificException e) { diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 69a47f24a0ab..d7f178cd0a9b 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -79,7 +79,8 @@ interface IConnectivityManager NetworkQuotaInfo getActiveNetworkQuotaInfo(); boolean isActiveNetworkMetered(); - boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress); + boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, + String callingPackageName, String callingAttributionTag); @UnsupportedAppUsage(maxTargetSdk = 29, publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative") @@ -170,10 +171,10 @@ interface IConnectivityManager NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, in Messenger messenger, int timeoutSec, in IBinder binder, int legacy, - String callingPackageName); + String callingPackageName, String callingAttributionTag); NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities, - in PendingIntent operation, String callingPackageName); + in PendingIntent operation, String callingPackageName, String callingAttributionTag); void releasePendingNetworkRequest(in PendingIntent operation); diff --git a/core/java/android/net/ITetheredInterfaceCallback.aidl b/core/java/android/net/ITetheredInterfaceCallback.aidl index e3d075988c8a..14aa0237f24a 100644 --- a/core/java/android/net/ITetheredInterfaceCallback.aidl +++ b/core/java/android/net/ITetheredInterfaceCallback.aidl @@ -17,7 +17,7 @@ package android.net; /** @hide */ -interface ITetheredInterfaceCallback { +oneway interface ITetheredInterfaceCallback { void onAvailable(in String iface); void onUnavailable(); }
\ No newline at end of file diff --git a/core/java/android/net/MatchAllNetworkSpecifier.java b/core/java/android/net/MatchAllNetworkSpecifier.java index 68a39355198b..70c4a7235b9d 100644 --- a/core/java/android/net/MatchAllNetworkSpecifier.java +++ b/core/java/android/net/MatchAllNetworkSpecifier.java @@ -43,7 +43,8 @@ public final class MatchAllNetworkSpecifier extends NetworkSpecifier implements } /** @hide */ - public boolean satisfiedBy(NetworkSpecifier other) { + @Override + public boolean canBeSatisfiedBy(NetworkSpecifier other) { /* * The method is called by a NetworkRequest to see if it is satisfied by a proposed * network (e.g. as offered by a network factory). Since MatchAllNetweorkSpecifier must diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index f807a4968d72..b872617ab31e 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; @@ -70,9 +71,9 @@ public class Network implements Parcelable { // 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 @@ -295,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; } /** @@ -365,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/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/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/ProxyInfo.java b/core/java/android/net/ProxyInfo.java index ffe9ae9521a8..a32b41f6be4b 100644 --- a/core/java/android/net/ProxyInfo.java +++ b/core/java/android/net/ProxyInfo.java @@ -127,18 +127,6 @@ public class ProxyInfo implements Parcelable { } /** - * Create a ProxyProperties that points at a PAC URL. - * @hide - */ - public ProxyInfo(String pacFileUrl) { - mHost = LOCAL_HOST; - mPort = LOCAL_PORT; - mExclusionList = LOCAL_EXCL_LIST; - mParsedExclusionList = parseExclusionList(mExclusionList); - mPacFileUrl = Uri.parse(pacFileUrl); - } - - /** * Only used in PacManager after Local Proxy is bound. * @hide */ diff --git a/core/java/android/net/http/OWNERS b/core/java/android/net/http/OWNERS index 309261277024..3271d243e2cd 100644 --- a/core/java/android/net/http/OWNERS +++ b/core/java/android/net/http/OWNERS @@ -1,4 +1,4 @@ narayan@google.com -tobiast@google.com +ngeoffray@google.com include platform/libcore:/OWNERS include platform/external/conscrypt:/OWNERS diff --git a/core/java/android/os/BadParcelableException.java b/core/java/android/os/BadParcelableException.java index 7e0b1a591d0a..9b1343ca7d82 100644 --- a/core/java/android/os/BadParcelableException.java +++ b/core/java/android/os/BadParcelableException.java @@ -32,4 +32,8 @@ public class BadParcelableException extends AndroidRuntimeException { public BadParcelableException(Exception cause) { super(cause); } + /** @hide */ + public BadParcelableException(String msg, Throwable cause) { + super(msg, cause); + } } diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index e5f07607d86a..947b77399e40 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -284,6 +284,8 @@ public class Binder implements IBinder { * system services to determine its identity and check permissions. * If the current thread is not currently executing an incoming transaction, * then its own pid is returned. + * + * Warning: oneway transactions do not receive PID. */ @CriticalNative public static final native int getCallingPid(); diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index b36aeb89c02a..e2486aff9d7c 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -106,6 +106,12 @@ public class Build { public static final String HARDWARE = getString("ro.hardware"); /** + * The hardware variant (SKU), if available. + */ + @NonNull + public static final String SKU = getString("ro.boot.hardware.sku"); + + /** * Whether this build was for an emulator device. * @hide */ diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 9f592e8d9718..4b2cfe222dd6 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -1115,8 +1115,6 @@ public final class Debug if (outStream != null) outStream.close(); } - - VMDebug.startEmulatorTracing(); } /** @@ -1130,8 +1128,6 @@ public final class Debug * region of code.</p> */ public static void stopNativeTracing() { - VMDebug.stopEmulatorTracing(); - // Open the sysfs file for writing and write "0" to it. PrintWriter outStream = null; try { @@ -1160,7 +1156,7 @@ public final class Debug * To temporarily enable tracing, use {@link #startNativeTracing()}. */ public static void enableEmulatorTraceOutput() { - VMDebug.startEmulatorTracing(); + Log.w(TAG, "Unimplemented"); } /** @@ -2097,25 +2093,6 @@ public final class Debug public static final native int getBinderDeathObjectCount(); /** - * Primes the register map cache. - * - * Only works for classes in the bootstrap class loader. Does not - * cause classes to be loaded if they're not already present. - * - * The classAndMethodDesc argument is a concatentation of the VM-internal - * class descriptor, method name, and method descriptor. Examples: - * Landroid/os/Looper;.loop:()V - * Landroid/app/ActivityThread;.main:([Ljava/lang/String;)V - * - * @param classAndMethodDesc the method to prepare - * - * @hide - */ - public static final boolean cacheRegisterMap(String classAndMethodDesc) { - return VMDebug.cacheRegisterMap(classAndMethodDesc); - } - - /** * Dumps the contents of VM reference tables (e.g. JNI locals and * globals) to the log file. * diff --git a/core/java/android/os/HandlerThread.java b/core/java/android/os/HandlerThread.java index 92fcbb65b106..4dd797a70fcb 100644 --- a/core/java/android/os/HandlerThread.java +++ b/core/java/android/os/HandlerThread.java @@ -71,23 +71,35 @@ public class HandlerThread extends Thread { /** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason isAlive() returns false, this method will return null. If this thread - * has been started, this method will block until the looper has been initialized. + * has been started, this method will block until the looper has been initialized. * @return The looper. */ public Looper getLooper() { if (!isAlive()) { return null; } - + + boolean wasInterrupted = false; + // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { + wasInterrupted = true; } } } + + /* + * We may need to restore the thread's interrupted flag, because it may + * have been cleared above since we eat InterruptedExceptions + */ + if (wasInterrupted) { + Thread.currentThread().interrupt(); + } + return mLooper; } diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java index 7c42c36e7747..64ab1d711765 100644 --- a/core/java/android/os/HwBinder.java +++ b/core/java/android/os/HwBinder.java @@ -96,6 +96,15 @@ public abstract class HwBinder implements IHwBinder { throws RemoteException, NoSuchElementException; /** + * This allows getService to bypass the VINTF manifest for testing only. + * + * Disabled on user builds. + * @hide + */ + public static native final void setTrebleTestingOverride( + boolean testingOverride); + + /** * Configures how many threads the process-wide hwbinder threadpool * has to process incoming requests. * diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 486ec2ab2b88..8a8a6af09e5f 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -313,13 +313,16 @@ public interface IBinder { * then the given {@link DeathRecipient}'s * {@link DeathRecipient#binderDied DeathRecipient.binderDied()} method * will be called. - * + * + * <p>This will automatically be unlinked when all references to the linked + * binder proxy are dropped.</p> + * * <p>You will only receive death notifications for remote binders, - * as local binders by definition can't die without you dying as well. - * + * as local binders by definition can't die without you dying as well.</p> + * * @throws RemoteException if the target IBinder's * process has already died. - * + * * @see #unlinkToDeath */ public void linkToDeath(@NonNull DeathRecipient recipient, int flags) diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index 1a3cf2d2c634..7213b067a691 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -726,7 +726,7 @@ public final class MessageQueue { Message n = p.next; if (n != null) { if (n.target == h && n.what == what - && (object == null || object.equals(n.obj))) { + && (object == null || object.equals(n.obj))) { Message nn = n.next; n.recycleUnchecked(); p.next = nn; @@ -794,7 +794,7 @@ public final class MessageQueue { Message n = p.next; if (n != null) { if (n.target == h && n.callback == r - && (object == null || object.equals(n.obj))) { + && (object == null || object.equals(n.obj))) { Message nn = n.next; n.recycleUnchecked(); p.next = nn; diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index e5bab6fc9230..7b82b1a2e0d4 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -3358,15 +3358,15 @@ public final class Parcel { } catch (IllegalAccessException e) { Log.e(TAG, "Illegal access when unmarshalling: " + name, e); throw new BadParcelableException( - "IllegalAccessException when unmarshalling: " + name); + "IllegalAccessException when unmarshalling: " + name, e); } catch (ClassNotFoundException e) { Log.e(TAG, "Class not found when unmarshalling: " + name, e); throw new BadParcelableException( - "ClassNotFoundException when unmarshalling: " + name); + "ClassNotFoundException when unmarshalling: " + name, e); } catch (NoSuchFieldException e) { throw new BadParcelableException("Parcelable protocol requires a " + "Parcelable.Creator object called " - + "CREATOR on class " + name); + + "CREATOR on class " + name, e); } if (creator == null) { throw new BadParcelableException("Parcelable protocol requires a " diff --git a/core/java/android/os/Parcelable.java b/core/java/android/os/Parcelable.java index 6632ca51e74c..9b360edb7238 100644 --- a/core/java/android/os/Parcelable.java +++ b/core/java/android/os/Parcelable.java @@ -118,7 +118,21 @@ public interface Parcelable { * by this Parcelable object instance. */ public @ContentsFlags int describeContents(); - + + /** + * 'Stable' means this parcelable is guaranteed to be stable for multiple years. + * It must be guaranteed by setting stability field in aidl_interface, + * OR explicitly override this method from @JavaOnlyStableParcelable marked Parcelable. + * WARNING: isStable() is only expected to be overridden by auto-generated code, + * OR @JavaOnlyStableParcelable marked Parcelable only if there is guaranteed to + * be only once copy of the parcelable on the system. + * @return true if this parcelable is stable. + * @hide + */ + default boolean isStable() { + return false; + } + /** * Flatten this object in to a Parcel. * diff --git a/core/java/android/os/ParcelableHolder.java b/core/java/android/os/ParcelableHolder.java new file mode 100644 index 000000000000..c37a2ff1112c --- /dev/null +++ b/core/java/android/os/ParcelableHolder.java @@ -0,0 +1,177 @@ +/* + * 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.os; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.util.MathUtils; + +/** + * Parcelable containing the other Parcelable object. + * @hide + */ +public final class ParcelableHolder implements Parcelable { + /** + * This is set by {@link #setParcelable}. + * {@link #mParcelable} and {@link #mParcel} are mutually exclusive + * if {@link ParcelableHolder} contains value, otherwise, both are null. + */ + private Parcelable mParcelable; + /** + * This is set by {@link #readFromParcel}. + * {@link #mParcelable} and {@link #mParcel} are mutually exclusive + * if {@link ParcelableHolder} contains value, otherwise, both are null. + */ + private Parcel mParcel; + private boolean mIsStable = false; + + public ParcelableHolder(boolean isStable) { + mIsStable = isStable; + } + + private ParcelableHolder() { + + } + + /** + * {@link ParcelableHolder}'s stability is determined by the parcelable + * which contains this ParcelableHolder. + * For more detail refer to {@link Parcelable#isStable}. + */ + @Override + public boolean isStable() { + return mIsStable; + } + + @NonNull + public static final Parcelable.Creator<ParcelableHolder> CREATOR = + new Parcelable.Creator<ParcelableHolder>() { + @NonNull + @Override + public ParcelableHolder createFromParcel(@NonNull Parcel parcel) { + ParcelableHolder parcelable = new ParcelableHolder(); + parcelable.readFromParcel(parcel); + return parcelable; + } + + @NonNull + @Override + public ParcelableHolder[] newArray(int size) { + return new ParcelableHolder[size]; + } + }; + + + /** + * Write a parcelable into ParcelableHolder, the previous parcelable will be removed. + * @return {@code false} if the parcelable's stability is more unstable ParcelableHolder. + */ + public synchronized boolean setParcelable(@Nullable Parcelable p) { + if (p != null && this.isStable() && !p.isStable()) { + return false; + } + mParcelable = p; + if (mParcel != null) { + mParcel.recycle(); + mParcel = null; + } + return true; + } + + /** + * @return the parcelable that was written by {@link #setParcelable} or {@link #readFromParcel}, + * or {@code null} if the parcelable has not been written, or T is different from + * the type written by (@link #setParcelable}. + */ + @Nullable + public synchronized <T extends Parcelable> T getParcelable(@NonNull Class<T> clazz) { + if (mParcel == null) { + if (!clazz.isInstance(mParcelable)) { + return null; + } + return (T) mParcelable; + } + + mParcel.setDataPosition(0); + + T parcelable = mParcel.readParcelable(clazz.getClassLoader()); + if (!clazz.isInstance(parcelable)) { + return null; + } + mParcelable = parcelable; + + mParcel.recycle(); + mParcel = null; + return parcelable; + } + + /** + * Read ParcelableHolder from a parcel. + */ + public synchronized void readFromParcel(@NonNull Parcel parcel) { + this.mIsStable = parcel.readBoolean(); + + mParcelable = null; + + if (mParcel == null) { + mParcel = Parcel.obtain(); + } + mParcel.setDataPosition(0); + mParcel.setDataSize(0); + + int dataSize = parcel.readInt(); + if (dataSize < 0) { + throw new IllegalArgumentException("dataSize from parcel is negative"); + } + int dataStartPos = parcel.dataPosition(); + + mParcel.appendFrom(parcel, dataStartPos, dataSize); + parcel.setDataPosition(MathUtils.addOrThrow(dataStartPos, dataSize)); + } + + @Override + public synchronized void writeToParcel(@NonNull Parcel parcel, int flags) { + parcel.writeBoolean(this.mIsStable); + + if (mParcel != null) { + parcel.writeInt(mParcel.dataSize()); + parcel.appendFrom(mParcel, 0, mParcel.dataSize()); + return; + } + + int sizePos = parcel.dataPosition(); + parcel.writeInt(0); + int dataStartPos = parcel.dataPosition(); + parcel.writeParcelable(mParcelable, 0); + int dataSize = parcel.dataPosition() - dataStartPos; + + parcel.setDataPosition(sizePos); + parcel.writeInt(dataSize); + parcel.setDataPosition(MathUtils.addOrThrow(parcel.dataPosition(), dataSize)); + } + + @Override + public synchronized int describeContents() { + if (mParcel != null) { + return mParcel.hasFileDescriptors() ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0; + } + if (mParcelable != null) { + return mParcelable.describeContents(); + } + return 0; + } +} diff --git a/core/java/android/os/Registrant.java b/core/java/android/os/Registrant.java index d6afd049f156..bde7ec14f37a 100644 --- a/core/java/android/os/Registrant.java +++ b/core/java/android/os/Registrant.java @@ -46,7 +46,7 @@ public class Registrant { internalNotifyRegistrant (null, null); } - + @UnsupportedAppUsage public void notifyResult(Object result) @@ -81,9 +81,7 @@ public class Registrant Message msg = Message.obtain(); msg.what = what; - msg.obj = new AsyncResult(userObj, result, exception); - h.sendMessage(msg); } } @@ -126,4 +124,3 @@ public class Registrant int what; Object userObj; } - diff --git a/core/java/android/os/RegistrantList.java b/core/java/android/os/RegistrantList.java index 81750021fdd5..b36734bcd199 100644 --- a/core/java/android/os/RegistrantList.java +++ b/core/java/android/os/RegistrantList.java @@ -42,9 +42,9 @@ public class RegistrantList { // if the handler is already in the registrant list, remove it remove(h); - add(new Registrant(h, what, obj)); + add(new Registrant(h, what, obj)); } - + @UnsupportedAppUsage public synchronized void add(Registrant r) @@ -59,7 +59,7 @@ public class RegistrantList { for (int i = registrants.size() - 1; i >= 0 ; i--) { Registrant r = (Registrant) registrants.get(i); - + if (r.refH == null) { registrants.remove(i); } @@ -92,7 +92,7 @@ public class RegistrantList r.internalNotifyRegistrant(result, exception); } } - + @UnsupportedAppUsage public /*synchronized*/ void notifyRegistrants() @@ -113,14 +113,14 @@ public class RegistrantList internalNotifyRegistrants (result, null); } - + @UnsupportedAppUsage public /*synchronized*/ void notifyRegistrants(AsyncResult ar) { internalNotifyRegistrants(ar.result, ar.exception); } - + @UnsupportedAppUsage public synchronized void remove(Handler h) diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index e86aa62d00bc..b45a1eba1e2f 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -119,6 +119,14 @@ public final class DeviceConfig { public static final String NAMESPACE_BLOBSTORE = "blobstore"; /** + * Namespace for all Bluetooth related features. + * + * @hide + */ + @SystemApi + public static final String NAMESPACE_BLUETOOTH = "bluetooth"; + + /** * Namespace for all networking connectivity related features. * * @hide diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 64d9c9dcc6e0..9ee88982f598 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11618,17 +11618,6 @@ public final class Settings { public static final String ALWAYS_ON_DISPLAY_CONSTANTS = "always_on_display_constants"; /** - * System VDSO global setting. This links to the "sys.vdso" system property. - * The following values are supported: - * false -> both 32 and 64 bit vdso disabled - * 32 -> 32 bit vdso enabled - * 64 -> 64 bit vdso enabled - * Any other value defaults to both 32 bit and 64 bit true. - * @hide - */ - public static final String SYS_VDSO = "sys_vdso"; - - /** * UidCpuPower global setting. This links the sys.uidcpupower system property. * The following values are supported: * 0 -> /proc/uid_cpupower/* are disabled diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index 2c66910529f1..fab70844989b 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -1357,8 +1357,7 @@ public final class Telephony { Object[] messages; try { messages = (Object[]) intent.getSerializableExtra("pdus"); - } - catch (ClassCastException e) { + } catch (ClassCastException e) { Rlog.e(TAG, "getMessagesFromIntent: " + e); return null; } @@ -1370,9 +1369,12 @@ public final class Telephony { String format = intent.getStringExtra("format"); int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, - SubscriptionManager.getDefaultSmsSubscriptionId()); - - Rlog.v(TAG, " getMessagesFromIntent sub_id : " + subId); + SubscriptionManager.INVALID_SUBSCRIPTION_ID); + if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + Rlog.v(TAG, "getMessagesFromIntent with valid subId : " + subId); + } else { + Rlog.v(TAG, "getMessagesFromIntent"); + } int pduCount = messages.length; SmsMessage[] msgs = new SmsMessage[pduCount]; diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 4adcd6948f85..a6e6d057d48c 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -780,7 +780,8 @@ public class PhoneStateListener { * */ @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) { + public void onCallDisconnectCauseChanged(@Annotation.DisconnectCauses int disconnectCause, + int preciseDisconnectCause) { // default implementation empty } diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 0854452e6886..8ab120f78835 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -18,7 +18,6 @@ package android.telephony; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; -import android.annotation.TestApi; import android.compat.Compatibility; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; @@ -283,7 +282,6 @@ public class TelephonyRegistryManager { * @param incomingNumber incoming phone number. * @hide */ - @TestApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyCallStateChangedForAllSubscriptions(@CallState int state, @Nullable String incomingNumber) { diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java index 0863a813543c..4fe6752be4d5 100755 --- a/core/java/android/text/format/DateFormat.java +++ b/core/java/android/text/format/DateFormat.java @@ -19,12 +19,13 @@ package android.text.format; import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.icu.text.DateFormatSymbols; +import android.icu.text.DateTimePatternGenerator; import android.provider.Settings; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.SpannedString; -import libcore.icu.ICU; import libcore.icu.LocaleData; import java.text.SimpleDateFormat; @@ -251,7 +252,8 @@ public class DateFormat { * @return a string pattern suitable for use with {@link java.text.SimpleDateFormat}. */ public static String getBestDateTimePattern(Locale locale, String skeleton) { - return ICU.getBestDateTimePattern(skeleton, locale); + DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(locale); + return dtpg.getBestPattern(skeleton); } /** @@ -333,7 +335,52 @@ public class DateFormat { * order returned here. */ public static char[] getDateFormatOrder(Context context) { - return ICU.getDateFormatOrder(getDateFormatString(context)); + return getDateFormatOrder(getDateFormatString(context)); + } + + /** + * @hide Used by internal framework class {@link android.widget.DatePickerSpinnerDelegate}. + */ + public static char[] getDateFormatOrder(String pattern) { + char[] result = new char[3]; + int resultIndex = 0; + boolean sawDay = false; + boolean sawMonth = false; + boolean sawYear = false; + + for (int i = 0; i < pattern.length(); ++i) { + char ch = pattern.charAt(i); + if (ch == 'd' || ch == 'L' || ch == 'M' || ch == 'y') { + if (ch == 'd' && !sawDay) { + result[resultIndex++] = 'd'; + sawDay = true; + } else if ((ch == 'L' || ch == 'M') && !sawMonth) { + result[resultIndex++] = 'M'; + sawMonth = true; + } else if ((ch == 'y') && !sawYear) { + result[resultIndex++] = 'y'; + sawYear = true; + } + } else if (ch == 'G') { + // Ignore the era specifier, if present. + } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { + throw new IllegalArgumentException("Bad pattern character '" + ch + "' in " + + pattern); + } else if (ch == '\'') { + if (i < pattern.length() - 1 && pattern.charAt(i + 1) == '\'') { + ++i; + } else { + i = pattern.indexOf('\'', i + 1); + if (i == -1) { + throw new IllegalArgumentException("Bad quoting in " + pattern); + } + ++i; + } + } else { + // Ignore spaces and punctuation. + } + } + return result; } private static String getDateFormatString(Context context) { @@ -429,6 +476,8 @@ public class DateFormat { int count; LocaleData localeData = LocaleData.get(Locale.getDefault()); + DateFormatSymbols dfs = getIcuDateFormatSymbols(Locale.getDefault()); + String[] amPm = dfs.getAmPmStrings(); int len = inFormat.length(); @@ -450,7 +499,7 @@ public class DateFormat { switch (c) { case 'A': case 'a': - replacement = localeData.amPm[inDate.get(Calendar.AM_PM) - Calendar.AM]; + replacement = amPm[inDate.get(Calendar.AM_PM) - Calendar.AM]; break; case 'd': replacement = zeroPad(inDate.get(Calendar.DATE), count); @@ -632,4 +681,16 @@ public class DateFormat { private static String zeroPad(int inValue, int inMinDigits) { return String.format(Locale.getDefault(), "%0" + inMinDigits + "d", inValue); } + + /** + * We use Gregorian calendar for date formats in android.text.format and various UI widget + * historically. It's a utility method to get an {@link DateFormatSymbols} instance. Note that + * {@link DateFormatSymbols} has cache, and external cache is not needed unless same instance is + * requested repeatedly in the performance critical code. + * + * @hide + */ + public static DateFormatSymbols getIcuDateFormatSymbols(Locale locale) { + return new DateFormatSymbols(android.icu.util.GregorianCalendar.class, locale); + } } diff --git a/core/java/android/text/format/DateIntervalFormat.java b/core/java/android/text/format/DateIntervalFormat.java new file mode 100644 index 000000000000..de9ec7ab9ea9 --- /dev/null +++ b/core/java/android/text/format/DateIntervalFormat.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2013 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.text.format; + +import static android.text.format.DateUtils.FORMAT_SHOW_TIME; +import static android.text.format.DateUtils.FORMAT_UTC; + +import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; + +import android.icu.util.Calendar; +import android.icu.util.ULocale; +import android.util.LruCache; + +import com.android.internal.annotations.VisibleForTesting; + +import java.text.FieldPosition; +import java.util.TimeZone; + +/** + * A wrapper of {@link android.icu.text.DateIntervalFormat} used by {@link DateUtilsBridge}. + * + * @hide + */ +@VisibleForTesting(visibility = PACKAGE) +public final class DateIntervalFormat { + + private static final LruCache<String, android.icu.text.DateIntervalFormat> CACHED_FORMATTERS = + new LruCache<>(8); + + private DateIntervalFormat() { + } + + /** + * Format a date range. + */ + @VisibleForTesting(visibility = PACKAGE) + public static String formatDateRange(long startMs, long endMs, int flags, String olsonId) { + if ((flags & FORMAT_UTC) != 0) { + olsonId = "UTC"; + } + // We create a java.util.TimeZone here to use libcore's data and libcore's olson ID / + // pseudo-tz logic. + TimeZone tz = (olsonId != null) ? TimeZone.getTimeZone(olsonId) : TimeZone.getDefault(); + android.icu.util.TimeZone icuTimeZone = DateUtilsBridge.icuTimeZone(tz); + ULocale icuLocale = ULocale.getDefault(); + return formatDateRange(icuLocale, icuTimeZone, startMs, endMs, flags); + } + + /** + * Format a date range. This is our slightly more sensible internal API. + * A truly sane replacement would take a skeleton instead of int flags. + */ + @VisibleForTesting(visibility = PACKAGE) + public static String formatDateRange(ULocale icuLocale, android.icu.util.TimeZone icuTimeZone, + long startMs, long endMs, int flags) { + Calendar startCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, startMs); + Calendar endCalendar; + if (startMs == endMs) { + endCalendar = startCalendar; + } else { + endCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, endMs); + } + + // Special handling when the range ends at midnight: + // - If we're not showing times, and the range is non-empty, we fudge the end date so we + // don't count the day that's about to start. + // - If we are showing times, and the range ends at exactly 00:00 of the day following + // its start (which can be thought of as 24:00 the same day), we fudge the end date so we + // don't show the dates --- unless the start is anything displayed as 00:00, in which case + // we include both dates to disambiguate. + // This is not the behavior of icu4j's DateIntervalFormat, but it's the required behavior + // of Android's DateUtils.formatDateRange. + if (isExactlyMidnight(endCalendar)) { + boolean showTime = (flags & FORMAT_SHOW_TIME) == FORMAT_SHOW_TIME; + boolean endsDayAfterStart = DateUtilsBridge.dayDistance(startCalendar, endCalendar) + == 1; + if ((!showTime && startMs != endMs) + || (endsDayAfterStart + && !DateUtilsBridge.isDisplayMidnightUsingSkeleton(startCalendar))) { + endCalendar.add(Calendar.DAY_OF_MONTH, -1); + } + } + + String skeleton = DateUtilsBridge.toSkeleton(startCalendar, endCalendar, flags); + synchronized (CACHED_FORMATTERS) { + android.icu.text.DateIntervalFormat formatter = + getFormatter(skeleton, icuLocale, icuTimeZone); + return formatter.format(startCalendar, endCalendar, new StringBuffer(), + new FieldPosition(0)).toString(); + } + } + + private static android.icu.text.DateIntervalFormat getFormatter(String skeleton, ULocale locale, + android.icu.util.TimeZone icuTimeZone) { + String key = skeleton + "\t" + locale + "\t" + icuTimeZone; + android.icu.text.DateIntervalFormat formatter = CACHED_FORMATTERS.get(key); + if (formatter != null) { + return formatter; + } + formatter = android.icu.text.DateIntervalFormat.getInstance(skeleton, locale); + formatter.setTimeZone(icuTimeZone); + CACHED_FORMATTERS.put(key, formatter); + return formatter; + } + + private static boolean isExactlyMidnight(Calendar c) { + return c.get(Calendar.HOUR_OF_DAY) == 0 + && c.get(Calendar.MINUTE) == 0 + && c.get(Calendar.SECOND) == 0 + && c.get(Calendar.MILLISECOND) == 0; + } +} diff --git a/core/java/android/text/format/DateTimeFormat.java b/core/java/android/text/format/DateTimeFormat.java new file mode 100644 index 000000000000..064d7172c44f --- /dev/null +++ b/core/java/android/text/format/DateTimeFormat.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2015 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.text.format; + +import android.icu.text.DateFormat; +import android.icu.text.DateTimePatternGenerator; +import android.icu.text.DisplayContext; +import android.icu.text.SimpleDateFormat; +import android.icu.util.Calendar; +import android.icu.util.ULocale; +import android.util.LruCache; + +/** + * A formatter that outputs a single date/time. + * + * @hide + */ +class DateTimeFormat { + private static final FormatterCache CACHED_FORMATTERS = new FormatterCache(); + + static class FormatterCache extends LruCache<String, DateFormat> { + FormatterCache() { + super(8); + } + } + + private DateTimeFormat() { + } + + public static String format(ULocale icuLocale, Calendar time, int flags, + DisplayContext displayContext) { + String skeleton = DateUtilsBridge.toSkeleton(time, flags); + String key = skeleton + "\t" + icuLocale + "\t" + time.getTimeZone(); + synchronized (CACHED_FORMATTERS) { + DateFormat formatter = CACHED_FORMATTERS.get(key); + if (formatter == null) { + DateTimePatternGenerator generator = DateTimePatternGenerator.getInstance( + icuLocale); + formatter = new SimpleDateFormat(generator.getBestPattern(skeleton), icuLocale); + CACHED_FORMATTERS.put(key, formatter); + } + formatter.setContext(displayContext); + return formatter.format(time); + } + } +} diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java index ce676e0908cd..741312f2337e 100644 --- a/core/java/android/text/format/DateUtils.java +++ b/core/java/android/text/format/DateUtils.java @@ -27,9 +27,7 @@ import android.icu.util.MeasureUnit; import com.android.internal.R; -import libcore.icu.DateIntervalFormat; import libcore.icu.LocaleData; -import libcore.icu.RelativeDateTimeFormatter; import java.io.IOException; import java.time.Instant; @@ -227,7 +225,8 @@ public class DateUtils */ @Deprecated public static String getAMPMString(int ampm) { - return LocaleData.get(Locale.getDefault()).amPm[ampm - Calendar.AM]; + String[] amPm = DateFormat.getIcuDateFormatSymbols(Locale.getDefault()).getAmPmStrings(); + return amPm[ampm - Calendar.AM]; } /** diff --git a/core/java/android/text/format/DateUtilsBridge.java b/core/java/android/text/format/DateUtilsBridge.java new file mode 100644 index 000000000000..92ec9cf6d736 --- /dev/null +++ b/core/java/android/text/format/DateUtilsBridge.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2015 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.text.format; + +import static android.text.format.DateUtils.FORMAT_12HOUR; +import static android.text.format.DateUtils.FORMAT_24HOUR; +import static android.text.format.DateUtils.FORMAT_ABBREV_ALL; +import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH; +import static android.text.format.DateUtils.FORMAT_ABBREV_TIME; +import static android.text.format.DateUtils.FORMAT_ABBREV_WEEKDAY; +import static android.text.format.DateUtils.FORMAT_NO_MONTH_DAY; +import static android.text.format.DateUtils.FORMAT_NO_YEAR; +import static android.text.format.DateUtils.FORMAT_NUMERIC_DATE; +import static android.text.format.DateUtils.FORMAT_SHOW_DATE; +import static android.text.format.DateUtils.FORMAT_SHOW_TIME; +import static android.text.format.DateUtils.FORMAT_SHOW_WEEKDAY; +import static android.text.format.DateUtils.FORMAT_SHOW_YEAR; + +import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; + +import android.icu.util.Calendar; +import android.icu.util.GregorianCalendar; +import android.icu.util.TimeZone; +import android.icu.util.ULocale; + +import com.android.internal.annotations.VisibleForTesting; + +/** + * Common methods and constants for the various ICU formatters used to support {@link + * android.text.format.DateUtils}. + * + * @hide + */ +@VisibleForTesting(visibility = PACKAGE) +public final class DateUtilsBridge { + + /** + * Creates an immutable ICU timezone backed by the specified libcore timezone data. At the time + * of writing the libcore implementation is faster but restricted to 1902 - 2038. Callers must + * not modify the {@code tz} after calling this method. + */ + public static TimeZone icuTimeZone(java.util.TimeZone tz) { + TimeZone icuTimeZone = TimeZone.getTimeZone(tz.getID()); + icuTimeZone.freeze(); // Optimization - allows the timezone to be copied cheaply. + return icuTimeZone; + } + + /** + * Create a GregorianCalendar based on the arguments + */ + public static Calendar createIcuCalendar(TimeZone icuTimeZone, ULocale icuLocale, + long timeInMillis) { + Calendar calendar = new GregorianCalendar(icuTimeZone, icuLocale); + calendar.setTimeInMillis(timeInMillis); + return calendar; + } + + public static String toSkeleton(Calendar calendar, int flags) { + return toSkeleton(calendar, calendar, flags); + } + + public static String toSkeleton(Calendar startCalendar, Calendar endCalendar, int flags) { + if ((flags & FORMAT_ABBREV_ALL) != 0) { + flags |= FORMAT_ABBREV_MONTH | FORMAT_ABBREV_TIME | FORMAT_ABBREV_WEEKDAY; + } + + String monthPart = "MMMM"; + if ((flags & FORMAT_NUMERIC_DATE) != 0) { + monthPart = "M"; + } else if ((flags & FORMAT_ABBREV_MONTH) != 0) { + monthPart = "MMM"; + } + + String weekPart = "EEEE"; + if ((flags & FORMAT_ABBREV_WEEKDAY) != 0) { + weekPart = "EEE"; + } + + String timePart = "j"; // "j" means choose 12 or 24 hour based on current locale. + if ((flags & FORMAT_24HOUR) != 0) { + timePart = "H"; + } else if ((flags & FORMAT_12HOUR) != 0) { + timePart = "h"; + } + + // If we've not been asked to abbreviate times, or we're using the 24-hour clock (where it + // never makes sense to leave out the minutes), include minutes. This gets us times like + // "4 PM" while avoiding times like "16" (for "16:00"). + if ((flags & FORMAT_ABBREV_TIME) == 0 || (flags & FORMAT_24HOUR) != 0) { + timePart += "m"; + } else { + // Otherwise, we're abbreviating a 12-hour time, and should only show the minutes + // if they're not both "00". + if (!(onTheHour(startCalendar) && onTheHour(endCalendar))) { + timePart = timePart + "m"; + } + } + + if (fallOnDifferentDates(startCalendar, endCalendar)) { + flags |= FORMAT_SHOW_DATE; + } + + if (fallInSameMonth(startCalendar, endCalendar) && (flags & FORMAT_NO_MONTH_DAY) != 0) { + flags &= (~FORMAT_SHOW_WEEKDAY); + flags &= (~FORMAT_SHOW_TIME); + } + + if ((flags & (FORMAT_SHOW_DATE | FORMAT_SHOW_TIME | FORMAT_SHOW_WEEKDAY)) == 0) { + flags |= FORMAT_SHOW_DATE; + } + + // If we've been asked to show the date, work out whether we think we should show the year. + if ((flags & FORMAT_SHOW_DATE) != 0) { + if ((flags & FORMAT_SHOW_YEAR) != 0) { + // The caller explicitly wants us to show the year. + } else if ((flags & FORMAT_NO_YEAR) != 0) { + // The caller explicitly doesn't want us to show the year, even if we otherwise + // would. + } else if (!fallInSameYear(startCalendar, endCalendar) || !isThisYear(startCalendar)) { + flags |= FORMAT_SHOW_YEAR; + } + } + + StringBuilder builder = new StringBuilder(); + if ((flags & (FORMAT_SHOW_DATE | FORMAT_NO_MONTH_DAY)) != 0) { + if ((flags & FORMAT_SHOW_YEAR) != 0) { + builder.append("y"); + } + builder.append(monthPart); + if ((flags & FORMAT_NO_MONTH_DAY) == 0) { + builder.append("d"); + } + } + if ((flags & FORMAT_SHOW_WEEKDAY) != 0) { + builder.append(weekPart); + } + if ((flags & FORMAT_SHOW_TIME) != 0) { + builder.append(timePart); + } + return builder.toString(); + } + + public static int dayDistance(Calendar c1, Calendar c2) { + return c2.get(Calendar.JULIAN_DAY) - c1.get(Calendar.JULIAN_DAY); + } + + /** + * Returns whether the argument will be displayed as if it were midnight, using any of the + * skeletons provided by {@link #toSkeleton}. + */ + public static boolean isDisplayMidnightUsingSkeleton(Calendar c) { + // All the skeletons returned by toSkeleton have minute precision (they may abbreviate + // 4:00 PM to 4 PM but will still show the following minute as 4:01 PM). + return c.get(Calendar.HOUR_OF_DAY) == 0 && c.get(Calendar.MINUTE) == 0; + } + + private static boolean onTheHour(Calendar c) { + return c.get(Calendar.MINUTE) == 0 && c.get(Calendar.SECOND) == 0; + } + + private static boolean fallOnDifferentDates(Calendar c1, Calendar c2) { + return c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR) + || c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH) + || c1.get(Calendar.DAY_OF_MONTH) != c2.get(Calendar.DAY_OF_MONTH); + } + + private static boolean fallInSameMonth(Calendar c1, Calendar c2) { + return c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH); + } + + private static boolean fallInSameYear(Calendar c1, Calendar c2) { + return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR); + } + + private static boolean isThisYear(Calendar c) { + Calendar now = (Calendar) c.clone(); + now.setTimeInMillis(System.currentTimeMillis()); + return c.get(Calendar.YEAR) == now.get(Calendar.YEAR); + } +} diff --git a/core/java/android/text/format/RelativeDateTimeFormatter.java b/core/java/android/text/format/RelativeDateTimeFormatter.java new file mode 100644 index 000000000000..9096469699c1 --- /dev/null +++ b/core/java/android/text/format/RelativeDateTimeFormatter.java @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2015 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.text.format; + +import static android.text.format.DateUtils.FORMAT_ABBREV_ALL; +import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH; +import static android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE; +import static android.text.format.DateUtils.FORMAT_NO_YEAR; +import static android.text.format.DateUtils.FORMAT_NUMERIC_DATE; +import static android.text.format.DateUtils.FORMAT_SHOW_DATE; +import static android.text.format.DateUtils.FORMAT_SHOW_TIME; +import static android.text.format.DateUtils.FORMAT_SHOW_YEAR; + +import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; + +import android.icu.text.DisplayContext; +import android.icu.util.Calendar; +import android.icu.util.ULocale; +import android.util.LruCache; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.Locale; + +/** + * Exposes icu4j's RelativeDateTimeFormatter. + * + * @hide + */ +@VisibleForTesting(visibility = PACKAGE) +public final class RelativeDateTimeFormatter { + + public static final long SECOND_IN_MILLIS = 1000; + public static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60; + public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60; + public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24; + public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7; + // YEAR_IN_MILLIS considers 364 days as a year. However, since this + // constant comes from public API in DateUtils, it cannot be fixed here. + public static final long YEAR_IN_MILLIS = WEEK_IN_MILLIS * 52; + + private static final int DAY_IN_MS = 24 * 60 * 60 * 1000; + private static final int EPOCH_JULIAN_DAY = 2440588; + + private static final FormatterCache CACHED_FORMATTERS = new FormatterCache(); + + static class FormatterCache + extends LruCache<String, android.icu.text.RelativeDateTimeFormatter> { + FormatterCache() { + super(8); + } + } + + private RelativeDateTimeFormatter() { + } + + /** + * This is the internal API that implements the functionality of DateUtils + * .getRelativeTimeSpanString(long, + * long, long, int), which is to return a string describing 'time' as a time relative to 'now' + * such as '5 minutes ago', or 'In 2 days'. More examples can be found in DateUtils' doc. + * <p> + * In the implementation below, it selects the appropriate time unit based on the elapsed time + * between time' and 'now', e.g. minutes, days and etc. Callers may also specify the desired + * minimum resolution to show in the result. For example, '45 minutes ago' will become '0 hours + * ago' when minResolution is HOUR_IN_MILLIS. Once getting the quantity and unit to display, it + * calls icu4j's RelativeDateTimeFormatter to format the actual string according to the given + * locale. + * <p> + * Note that when minResolution is set to DAY_IN_MILLIS, it returns the result depending on the + * actual date difference. For example, it will return 'Yesterday' even if 'time' was less than + * 24 hours ago but falling onto a different calendar day. + * <p> + * It takes two additional parameters of Locale and TimeZone than the DateUtils' API. Caller + * must specify the locale and timezone. FORMAT_ABBREV_RELATIVE or FORMAT_ABBREV_ALL can be set + * in 'flags' to get the abbreviated forms when available. When 'time' equals to 'now', it + * always // returns a string like '0 seconds/minutes/... ago' according to minResolution. + */ + public static String getRelativeTimeSpanString(Locale locale, java.util.TimeZone tz, long time, + long now, long minResolution, int flags) { + // Android has been inconsistent about capitalization in the past. e.g. bug + // http://b/20247811. + // Now we capitalize everything consistently. + final DisplayContext displayContext = + DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE; + return getRelativeTimeSpanString(locale, tz, time, now, minResolution, flags, + displayContext); + } + + public static String getRelativeTimeSpanString(Locale locale, java.util.TimeZone tz, long time, + long now, long minResolution, int flags, DisplayContext displayContext) { + if (locale == null) { + throw new NullPointerException("locale == null"); + } + if (tz == null) { + throw new NullPointerException("tz == null"); + } + ULocale icuLocale = ULocale.forLocale(locale); + android.icu.util.TimeZone icuTimeZone = DateUtilsBridge.icuTimeZone(tz); + return getRelativeTimeSpanString(icuLocale, icuTimeZone, time, now, minResolution, flags, + displayContext); + } + + private static String getRelativeTimeSpanString(ULocale icuLocale, + android.icu.util.TimeZone icuTimeZone, long time, long now, long minResolution, + int flags, + DisplayContext displayContext) { + + long duration = Math.abs(now - time); + boolean past = (now >= time); + + android.icu.text.RelativeDateTimeFormatter.Style style; + if ((flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0) { + style = android.icu.text.RelativeDateTimeFormatter.Style.SHORT; + } else { + style = android.icu.text.RelativeDateTimeFormatter.Style.LONG; + } + + android.icu.text.RelativeDateTimeFormatter.Direction direction; + if (past) { + direction = android.icu.text.RelativeDateTimeFormatter.Direction.LAST; + } else { + direction = android.icu.text.RelativeDateTimeFormatter.Direction.NEXT; + } + + // 'relative' defaults to true as we are generating relative time span + // string. It will be set to false when we try to display strings without + // a quantity, such as 'Yesterday', etc. + boolean relative = true; + int count; + android.icu.text.RelativeDateTimeFormatter.RelativeUnit unit; + android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit aunit = null; + + if (duration < MINUTE_IN_MILLIS && minResolution < MINUTE_IN_MILLIS) { + count = (int) (duration / SECOND_IN_MILLIS); + unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.SECONDS; + } else if (duration < HOUR_IN_MILLIS && minResolution < HOUR_IN_MILLIS) { + count = (int) (duration / MINUTE_IN_MILLIS); + unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.MINUTES; + } else if (duration < DAY_IN_MILLIS && minResolution < DAY_IN_MILLIS) { + // Even if 'time' actually happened yesterday, we don't format it as + // "Yesterday" in this case. Unless the duration is longer than a day, + // or minResolution is specified as DAY_IN_MILLIS by user. + count = (int) (duration / HOUR_IN_MILLIS); + unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.HOURS; + } else if (duration < WEEK_IN_MILLIS && minResolution < WEEK_IN_MILLIS) { + count = Math.abs(dayDistance(icuTimeZone, time, now)); + unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.DAYS; + + if (count == 2) { + // Some locales have special terms for "2 days ago". Return them if + // available. Note that we cannot set up direction and unit here and + // make it fall through to use the call near the end of the function, + // because for locales that don't have special terms for "2 days ago", + // icu4j returns an empty string instead of falling back to strings + // like "2 days ago". + String str; + if (past) { + synchronized (CACHED_FORMATTERS) { + str = getFormatter(icuLocale, style, displayContext).format( + android.icu.text.RelativeDateTimeFormatter.Direction.LAST_2, + android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY); + } + } else { + synchronized (CACHED_FORMATTERS) { + str = getFormatter(icuLocale, style, displayContext).format( + android.icu.text.RelativeDateTimeFormatter.Direction.NEXT_2, + android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY); + } + } + if (str != null && !str.isEmpty()) { + return str; + } + // Fall back to show something like "2 days ago". + } else if (count == 1) { + // Show "Yesterday / Tomorrow" instead of "1 day ago / In 1 day". + aunit = android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY; + relative = false; + } else if (count == 0) { + // Show "Today" if time and now are on the same day. + aunit = android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY; + direction = android.icu.text.RelativeDateTimeFormatter.Direction.THIS; + relative = false; + } + } else if (minResolution == WEEK_IN_MILLIS) { + count = (int) (duration / WEEK_IN_MILLIS); + unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.WEEKS; + } else { + Calendar timeCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, time); + // The duration is longer than a week and minResolution is not + // WEEK_IN_MILLIS. Return the absolute date instead of relative time. + + // Bug 19822016: + // If user doesn't supply the year display flag, we need to explicitly + // set that to show / hide the year based on time and now. Otherwise + // formatDateRange() would determine that based on the current system + // time and may give wrong results. + if ((flags & (FORMAT_NO_YEAR | FORMAT_SHOW_YEAR)) == 0) { + Calendar nowCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, + now); + + if (timeCalendar.get(Calendar.YEAR) != nowCalendar.get(Calendar.YEAR)) { + flags |= FORMAT_SHOW_YEAR; + } else { + flags |= FORMAT_NO_YEAR; + } + } + return DateTimeFormat.format(icuLocale, timeCalendar, flags, displayContext); + } + + synchronized (CACHED_FORMATTERS) { + android.icu.text.RelativeDateTimeFormatter formatter = + getFormatter(icuLocale, style, displayContext); + if (relative) { + return formatter.format(count, direction, unit); + } else { + return formatter.format(direction, aunit); + } + } + } + + /** + * This is the internal API that implements DateUtils.getRelativeDateTimeString(long, long, + * long, long, int), which is to return a string describing 'time' as a time relative to 'now', + * formatted like '[relative time/date], [time]'. More examples can be found in DateUtils' doc. + * <p> + * The function is similar to getRelativeTimeSpanString, but it always appends the absolute time + * to the relative time string to return '[relative time/date clause], [absolute time clause]'. + * It also takes an extra parameter transitionResolution to determine the format of the date + * clause. When the elapsed time is less than the transition resolution, it displays the + * relative time string. Otherwise, it gives the absolute numeric date string as the date + * clause. With the date and time clauses, it relies on icu4j's + * RelativeDateTimeFormatter::combineDateAndTime() + * to concatenate the two. + * <p> + * It takes two additional parameters of Locale and TimeZone than the DateUtils' API. Caller + * must specify the locale and timezone. FORMAT_ABBREV_RELATIVE or FORMAT_ABBREV_ALL can be set + * in 'flags' to get the abbreviated forms when they are available. + * <p> + * Bug 5252772: Since the absolute time will always be part of the result, minResolution will be + * set to at least DAY_IN_MILLIS to correctly indicate the date difference. For example, when + * it's 1:30 AM, it will return 'Yesterday, 11:30 PM' for getRelativeDateTimeString(null, null, + * now - 2 hours, now, HOUR_IN_MILLIS, DAY_IN_MILLIS, 0), instead of '2 hours ago, 11:30 PM' + * even with minResolution being HOUR_IN_MILLIS. + */ + public static String getRelativeDateTimeString(Locale locale, java.util.TimeZone tz, long time, + long now, long minResolution, long transitionResolution, int flags) { + + if (locale == null) { + throw new NullPointerException("locale == null"); + } + if (tz == null) { + throw new NullPointerException("tz == null"); + } + ULocale icuLocale = ULocale.forLocale(locale); + android.icu.util.TimeZone icuTimeZone = DateUtilsBridge.icuTimeZone(tz); + + long duration = Math.abs(now - time); + // It doesn't make much sense to have results like: "1 week ago, 10:50 AM". + if (transitionResolution > WEEK_IN_MILLIS) { + transitionResolution = WEEK_IN_MILLIS; + } + android.icu.text.RelativeDateTimeFormatter.Style style; + if ((flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0) { + style = android.icu.text.RelativeDateTimeFormatter.Style.SHORT; + } else { + style = android.icu.text.RelativeDateTimeFormatter.Style.LONG; + } + + Calendar timeCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, time); + Calendar nowCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, now); + + int days = Math.abs(DateUtilsBridge.dayDistance(timeCalendar, nowCalendar)); + + // Now get the date clause, either in relative format or the actual date. + String dateClause; + if (duration < transitionResolution) { + // This is to fix bug 5252772. If there is any date difference, we should + // promote the minResolution to DAY_IN_MILLIS so that it can display the + // date instead of "x hours/minutes ago, [time]". + if (days > 0 && minResolution < DAY_IN_MILLIS) { + minResolution = DAY_IN_MILLIS; + } + dateClause = getRelativeTimeSpanString(icuLocale, icuTimeZone, time, now, minResolution, + flags, DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE); + } else { + // We always use fixed flags to format the date clause. User-supplied + // flags are ignored. + if (timeCalendar.get(Calendar.YEAR) != nowCalendar.get(Calendar.YEAR)) { + // Different years + flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE; + } else { + // Default + flags = FORMAT_SHOW_DATE | FORMAT_NO_YEAR | FORMAT_ABBREV_MONTH; + } + + dateClause = DateTimeFormat.format(icuLocale, timeCalendar, flags, + DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE); + } + + String timeClause = DateTimeFormat.format(icuLocale, timeCalendar, FORMAT_SHOW_TIME, + DisplayContext.CAPITALIZATION_NONE); + + // icu4j also has other options available to control the capitalization. We are currently + // using + // the _NONE option only. + DisplayContext capitalizationContext = DisplayContext.CAPITALIZATION_NONE; + + // Combine the two clauses, such as '5 days ago, 10:50 AM'. + synchronized (CACHED_FORMATTERS) { + return getFormatter(icuLocale, style, capitalizationContext) + .combineDateAndTime(dateClause, timeClause); + } + } + + /** + * getFormatter() caches the RelativeDateTimeFormatter instances based on the combination of + * localeName, sytle and capitalizationContext. It should always be used along with the action + * of the formatter in a synchronized block, because otherwise the formatter returned by + * getFormatter() may have been evicted by the time of the call to formatter->action(). + */ + private static android.icu.text.RelativeDateTimeFormatter getFormatter( + ULocale locale, android.icu.text.RelativeDateTimeFormatter.Style style, + DisplayContext displayContext) { + String key = locale + "\t" + style + "\t" + displayContext; + android.icu.text.RelativeDateTimeFormatter formatter = CACHED_FORMATTERS.get(key); + if (formatter == null) { + formatter = android.icu.text.RelativeDateTimeFormatter.getInstance( + locale, null, style, displayContext); + CACHED_FORMATTERS.put(key, formatter); + } + return formatter; + } + + // Return the date difference for the two times in a given timezone. + private static int dayDistance(android.icu.util.TimeZone icuTimeZone, long startTime, + long endTime) { + return julianDay(icuTimeZone, endTime) - julianDay(icuTimeZone, startTime); + } + + private static int julianDay(android.icu.util.TimeZone icuTimeZone, long time) { + long utcMs = time + icuTimeZone.getOffset(time); + return (int) (utcMs / DAY_IN_MS) + EPOCH_JULIAN_DAY; + } +} diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java index 49cebc141636..80c8ec852146 100644 --- a/core/java/android/text/format/Time.java +++ b/core/java/android/text/format/Time.java @@ -18,10 +18,9 @@ package android.text.format; import android.util.TimeFormatException; -import libcore.timezone.ZoneInfoDb; -import libcore.util.ZoneInfo; +import com.android.i18n.timezone.ZoneInfoData; +import com.android.i18n.timezone.ZoneInfoDb; -import java.io.IOException; import java.util.Locale; import java.util.TimeZone; @@ -1071,15 +1070,15 @@ public class Time { * to the enclosing object, but others do not: thus separate state is retained. */ private static class TimeCalculator { - public final ZoneInfo.WallTime wallTime; + public final ZoneInfoData.WallTime wallTime; public String timezone; // Information about the current timezone. - private ZoneInfo zoneInfo; + private ZoneInfoData mZoneInfoData; public TimeCalculator(String timezoneId) { - this.zoneInfo = lookupZoneInfo(timezoneId); - this.wallTime = new ZoneInfo.WallTime(); + this.mZoneInfoData = lookupZoneInfoData(timezoneId); + this.wallTime = new ZoneInfoData.WallTime(); } public long toMillis(boolean ignoreDst) { @@ -1087,7 +1086,7 @@ public class Time { wallTime.setIsDst(-1); } - int r = wallTime.mktime(zoneInfo); + int r = wallTime.mktime(mZoneInfoData); if (r == -1) { return -1; } @@ -1099,7 +1098,7 @@ public class Time { int intSeconds = (int) (millis / 1000); updateZoneInfoFromTimeZone(); - wallTime.localtime(intSeconds, zoneInfo); + wallTime.localtime(intSeconds, mZoneInfoData); } public String format(String format) { @@ -1107,36 +1106,31 @@ public class Time { format = "%c"; } TimeFormatter formatter = new TimeFormatter(); - return formatter.format(format, wallTime, zoneInfo); + return formatter.format(format, wallTime, mZoneInfoData); } private void updateZoneInfoFromTimeZone() { - if (!zoneInfo.getID().equals(timezone)) { - this.zoneInfo = lookupZoneInfo(timezone); + if (!mZoneInfoData.getID().equals(timezone)) { + this.mZoneInfoData = lookupZoneInfoData(timezone); } } - private static ZoneInfo lookupZoneInfo(String timezoneId) { - try { - ZoneInfo zoneInfo = ZoneInfoDb.getInstance().makeTimeZone(timezoneId); - if (zoneInfo == null) { - zoneInfo = ZoneInfoDb.getInstance().makeTimeZone("GMT"); - } - if (zoneInfo == null) { - throw new AssertionError("GMT not found: \"" + timezoneId + "\""); - } - return zoneInfo; - } catch (IOException e) { - // This should not ever be thrown. - throw new AssertionError("Error loading timezone: \"" + timezoneId + "\"", e); + private static ZoneInfoData lookupZoneInfoData(String timezoneId) { + ZoneInfoData zoneInfoData = ZoneInfoDb.getInstance().makeZoneInfoData(timezoneId); + if (zoneInfoData == null) { + zoneInfoData = ZoneInfoDb.getInstance().makeZoneInfoData("GMT"); + } + if (zoneInfoData == null) { + throw new AssertionError("GMT not found: \"" + timezoneId + "\""); } + return zoneInfoData; } public void switchTimeZone(String timezone) { - int seconds = wallTime.mktime(zoneInfo); + int seconds = wallTime.mktime(mZoneInfoData); this.timezone = timezone; updateZoneInfoFromTimeZone(); - wallTime.localtime(seconds, zoneInfo); + wallTime.localtime(seconds, mZoneInfoData); } public String format2445(boolean hasTime) { diff --git a/core/java/android/text/format/TimeFormatter.java b/core/java/android/text/format/TimeFormatter.java index f7fd89d7d819..9393f36d1b6f 100644 --- a/core/java/android/text/format/TimeFormatter.java +++ b/core/java/android/text/format/TimeFormatter.java @@ -21,9 +21,11 @@ package android.text.format; import android.content.res.Resources; +import android.icu.text.DateFormatSymbols; + +import com.android.i18n.timezone.ZoneInfoData; import libcore.icu.LocaleData; -import libcore.util.ZoneInfo; import java.nio.CharBuffer; import java.time.Instant; @@ -54,11 +56,13 @@ class TimeFormatter { * The Locale for which the cached LocaleData and formats have been loaded. */ private static Locale sLocale; + private static DateFormatSymbols sDateFormatSymbols; private static LocaleData sLocaleData; private static String sTimeOnlyFormat; private static String sDateOnlyFormat; private static String sDateTimeFormat; + private final DateFormatSymbols dateFormatSymbols; private final LocaleData localeData; private final String dateTimeFormat; private final String timeOnlyFormat; @@ -73,6 +77,7 @@ class TimeFormatter { if (sLocale == null || !(locale.equals(sLocale))) { sLocale = locale; + sDateFormatSymbols = DateFormat.getIcuDateFormatSymbols(locale); sLocaleData = LocaleData.get(locale); Resources r = Resources.getSystem(); @@ -81,6 +86,7 @@ class TimeFormatter { sDateTimeFormat = r.getString(com.android.internal.R.string.date_and_time); } + this.dateFormatSymbols = sDateFormatSymbols; this.dateTimeFormat = sDateTimeFormat; this.timeOnlyFormat = sTimeOnlyFormat; this.dateOnlyFormat = sDateOnlyFormat; @@ -94,8 +100,8 @@ class TimeFormatter { * incorrect digit localization behavior. */ String formatMillisWithFixedFormat(long timeMillis) { - // This method is deliberately not a general purpose replacement for - // format(String, ZoneInfo.WallTime, ZoneInfo): It hard-codes the pattern used; many of the + // This method is deliberately not a general purpose replacement for format(String, + // ZoneInfoData.WallTime, ZoneInfoData): It hard-codes the pattern used; many of the // pattern characters supported by Time.format() have unusual behavior which would make // using java.time.format or similar packages difficult. It would be a lot of work to share // behavior and many internal Android usecases can be covered by this common pattern @@ -144,7 +150,8 @@ class TimeFormatter { /** * Format the specified {@code wallTime} using {@code pattern}. The output is returned. */ - public String format(String pattern, ZoneInfo.WallTime wallTime, ZoneInfo zoneInfo) { + public String format(String pattern, ZoneInfoData.WallTime wallTime, + ZoneInfoData zoneInfoData) { try { StringBuilder stringBuilder = new StringBuilder(); @@ -153,7 +160,7 @@ class TimeFormatter { // and locale sensitive strings are output directly using outputBuilder. numberFormatter = new Formatter(stringBuilder, Locale.US); - formatInternal(pattern, wallTime, zoneInfo); + formatInternal(pattern, wallTime, zoneInfoData); String result = stringBuilder.toString(); // The localizeDigits() behavior is the source of a bug since some formats are defined // as being in ASCII and not localized. @@ -186,13 +193,14 @@ class TimeFormatter { * Format the specified {@code wallTime} using {@code pattern}. The output is written to * {@link #outputBuilder}. */ - private void formatInternal(String pattern, ZoneInfo.WallTime wallTime, ZoneInfo zoneInfo) { + private void formatInternal(String pattern, ZoneInfoData.WallTime wallTime, + ZoneInfoData zoneInfoData) { CharBuffer formatBuffer = CharBuffer.wrap(pattern); while (formatBuffer.remaining() > 0) { boolean outputCurrentChar = true; char currentChar = formatBuffer.get(formatBuffer.position()); if (currentChar == '%') { - outputCurrentChar = handleToken(formatBuffer, wallTime, zoneInfo); + outputCurrentChar = handleToken(formatBuffer, wallTime, zoneInfoData); } if (outputCurrentChar) { outputBuilder.append(formatBuffer.get(formatBuffer.position())); @@ -201,8 +209,8 @@ class TimeFormatter { } } - private boolean handleToken(CharBuffer formatBuffer, ZoneInfo.WallTime wallTime, - ZoneInfo zoneInfo) { + private boolean handleToken(CharBuffer formatBuffer, ZoneInfoData.WallTime wallTime, + ZoneInfoData zoneInfoData) { // The char at formatBuffer.position() is expected to be '%' at this point. int modifier = 0; @@ -247,10 +255,10 @@ class TimeFormatter { outputYear(wallTime.getYear(), true, false, modifier); return false; case 'c': - formatInternal(dateTimeFormat, wallTime, zoneInfo); + formatInternal(dateTimeFormat, wallTime, zoneInfoData); return false; case 'D': - formatInternal("%m/%d/%y", wallTime, zoneInfo); + formatInternal("%m/%d/%y", wallTime, zoneInfoData); return false; case 'd': numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), @@ -272,7 +280,7 @@ class TimeFormatter { wallTime.getMonthDay()); return false; case 'F': - formatInternal("%Y-%m-%d", wallTime, zoneInfo); + formatInternal("%Y-%m-%d", wallTime, zoneInfoData); return false; case 'H': numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), @@ -307,29 +315,31 @@ class TimeFormatter { outputBuilder.append('\n'); return false; case 'p': - modifyAndAppend((wallTime.getHour() >= (HOURSPERDAY / 2)) ? localeData.amPm[1] - : localeData.amPm[0], modifier); + modifyAndAppend((wallTime.getHour() >= (HOURSPERDAY / 2)) + ? dateFormatSymbols.getAmPmStrings()[1] + : dateFormatSymbols.getAmPmStrings()[0], modifier); return false; case 'P': - modifyAndAppend((wallTime.getHour() >= (HOURSPERDAY / 2)) ? localeData.amPm[1] - : localeData.amPm[0], FORCE_LOWER_CASE); + modifyAndAppend((wallTime.getHour() >= (HOURSPERDAY / 2)) + ? dateFormatSymbols.getAmPmStrings()[1] + : dateFormatSymbols.getAmPmStrings()[0], FORCE_LOWER_CASE); return false; case 'R': - formatInternal("%H:%M", wallTime, zoneInfo); + formatInternal("%H:%M", wallTime, zoneInfoData); return false; case 'r': - formatInternal("%I:%M:%S %p", wallTime, zoneInfo); + formatInternal("%I:%M:%S %p", wallTime, zoneInfoData); return false; case 'S': numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), wallTime.getSecond()); return false; case 's': - int timeInSeconds = wallTime.mktime(zoneInfo); + int timeInSeconds = wallTime.mktime(zoneInfoData); outputBuilder.append(Integer.toString(timeInSeconds)); return false; case 'T': - formatInternal("%H:%M:%S", wallTime, zoneInfo); + formatInternal("%H:%M:%S", wallTime, zoneInfoData); return false; case 't': outputBuilder.append('\t'); @@ -383,7 +393,7 @@ class TimeFormatter { return false; } case 'v': - formatInternal("%e-%b-%Y", wallTime, zoneInfo); + formatInternal("%e-%b-%Y", wallTime, zoneInfoData); return false; case 'W': int n = (wallTime.getYearDay() + DAYSPERWEEK - ( @@ -395,10 +405,10 @@ class TimeFormatter { numberFormatter.format("%d", wallTime.getWeekDay()); return false; case 'X': - formatInternal(timeOnlyFormat, wallTime, zoneInfo); + formatInternal(timeOnlyFormat, wallTime, zoneInfoData); return false; case 'x': - formatInternal(dateOnlyFormat, wallTime, zoneInfo); + formatInternal(dateOnlyFormat, wallTime, zoneInfoData); return false; case 'y': outputYear(wallTime.getYear(), false, true, modifier); @@ -411,7 +421,8 @@ class TimeFormatter { return false; } boolean isDst = wallTime.getIsDst() != 0; - modifyAndAppend(zoneInfo.getDisplayName(isDst, TimeZone.SHORT), modifier); + modifyAndAppend(TimeZone.getTimeZone(zoneInfoData.getID()) + .getDisplayName(isDst, TimeZone.SHORT), modifier); return false; case 'z': { if (wallTime.getIsDst() < 0) { @@ -432,7 +443,7 @@ class TimeFormatter { return false; } case '+': - formatInternal("%a %b %e %H:%M:%S %Z %Y", wallTime, zoneInfo); + formatInternal("%a %b %e %H:%M:%S %Z %Y", wallTime, zoneInfoData); return false; case '%': // If conversion char is undefined, behavior is undefined. Print out the diff --git a/core/java/android/text/method/NumberKeyListener.java b/core/java/android/text/method/NumberKeyListener.java index d40015ee17a8..2b038dd11348 100644 --- a/core/java/android/text/method/NumberKeyListener.java +++ b/core/java/android/text/method/NumberKeyListener.java @@ -29,8 +29,6 @@ import android.text.format.DateFormat; import android.view.KeyEvent; import android.view.View; -import libcore.icu.LocaleData; - import java.util.Collection; import java.util.Locale; @@ -228,7 +226,7 @@ public abstract class NumberKeyListener extends BaseKeyListener if (locale == null) { return false; } - final String[] amPm = LocaleData.get(locale).amPm; + final String[] amPm = DateFormat.getIcuDateFormatSymbols(locale).getAmPmStrings(); for (int i = 0; i < amPm.length; i++) { for (int j = 0; j < amPm[i].length(); j++) { final char ch = amPm[i].charAt(j); diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java index 82c7ea705aa6..a7ddfa93a74e 100644 --- a/core/java/android/text/util/Linkify.java +++ b/core/java/android/text/util/Linkify.java @@ -304,7 +304,7 @@ public class Linkify { if ((mask & WEB_URLS) != 0) { gatherLinks(links, text, Patterns.AUTOLINK_WEB_URL, - new String[] { "http://", "https://", "rtsp://" }, + new String[] { "http://", "https://", "rtsp://", "ftp://" }, sUrlMatchFilter, null); } diff --git a/core/java/android/timezone/CountryTimeZones.java b/core/java/android/timezone/CountryTimeZones.java index a8db50e51782..44d140242409 100644 --- a/core/java/android/timezone/CountryTimeZones.java +++ b/core/java/android/timezone/CountryTimeZones.java @@ -40,9 +40,9 @@ public final class CountryTimeZones { public static final class TimeZoneMapping { @NonNull - private libcore.timezone.CountryTimeZones.TimeZoneMapping mDelegate; + private com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping mDelegate; - TimeZoneMapping(libcore.timezone.CountryTimeZones.TimeZoneMapping delegate) { + TimeZoneMapping(com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping delegate) { this.mDelegate = Objects.requireNonNull(delegate); } @@ -147,9 +147,9 @@ public final class CountryTimeZones { } @NonNull - private final libcore.timezone.CountryTimeZones mDelegate; + private final com.android.i18n.timezone.CountryTimeZones mDelegate; - CountryTimeZones(libcore.timezone.CountryTimeZones delegate) { + CountryTimeZones(com.android.i18n.timezone.CountryTimeZones delegate) { mDelegate = delegate; } @@ -158,7 +158,7 @@ public final class CountryTimeZones { * supplied. */ public boolean matchesCountryCode(@NonNull String countryIso) { - return mDelegate.isForCountryCode(countryIso); + return mDelegate.matchesCountryCode(countryIso); } /** @@ -221,7 +221,7 @@ public final class CountryTimeZones { @Nullable public OffsetResult lookupByOffsetWithBias(long whenMillis, @Nullable TimeZone bias, int totalOffsetMillis, boolean isDst) { - libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult = + com.android.i18n.timezone.CountryTimeZones.OffsetResult delegateOffsetResult = mDelegate.lookupByOffsetWithBias( whenMillis, bias, totalOffsetMillis, isDst); return delegateOffsetResult == null ? null : @@ -244,7 +244,7 @@ public final class CountryTimeZones { @Nullable public OffsetResult lookupByOffsetWithBias(long whenMillis, @Nullable TimeZone bias, int totalOffsetMillis) { - libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult = + com.android.i18n.timezone.CountryTimeZones.OffsetResult delegateOffsetResult = mDelegate.lookupByOffsetWithBias(whenMillis, bias, totalOffsetMillis); return delegateOffsetResult == null ? null : new OffsetResult( @@ -260,11 +260,12 @@ public final class CountryTimeZones { */ @NonNull public List<TimeZoneMapping> getEffectiveTimeZoneMappingsAt(long whenMillis) { - List<libcore.timezone.CountryTimeZones.TimeZoneMapping> delegateList = + List<com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping> delegateList = mDelegate.getEffectiveTimeZoneMappingsAt(whenMillis); List<TimeZoneMapping> toReturn = new ArrayList<>(delegateList.size()); - for (libcore.timezone.CountryTimeZones.TimeZoneMapping delegateMapping : delegateList) { + for (com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping delegateMapping + : delegateList) { toReturn.add(new TimeZoneMapping(delegateMapping)); } return Collections.unmodifiableList(toReturn); diff --git a/core/java/android/timezone/TelephonyLookup.java b/core/java/android/timezone/TelephonyLookup.java index a4c3fbd33410..c97bf28cebfe 100644 --- a/core/java/android/timezone/TelephonyLookup.java +++ b/core/java/android/timezone/TelephonyLookup.java @@ -41,16 +41,17 @@ public final class TelephonyLookup { public static TelephonyLookup getInstance() { synchronized (sLock) { if (sInstance == null) { - sInstance = new TelephonyLookup(libcore.timezone.TelephonyLookup.getInstance()); + sInstance = new TelephonyLookup(com.android.i18n.timezone.TelephonyLookup + .getInstance()); } return sInstance; } } @NonNull - private final libcore.timezone.TelephonyLookup mDelegate; + private final com.android.i18n.timezone.TelephonyLookup mDelegate; - private TelephonyLookup(@NonNull libcore.timezone.TelephonyLookup delegate) { + private TelephonyLookup(@NonNull com.android.i18n.timezone.TelephonyLookup delegate) { mDelegate = Objects.requireNonNull(delegate); } @@ -60,7 +61,7 @@ public final class TelephonyLookup { */ @Nullable public TelephonyNetworkFinder getTelephonyNetworkFinder() { - libcore.timezone.TelephonyNetworkFinder telephonyNetworkFinderDelegate = + com.android.i18n.timezone.TelephonyNetworkFinder telephonyNetworkFinderDelegate = mDelegate.getTelephonyNetworkFinder(); return telephonyNetworkFinderDelegate != null ? new TelephonyNetworkFinder(telephonyNetworkFinderDelegate) : null; diff --git a/core/java/android/timezone/TelephonyNetwork.java b/core/java/android/timezone/TelephonyNetwork.java index 823cd251fbf0..3b65c6ffc379 100644 --- a/core/java/android/timezone/TelephonyNetwork.java +++ b/core/java/android/timezone/TelephonyNetwork.java @@ -28,9 +28,9 @@ import java.util.Objects; public final class TelephonyNetwork { @NonNull - private final libcore.timezone.TelephonyNetwork mDelegate; + private final com.android.i18n.timezone.TelephonyNetwork mDelegate; - TelephonyNetwork(@NonNull libcore.timezone.TelephonyNetwork delegate) { + TelephonyNetwork(@NonNull com.android.i18n.timezone.TelephonyNetwork delegate) { mDelegate = Objects.requireNonNull(delegate); } diff --git a/core/java/android/timezone/TelephonyNetworkFinder.java b/core/java/android/timezone/TelephonyNetworkFinder.java index 4bfeff8a73ad..c69ddf86d3f8 100644 --- a/core/java/android/timezone/TelephonyNetworkFinder.java +++ b/core/java/android/timezone/TelephonyNetworkFinder.java @@ -29,9 +29,9 @@ import java.util.Objects; public final class TelephonyNetworkFinder { @NonNull - private final libcore.timezone.TelephonyNetworkFinder mDelegate; + private final com.android.i18n.timezone.TelephonyNetworkFinder mDelegate; - TelephonyNetworkFinder(libcore.timezone.TelephonyNetworkFinder delegate) { + TelephonyNetworkFinder(com.android.i18n.timezone.TelephonyNetworkFinder delegate) { mDelegate = Objects.requireNonNull(delegate); } @@ -45,7 +45,7 @@ public final class TelephonyNetworkFinder { Objects.requireNonNull(mcc); Objects.requireNonNull(mnc); - libcore.timezone.TelephonyNetwork telephonyNetworkDelegate = + com.android.i18n.timezone.TelephonyNetwork telephonyNetworkDelegate = mDelegate.findNetworkByMccMnc(mcc, mnc); return telephonyNetworkDelegate != null ? new TelephonyNetwork(telephonyNetworkDelegate) : null; diff --git a/core/java/android/timezone/TimeZoneFinder.java b/core/java/android/timezone/TimeZoneFinder.java index 03f5013f230c..bf4275fb5b56 100644 --- a/core/java/android/timezone/TimeZoneFinder.java +++ b/core/java/android/timezone/TimeZoneFinder.java @@ -41,16 +41,17 @@ public final class TimeZoneFinder { public static TimeZoneFinder getInstance() { synchronized (sLock) { if (sInstance == null) { - sInstance = new TimeZoneFinder(libcore.timezone.TimeZoneFinder.getInstance()); + sInstance = new TimeZoneFinder(com.android.i18n.timezone.TimeZoneFinder + .getInstance()); } } return sInstance; } @NonNull - private final libcore.timezone.TimeZoneFinder mDelegate; + private final com.android.i18n.timezone.TimeZoneFinder mDelegate; - private TimeZoneFinder(@NonNull libcore.timezone.TimeZoneFinder delegate) { + private TimeZoneFinder(@NonNull com.android.i18n.timezone.TimeZoneFinder delegate) { mDelegate = Objects.requireNonNull(delegate); } @@ -70,7 +71,8 @@ public final class TimeZoneFinder { */ @Nullable public CountryTimeZones lookupCountryTimeZones(@NonNull String countryIso) { - libcore.timezone.CountryTimeZones delegate = mDelegate.lookupCountryTimeZones(countryIso); + com.android.i18n.timezone.CountryTimeZones delegate = mDelegate + .lookupCountryTimeZones(countryIso); return delegate == null ? null : new CountryTimeZones(delegate); } } diff --git a/core/java/android/timezone/TzDataSetVersion.java b/core/java/android/timezone/TzDataSetVersion.java index f993012aeb1c..e1fb932b977d 100644 --- a/core/java/android/timezone/TzDataSetVersion.java +++ b/core/java/android/timezone/TzDataSetVersion.java @@ -50,14 +50,14 @@ public final class TzDataSetVersion { * Returns the major tz data format version supported by this device. */ public static int currentFormatMajorVersion() { - return libcore.timezone.TzDataSetVersion.currentFormatMajorVersion(); + return com.android.i18n.timezone.TzDataSetVersion.currentFormatMajorVersion(); } /** * Returns the minor tz data format version supported by this device. */ public static int currentFormatMinorVersion() { - return libcore.timezone.TzDataSetVersion.currentFormatMinorVersion(); + return com.android.i18n.timezone.TzDataSetVersion.currentFormatMinorVersion(); } /** @@ -65,7 +65,7 @@ public final class TzDataSetVersion { * with the current system image, and set of active modules. */ public static boolean isCompatibleWithThisDevice(TzDataSetVersion tzDataSetVersion) { - return libcore.timezone.TzDataSetVersion.isCompatibleWithThisDevice( + return com.android.i18n.timezone.TzDataSetVersion.isCompatibleWithThisDevice( tzDataSetVersion.mDelegate); } @@ -76,8 +76,8 @@ public final class TzDataSetVersion { public static TzDataSetVersion read() throws IOException, TzDataSetException { try { return new TzDataSetVersion( - libcore.timezone.TzDataSetVersion.readTimeZoneModuleVersion()); - } catch (libcore.timezone.TzDataSetVersion.TzDataSetException e) { + com.android.i18n.timezone.TzDataSetVersion.readTimeZoneModuleVersion()); + } catch (com.android.i18n.timezone.TzDataSetVersion.TzDataSetException e) { throw new TzDataSetException(e.getMessage(), e); } } @@ -100,9 +100,9 @@ public final class TzDataSetVersion { } @NonNull - private final libcore.timezone.TzDataSetVersion mDelegate; + private final com.android.i18n.timezone.TzDataSetVersion mDelegate; - private TzDataSetVersion(@NonNull libcore.timezone.TzDataSetVersion delegate) { + private TzDataSetVersion(@NonNull com.android.i18n.timezone.TzDataSetVersion delegate) { mDelegate = Objects.requireNonNull(delegate); } diff --git a/core/java/android/timezone/ZoneInfoDb.java b/core/java/android/timezone/ZoneInfoDb.java index 9354a695812d..65d6eaddf824 100644 --- a/core/java/android/timezone/ZoneInfoDb.java +++ b/core/java/android/timezone/ZoneInfoDb.java @@ -41,16 +41,16 @@ public final class ZoneInfoDb { public static ZoneInfoDb getInstance() { synchronized (sLock) { if (sInstance == null) { - sInstance = new ZoneInfoDb(libcore.timezone.ZoneInfoDb.getInstance()); + sInstance = new ZoneInfoDb(com.android.i18n.timezone.ZoneInfoDb.getInstance()); } } return sInstance; } @NonNull - private final libcore.timezone.ZoneInfoDb mDelegate; + private final com.android.i18n.timezone.ZoneInfoDb mDelegate; - private ZoneInfoDb(libcore.timezone.ZoneInfoDb delegate) { + private ZoneInfoDb(com.android.i18n.timezone.ZoneInfoDb delegate) { mDelegate = Objects.requireNonNull(delegate); } diff --git a/core/java/android/util/Patterns.java b/core/java/android/util/Patterns.java index 50cd7b18e254..7ad16ff3dc23 100644 --- a/core/java/android/util/Patterns.java +++ b/core/java/android/util/Patterns.java @@ -301,7 +301,7 @@ public class Patterns { private static final String DOMAIN_NAME_STR = "(" + HOST_NAME + "|" + IP_ADDRESS_STRING + ")"; public static final Pattern DOMAIN_NAME = Pattern.compile(DOMAIN_NAME_STR); - private static final String PROTOCOL = "(?i:http|https|rtsp)://"; + private static final String PROTOCOL = "(?i:http|https|rtsp|ftp)://"; /* A word boundary or end of input. This is to stop foo.sure from matching as foo.su */ private static final String WORD_BOUNDARY = "(?:\\b|$|^)"; diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java index e8d345997022..e0b8d52aa132 100644 --- a/core/java/android/util/TimeUtils.java +++ b/core/java/android/util/TimeUtils.java @@ -23,10 +23,10 @@ import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.SystemClock; -import libcore.timezone.CountryTimeZones; -import libcore.timezone.CountryTimeZones.TimeZoneMapping; -import libcore.timezone.TimeZoneFinder; -import libcore.timezone.ZoneInfoDb; +import com.android.i18n.timezone.CountryTimeZones; +import com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping; +import com.android.i18n.timezone.TimeZoneFinder; +import com.android.i18n.timezone.ZoneInfoDb; import java.io.PrintWriter; import java.text.SimpleDateFormat; diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java index 713cfb48c95f..064bc6947fc4 100644 --- a/core/java/android/view/FocusFinder.java +++ b/core/java/android/view/FocusFinder.java @@ -311,6 +311,9 @@ public class FocusFinder { } final int count = focusables.size(); + if (count < 2) { + return null; + } switch (direction) { case View.FOCUS_FORWARD: return getNextFocusable(focused, focusables, count); @@ -373,29 +376,29 @@ public class FocusFinder { } private static View getNextFocusable(View focused, ArrayList<View> focusables, int count) { + if (count < 2) { + return null; + } if (focused != null) { int position = focusables.lastIndexOf(focused); if (position >= 0 && position + 1 < count) { return focusables.get(position + 1); } } - if (!focusables.isEmpty()) { - return focusables.get(0); - } - return null; + return focusables.get(0); } private static View getPreviousFocusable(View focused, ArrayList<View> focusables, int count) { + if (count < 2) { + return null; + } if (focused != null) { int position = focusables.indexOf(focused); if (position > 0) { return focusables.get(position - 1); } } - if (!focusables.isEmpty()) { - return focusables.get(count - 1); - } - return null; + return focusables.get(count - 1); } private static View getNextKeyboardNavigationCluster( diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 4e07a5f58de4..b1d552060c87 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -221,12 +221,12 @@ public class Surface implements Parcelable { } /** - * Create a Surface assosciated with a given {@link SurfaceControl}. Buffers submitted to this + * Create a Surface associated with a given {@link SurfaceControl}. Buffers submitted to this * surface will be displayed by the system compositor according to the parameters * specified by the control. Multiple surfaces may be constructed from one SurfaceControl, * but only one can be connected (e.g. have an active EGL context) at a time. * - * @param from The SurfaceControl to assosciate this Surface with + * @param from The SurfaceControl to associate this Surface with */ public Surface(@NonNull SurfaceControl from) { copyFrom(from); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 87b2f4b46df7..6826253874f2 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -2559,7 +2559,7 @@ public final class SurfaceControl implements Parcelable { } /** - * Specify how the buffer assosciated with this Surface is mapped in to the + * Specify how the buffer associated with this Surface is mapped in to the * parent coordinate space. The source frame will be scaled to fit the destination * frame, after being rotated according to the orientation parameter. * diff --git a/core/java/android/view/textclassifier/OWNERS b/core/java/android/view/textclassifier/OWNERS index 893a083398fa..be4fbaa6d06a 100644 --- a/core/java/android/view/textclassifier/OWNERS +++ b/core/java/android/view/textclassifier/OWNERS @@ -7,4 +7,8 @@ jalt@google.com joannechung@google.com svetoslavganov@google.com eugeniom@google.com -samsellem@google.com
\ No newline at end of file +samsellem@google.com +adamhe@google.com +augale@google.com +lpeter@google.com +tymtsai@google.com
\ No newline at end of file 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/android/widget/DatePickerSpinnerDelegate.java b/core/java/android/widget/DatePickerSpinnerDelegate.java index 096e6ea52c8a..fd89b2e09131 100644 --- a/core/java/android/widget/DatePickerSpinnerDelegate.java +++ b/core/java/android/widget/DatePickerSpinnerDelegate.java @@ -34,8 +34,6 @@ import android.view.inputmethod.InputMethodManager; import android.widget.DatePicker.AbstractDatePickerDelegate; import android.widget.NumberPicker.OnValueChangeListener; -import libcore.icu.ICU; - import java.text.DateFormatSymbols; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -459,7 +457,7 @@ class DatePickerSpinnerDelegate extends AbstractDatePickerDelegate { // We use numeric spinners for year and day, but textual months. Ask icu4c what // order the user's locale uses for that combination. http://b/7207103. String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd"); - char[] order = ICU.getDateFormatOrder(pattern); + char[] order = DateFormat.getDateFormatOrder(pattern); final int spinnerCount = order.length; for (int i = 0; i < spinnerCount; i++) { switch (order[i]) { diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java index 7fa8f9a31526..23bbe69afafb 100644 --- a/core/java/android/widget/Magnifier.java +++ b/core/java/android/widget/Magnifier.java @@ -140,8 +140,6 @@ public final class Magnifier { // Lock to synchronize between the UI thread and the thread that handles pixel copy results. // Only sync mWindow writes from UI thread with mWindow reads from sPixelCopyHandlerThread. private final Object mLock = new Object(); - // The lock used to synchronize the UI and render threads when a #dismiss is performed. - private final Object mDestroyLock = new Object(); // Members for new styled magnifier (Eloquent style). diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 970d70cf1fb4..4b32e10d083b 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -16,6 +16,8 @@ package android.widget; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.annotation.InterpolatorRes; import android.annotation.NonNull; @@ -245,6 +247,8 @@ public class ProgressBar extends View { private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>(); + private ObjectAnimator mLastProgressAnimator; + /** * Create a new progress bar with range 0...100 and initial progress of 0. * @param context the application environment @@ -1546,8 +1550,19 @@ public class ProgressBar extends View { animator.setAutoCancel(true); animator.setDuration(PROGRESS_ANIM_DURATION); animator.setInterpolator(PROGRESS_ANIM_INTERPOLATOR); + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mLastProgressAnimator = null; + } + }); animator.start(); + mLastProgressAnimator = animator; } else { + if (isPrimary && mLastProgressAnimator != null) { + mLastProgressAnimator.cancel(); + mLastProgressAnimator = null; + } setVisualProgress(id, scale); } diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index 843700cef55e..32c68bdd0491 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -108,7 +108,7 @@ public final class SelectionActionModeHelper { * * @return the swap result, index 0 is the start index and index 1 is the end index. */ - private static int[] sortSelctionIndices(int selectionStart, int selectionEnd) { + private static int[] sortSelectionIndices(int selectionStart, int selectionEnd) { if (selectionStart < selectionEnd) { return new int[]{selectionStart, selectionEnd}; } @@ -122,11 +122,11 @@ public final class SelectionActionModeHelper { * @param textView the selected TextView. * @return the swap result, index 0 is the start index and index 1 is the end index. */ - private static int[] sortSelctionIndicesFromTextView(TextView textView) { + private static int[] sortSelectionIndicesFromTextView(TextView textView) { int selectionStart = textView.getSelectionStart(); int selectionEnd = textView.getSelectionEnd(); - return sortSelctionIndices(selectionStart, selectionEnd); + return sortSelectionIndices(selectionStart, selectionEnd); } /** @@ -135,7 +135,7 @@ public final class SelectionActionModeHelper { public void startSelectionActionModeAsync(boolean adjustSelection) { // Check if the smart selection should run for editable text. adjustSelection &= getTextClassificationSettings().isSmartSelectionEnabled(); - int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView); + int[] sortedSelectionIndices = sortSelectionIndicesFromTextView(mTextView); mSelectionTracker.onOriginalSelection( getText(mTextView), @@ -165,7 +165,7 @@ public final class SelectionActionModeHelper { * Starts Link ActionMode. */ public void startLinkActionModeAsync(int start, int end) { - int[] indexResult = sortSelctionIndices(start, end); + int[] indexResult = sortSelectionIndices(start, end); mSelectionTracker.onOriginalSelection(getText(mTextView), indexResult[0], indexResult[1], true /*isLink*/); cancelAsyncTask(); @@ -201,21 +201,21 @@ public final class SelectionActionModeHelper { /** Reports a selection action event. */ public void onSelectionAction(int menuItemId, @Nullable String actionLabel) { - int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView); + int[] sortedSelectionIndices = sortSelectionIndicesFromTextView(mTextView); mSelectionTracker.onSelectionAction( sortedSelectionIndices[0], sortedSelectionIndices[1], getActionType(menuItemId), actionLabel, mTextClassification); } public void onSelectionDrag() { - int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView); + int[] sortedSelectionIndices = sortSelectionIndicesFromTextView(mTextView); mSelectionTracker.onSelectionAction( sortedSelectionIndices[0], sortedSelectionIndices[1], SelectionEvent.ACTION_DRAG, /* actionLabel= */ null, mTextClassification); } public void onTextChanged(int start, int end) { - int[] sortedSelectionIndices = sortSelctionIndices(start, end); + int[] sortedSelectionIndices = sortSelectionIndices(start, end); mSelectionTracker.onTextChanged(sortedSelectionIndices[0], sortedSelectionIndices[1], mTextClassification); } @@ -334,7 +334,7 @@ public final class SelectionActionModeHelper { startSelectionActionMode(startSelectionResult); }; // TODO do not trigger the animation if the change included only non-printable characters - int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView); + int[] sortedSelectionIndices = sortSelectionIndicesFromTextView(mTextView); final boolean didSelectionChange = result != null && (sortedSelectionIndices[0] != result.mStart || sortedSelectionIndices[1] != result.mEnd); @@ -486,7 +486,7 @@ public final class SelectionActionModeHelper { if (actionMode != null) { actionMode.invalidate(); } - final int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView); + final int[] sortedSelectionIndices = sortSelectionIndicesFromTextView(mTextView); mSelectionTracker.onSelectionUpdated( sortedSelectionIndices[0], sortedSelectionIndices[1], mTextClassification); mTextClassificationAsyncTask = null; @@ -495,7 +495,7 @@ public final class SelectionActionModeHelper { private void resetTextClassificationHelper(int selectionStart, int selectionEnd) { if (selectionStart < 0 || selectionEnd < 0) { // Use selection indices - int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(mTextView); + int[] sortedSelectionIndices = sortSelectionIndicesFromTextView(mTextView); selectionStart = sortedSelectionIndices[0]; selectionEnd = sortedSelectionIndices[1]; } @@ -637,7 +637,7 @@ public final class SelectionActionModeHelper { mAllowReset = false; boolean selected = editor.selectCurrentWord(); if (selected) { - final int[] sortedSelectionIndices = sortSelctionIndicesFromTextView(textView); + final int[] sortedSelectionIndices = sortSelectionIndicesFromTextView(textView); mSelectionStart = sortedSelectionIndices[0]; mSelectionEnd = sortedSelectionIndices[1]; mLogger.logSelectionAction( @@ -1215,7 +1215,7 @@ public final class SelectionActionModeHelper { SelectionResult(int start, int end, @Nullable TextClassification classification, @Nullable TextSelection selection) { - int[] sortedIndices = sortSelctionIndices(start, end); + int[] sortedIndices = sortSelectionIndices(start, end); mStart = sortedIndices[0]; mEnd = sortedIndices[1]; mClassification = classification; diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index 51b18473f1ac..1c219eb95479 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -24,9 +24,11 @@ import android.annotation.Widget; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; +import android.icu.text.DateFormatSymbols; import android.icu.util.Calendar; import android.os.Parcel; import android.os.Parcelable; +import android.text.format.DateFormat; import android.util.AttributeSet; import android.util.Log; import android.util.MathUtils; @@ -39,8 +41,6 @@ import android.view.inspector.InspectableProperty; import com.android.internal.R; -import libcore.icu.LocaleData; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Locale; @@ -421,11 +421,13 @@ public class TimePicker extends FrameLayout { static String[] getAmPmStrings(Context context) { final Locale locale = context.getResources().getConfiguration().locale; - final LocaleData d = LocaleData.get(locale); + DateFormatSymbols dfs = DateFormat.getIcuDateFormatSymbols(locale); + String[] amPm = dfs.getAmPmStrings(); + String[] narrowAmPm = dfs.getAmpmNarrowStrings(); final String[] result = new String[2]; - result[0] = d.amPm[0].length() > 4 ? d.narrowAm : d.amPm[0]; - result[1] = d.amPm[1].length() > 4 ? d.narrowPm : d.amPm[1]; + result[0] = amPm[0].length() > 4 ? narrowAmPm[0] : amPm[0]; + result[1] = amPm[1].length() > 4 ? narrowAmPm[1] : amPm[1]; return result; } diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java index 83c86d5ce36b..bd2fa5965bc9 100644 --- a/core/java/android/widget/TimePickerSpinnerDelegate.java +++ b/core/java/android/widget/TimePickerSpinnerDelegate.java @@ -35,8 +35,6 @@ import android.view.inputmethod.InputMethodManager; import com.android.internal.R; -import libcore.icu.LocaleData; - import java.util.Calendar; /** @@ -143,7 +141,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate { mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); // Get the localized am/pm strings and use them in the spinner. - mAmPmStrings = getAmPmStrings(context); + mAmPmStrings = TimePicker.getAmPmStrings(context); // am/pm final View amPmView = mDelegator.findViewById(R.id.amPm); @@ -574,12 +572,4 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate { target.setContentDescription(mContext.getString(contDescResId)); } } - - public static String[] getAmPmStrings(Context context) { - String[] result = new String[2]; - LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); - result[0] = d.amPm[0].length() > 4 ? d.narrowAm : d.amPm[0]; - result[1] = d.amPm[1].length() > 4 ? d.narrowPm : d.amPm[1]; - return result; - } } diff --git a/core/java/com/android/internal/accessibility/OWNERS b/core/java/com/android/internal/accessibility/OWNERS new file mode 100644 index 000000000000..b3c09e9d539a --- /dev/null +++ b/core/java/com/android/internal/accessibility/OWNERS @@ -0,0 +1,4 @@ +# Bug component: 44214 +svetoslavganov@google.com +pweaver@google.com +qasid@google.com diff --git a/core/java/com/android/internal/compat/OWNERS b/core/java/com/android/internal/compat/OWNERS index 2b7cdb0cbce9..cfd0a4b079ad 100644 --- a/core/java/com/android/internal/compat/OWNERS +++ b/core/java/com/android/internal/compat/OWNERS @@ -2,6 +2,5 @@ platform-compat-eng+reviews@google.com andreionea@google.com -atrost@google.com mathewi@google.com satayev@google.com diff --git a/core/java/com/android/internal/logging/AndroidHandler.java b/core/java/com/android/internal/logging/AndroidHandler.java index f55a31fcc986..119f3662a94f 100644 --- a/core/java/com/android/internal/logging/AndroidHandler.java +++ b/core/java/com/android/internal/logging/AndroidHandler.java @@ -17,9 +17,8 @@ package com.android.internal.logging; import android.util.Log; + import com.android.internal.util.FastPrintWriter; -import dalvik.system.DalvikLogging; -import dalvik.system.DalvikLogHandler; import java.io.PrintWriter; import java.io.StringWriter; @@ -82,7 +81,7 @@ import java.util.logging.Logger; * </tr> * </table> */ -public class AndroidHandler extends Handler implements DalvikLogHandler { +public class AndroidHandler extends Handler { /** * Holds the formatter for all Android log handlers. */ @@ -121,10 +120,32 @@ public class AndroidHandler extends Handler implements DalvikLogHandler { // No need to flush, but must implement abstract method. } + /** + * Returns the short logger tag (up to 23 chars) for the given logger name. + * Traditionally loggers are named by fully-qualified Java classes; this + * method attempts to return a concise identifying part of such names. + */ + private static String loggerNameToTag(String loggerName) { + // Anonymous logger. + if (loggerName == null) { + return "null"; + } + + int length = loggerName.length(); + if (length <= 23) { + return loggerName; + } + + int lastPeriod = loggerName.lastIndexOf("."); + return length - (lastPeriod + 1) <= 23 + ? loggerName.substring(lastPeriod + 1) + : loggerName.substring(loggerName.length() - 23); + } + @Override public void publish(LogRecord record) { int level = getAndroidLevel(record.getLevel()); - String tag = DalvikLogging.loggerNameToTag(record.getLoggerName()); + String tag = loggerNameToTag(record.getLoggerName()); if (!Log.isLoggable(tag, level)) { return; } diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index 8ea5aa815a1c..b4727499d8ef 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -21,6 +21,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.net.Ikev2VpnProfile; import android.net.PlatformVpnProfile; import android.net.ProxyInfo; +import android.net.Uri; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -287,7 +288,7 @@ public final class VpnProfile implements Cloneable, Parcelable { profile.proxy = new ProxyInfo(host, port.isEmpty() ? 0 : Integer.parseInt(port), exclList); } else if (!pacFileUrl.isEmpty()) { - profile.proxy = new ProxyInfo(pacFileUrl); + profile.proxy = new ProxyInfo(Uri.parse(pacFileUrl)); } } // else profile.proxy = null diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 5a1af84eccac..bb4623b3d521 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -5433,7 +5433,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/KernelCpuUidBpfMapReader.java b/core/java/com/android/internal/os/KernelCpuUidBpfMapReader.java index 26f81d9db9c8..dafb924f37bd 100644 --- a/core/java/com/android/internal/os/KernelCpuUidBpfMapReader.java +++ b/core/java/com/android/internal/os/KernelCpuUidBpfMapReader.java @@ -16,7 +16,6 @@ package com.android.internal.os; -import android.os.StrictMode; import android.os.SystemClock; import android.util.Slog; import android.util.SparseArray; @@ -90,9 +89,21 @@ public abstract class KernelCpuUidBpfMapReader { if (mErrors > ERROR_THRESHOLD) { return; } + if (endUid < startUid || startUid < 0) { + return; + } + mWriteLock.lock(); int firstIndex = mData.indexOfKey(startUid); + if (firstIndex < 0) { + mData.put(startUid, null); + firstIndex = mData.indexOfKey(startUid); + } int lastIndex = mData.indexOfKey(endUid); + if (lastIndex < 0) { + mData.put(endUid, null); + lastIndex = mData.indexOfKey(endUid); + } mData.removeAtRange(firstIndex, lastIndex - firstIndex + 1); mWriteLock.unlock(); } diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java index cffb0ad9fdb9..3d35d2fbaa82 100644 --- a/core/java/com/android/internal/os/KernelWakelockReader.java +++ b/core/java/com/android/internal/os/KernelWakelockReader.java @@ -153,19 +153,32 @@ public class KernelWakelockReader { } /** + * Attempt to wait for suspend_control service if not immediately available. + */ + private ISuspendControlService waitForSuspendControlService() throws ServiceNotFoundException { + final String name = "suspend_control"; + final int numRetries = 5; + for (int i = 0; i < numRetries; i++) { + mSuspendControlService = ISuspendControlService.Stub.asInterface( + ServiceManager.getService(name)); + if (mSuspendControlService != null) { + return mSuspendControlService; + } + } + throw new ServiceNotFoundException(name); + } + + /** * On success, returns the updated stats from SystemSupend, else returns null. */ private KernelWakelockStats getWakelockStatsFromSystemSuspend( final KernelWakelockStats staleStats) { WakeLockInfo[] wlStats = null; - if (mSuspendControlService == null) { - try { - mSuspendControlService = ISuspendControlService.Stub.asInterface( - ServiceManager.getServiceOrThrow("suspend_control")); - } catch (ServiceNotFoundException e) { - Slog.wtf(TAG, "Required service suspend_control not available", e); - return null; - } + try { + mSuspendControlService = waitForSuspendControlService(); + } catch (ServiceNotFoundException e) { + Slog.wtf(TAG, "Required service suspend_control not available", e); + return null; } try { diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java index 7a9b6590d56b..8e0546e6a86c 100644 --- a/core/java/com/android/internal/os/ProcessCpuTracker.java +++ b/core/java/com/android/internal/os/ProcessCpuTracker.java @@ -945,8 +945,11 @@ public class ProcessCpuTracker { private void getName(Stats st, String cmdlineFile) { String newName = st.name; - if (st.name == null || st.name.equals("app_process") - || st.name.equals("<pre-initialized>")) { + if (st.name == null + || st.name.equals("app_process") + || st.name.equals("<pre-initialized>") + || st.name.equals("usap32") + || st.name.equals("usap64")) { String cmdName = ProcStatsUtil.readTerminatedProcFile(cmdlineFile, (byte) '\0'); if (cmdName != null && cmdName.length() > 1) { newName = cmdName; diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index a7d9827855a2..2c653bbb0f63 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -1092,6 +1092,11 @@ public final class Zygote { public static native int nativeParseSigChld(byte[] in, int length, int[] out); /** + * Returns whether the hardware supports memory tagging (ARM MTE). + */ + public static native boolean nativeSupportsMemoryTagging(); + + /** * Returns whether the kernel supports tagged pointers. Present in the * Android Common Kernel from 4.14 and up. By default, you should prefer * fully-feature Memory Tagging, rather than the static Tagged Pointers. diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 2e32730a6ecb..a70955ce5d4c 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -763,7 +763,11 @@ public class ZygoteInit { Zygote.applyDebuggerSystemProperty(parsedArgs); Zygote.applyInvokeWithSystemProperty(parsedArgs); - if (Zygote.nativeSupportsTaggedPointers()) { + if (Zygote.nativeSupportsMemoryTagging()) { + /* The system server is more privileged than regular app processes, so it has async + * tag checks enabled on hardware that supports memory tagging. */ + parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC; + } else if (Zygote.nativeSupportsTaggedPointers()) { /* Enable pointer tagging in the system server. Hardware support for this is present * in all ARMv8 CPUs. */ parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI; diff --git a/core/java/com/android/internal/util/ContrastColorUtil.java b/core/java/com/android/internal/util/ContrastColorUtil.java index bf088e0a2755..8508a8dd71a4 100644 --- a/core/java/com/android/internal/util/ContrastColorUtil.java +++ b/core/java/com/android/internal/util/ContrastColorUtil.java @@ -73,7 +73,7 @@ public class ContrastColorUtil { private ContrastColorUtil(Context context) { mGrayscaleIconMaxSize = context.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.notification_large_icon_width); + com.android.internal.R.dimen.notification_grayscale_icon_max_size); } /** diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java index 0c2406559dcc..7a79cc9ef868 100644 --- a/core/java/com/android/internal/util/StateMachine.java +++ b/core/java/com/android/internal/util/StateMachine.java @@ -2088,10 +2088,11 @@ public class StateMachine { pw.println(getName() + ":"); pw.println(" total records=" + getLogRecCount()); for (int i = 0; i < getLogRecSize(); i++) { - pw.println(" rec[" + i + "]: " + getLogRec(i).toString()); + pw.println(" rec[" + i + "]: " + getLogRec(i)); pw.flush(); } - pw.println("curState=" + getCurrentState().getName()); + final IState curState = getCurrentState(); + pw.println("curState=" + (curState == null ? "<QUIT>" : curState.getName())); } @Override diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java index dc8d57ab709e..a2de0aff5dfa 100644 --- a/core/java/com/android/internal/widget/PointerLocationView.java +++ b/core/java/com/android/internal/widget/PointerLocationView.java @@ -371,7 +371,7 @@ public class PointerLocationView extends View implements InputDeviceListener, } if (haveLast) { canvas.drawLine(lastX, lastY, x, y, mPathPaint); - final Paint paint = ps.mTraceCurrent[i] ? mCurrentPointPaint : mPaint; + final Paint paint = ps.mTraceCurrent[i - 1] ? mCurrentPointPaint : mPaint; canvas.drawPoint(lastX, lastY, paint); drawn = true; } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 0797b18f12de..f0f1b74c37b3 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -309,4 +309,10 @@ cc_library_shared { ], }, }, + + product_variables: { + experimental_mte: { + cflags: ["-DANDROID_EXPERIMENTAL_MTE"], + }, + }, } diff --git a/core/jni/android_app_ActivityThread.cpp b/core/jni/android_app_ActivityThread.cpp index 5aa684d51a01..e9d9a20c7538 100644 --- a/core/jni/android_app_ActivityThread.cpp +++ b/core/jni/android_app_ActivityThread.cpp @@ -15,7 +15,7 @@ */ #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "core_jni_helpers.h" #include <unistd.h> 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_backup_BackupDataInput.cpp b/core/jni/android_backup_BackupDataInput.cpp index aa8acc16bc3f..79fa2a28666c 100644 --- a/core/jni/android_backup_BackupDataInput.cpp +++ b/core/jni/android_backup_BackupDataInput.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "FileBackupHelper_native" #include <utils/Log.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <androidfw/BackupHelpers.h> diff --git a/core/jni/android_backup_BackupDataOutput.cpp b/core/jni/android_backup_BackupDataOutput.cpp index 4f5d1f80dffc..324b3e71b8cc 100644 --- a/core/jni/android_backup_BackupDataOutput.cpp +++ b/core/jni/android_backup_BackupDataOutput.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "FileBackupHelper_native" #include <utils/Log.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "core_jni_helpers.h" #include <androidfw/BackupHelpers.h> diff --git a/core/jni/android_backup_BackupHelperDispatcher.cpp b/core/jni/android_backup_BackupHelperDispatcher.cpp index fac7eba4c0a2..efe7d0b6ad0a 100644 --- a/core/jni/android_backup_BackupHelperDispatcher.cpp +++ b/core/jni/android_backup_BackupHelperDispatcher.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "BackupHelperDispatcher_native" #include <utils/Log.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <sys/types.h> diff --git a/core/jni/android_backup_FileBackupHelperBase.cpp b/core/jni/android_backup_FileBackupHelperBase.cpp index 65840ee2c016..5f84fafa383e 100644 --- a/core/jni/android_backup_FileBackupHelperBase.cpp +++ b/core/jni/android_backup_FileBackupHelperBase.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "FileBackupHelper_native" #include <utils/Log.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "core_jni_helpers.h" #include <androidfw/BackupHelpers.h> diff --git a/core/jni/android_hardware_SerialPort.cpp b/core/jni/android_hardware_SerialPort.cpp index 3ff24468e3aa..d06107e2e0b2 100644 --- a/core/jni/android_hardware_SerialPort.cpp +++ b/core/jni/android_hardware_SerialPort.cpp @@ -19,7 +19,7 @@ #include "utils/Log.h" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "core_jni_helpers.h" #include <stdio.h> diff --git a/core/jni/android_hardware_UsbDeviceConnection.cpp b/core/jni/android_hardware_UsbDeviceConnection.cpp index b885c285e380..845d65c67719 100644 --- a/core/jni/android_hardware_UsbDeviceConnection.cpp +++ b/core/jni/android_hardware_UsbDeviceConnection.cpp @@ -19,7 +19,7 @@ #include "utils/Log.h" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "core_jni_helpers.h" #include <usbhost/usbhost.h> diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp index 1163b860977d..42cf1f479122 100644 --- a/core/jni/android_net_LocalSocketImpl.cpp +++ b/core/jni/android_net_LocalSocketImpl.cpp @@ -16,7 +16,7 @@ #define LOG_TAG "LocalSocketImpl" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "jni.h" #include "utils/Log.h" #include "utils/misc.h" diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index d4805acb06d0..e56809f66dc7 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -30,7 +30,7 @@ #include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS #include <android_runtime/AndroidRuntime.h> #include <cutils/properties.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <nativehelper/ScopedLocalRef.h> #include <utils/Log.h> #include <utils/misc.h> diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp index de5e3a52a0c1..2f29cae42d07 100644 --- a/core/jni/android_opengl_EGL14.cpp +++ b/core/jni/android_opengl_EGL14.cpp @@ -20,7 +20,7 @@ #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_graphics_SurfaceTexture.h> diff --git a/core/jni/android_opengl_EGL15.cpp b/core/jni/android_opengl_EGL15.cpp index 4aeed8765165..b9c36b9ed9aa 100644 --- a/core/jni/android_opengl_EGL15.cpp +++ b/core/jni/android_opengl_EGL15.cpp @@ -20,7 +20,7 @@ #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> diff --git a/core/jni/android_opengl_EGLExt.cpp b/core/jni/android_opengl_EGLExt.cpp index fef8116dc93a..1758807304bf 100644 --- a/core/jni/android_opengl_EGLExt.cpp +++ b/core/jni/android_opengl_EGLExt.cpp @@ -20,7 +20,7 @@ #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_graphics_SurfaceTexture.h> diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp index 3d9a3b6687b1..e4d138d92621 100644 --- a/core/jni/android_opengl_GLES10.cpp +++ b/core/jni/android_opengl_GLES10.cpp @@ -24,7 +24,7 @@ #include <GLES/glext.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp index 6d7f41e5b3b2..3638b87e201f 100644 --- a/core/jni/android_opengl_GLES10Ext.cpp +++ b/core/jni/android_opengl_GLES10Ext.cpp @@ -24,7 +24,7 @@ #include <GLES/glext.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp index 39ef41a0e19e..1069a1d3acb1 100644 --- a/core/jni/android_opengl_GLES11.cpp +++ b/core/jni/android_opengl_GLES11.cpp @@ -24,7 +24,7 @@ #include <GLES/glext.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp index 1144d5bfb4e6..86d7ecdce44d 100644 --- a/core/jni/android_opengl_GLES11Ext.cpp +++ b/core/jni/android_opengl_GLES11Ext.cpp @@ -24,7 +24,7 @@ #include <GLES/glext.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp index 2add72d14c7b..49baa51f2342 100644 --- a/core/jni/android_opengl_GLES20.cpp +++ b/core/jni/android_opengl_GLES20.cpp @@ -24,7 +24,7 @@ #include <GLES2/gl2ext.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp index a9c021951758..32a2a24c2d2d 100644 --- a/core/jni/android_opengl_GLES30.cpp +++ b/core/jni/android_opengl_GLES30.cpp @@ -24,7 +24,7 @@ #include <GLES3/gl3ext.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/core/jni/android_opengl_GLES31.cpp b/core/jni/android_opengl_GLES31.cpp index 456da93784d5..afe7c63b6d47 100644 --- a/core/jni/android_opengl_GLES31.cpp +++ b/core/jni/android_opengl_GLES31.cpp @@ -22,7 +22,7 @@ #include <stdint.h> #include <GLES3/gl31.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/core/jni/android_opengl_GLES31Ext.cpp b/core/jni/android_opengl_GLES31Ext.cpp index dcaf4a58cd53..81274331ffa4 100644 --- a/core/jni/android_opengl_GLES31Ext.cpp +++ b/core/jni/android_opengl_GLES31Ext.cpp @@ -23,7 +23,7 @@ #include <GLES2/gl2ext.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/core/jni/android_opengl_GLES32.cpp b/core/jni/android_opengl_GLES32.cpp index 6bdc711d64a2..07a794d0ef19 100644 --- a/core/jni/android_opengl_GLES32.cpp +++ b/core/jni/android_opengl_GLES32.cpp @@ -22,7 +22,7 @@ #include <stdint.h> #include <GLES3/gl32.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index f7c6dbd1a65d..3da2fa26ffe6 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -40,7 +40,7 @@ #include <utils/misc.h> #include <utils/String8.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <nativehelper/ScopedUtfChars.h> #include "jni.h" #include <dmabufinfo/dmabufinfo.h> diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp index b6427c9aa01c..48f33a6a3d77 100644 --- a/core/jni/android_os_HwBinder.cpp +++ b/core/jni/android_os_HwBinder.cpp @@ -339,6 +339,10 @@ static jobject JHwBinder_native_getService( return JHwRemoteBinder::NewObject(env, service); } +void JHwBinder_native_setTrebleTestingOverride(JNIEnv*, jclass, jboolean testingOverride) { + hardware::details::setTrebleTestingOverride(testingOverride); +} + void JHwBinder_native_configureRpcThreadpool(JNIEnv *, jclass, jlong maxThreads, jboolean callerWillJoin) { CHECK(maxThreads > 0); @@ -368,6 +372,9 @@ static JNINativeMethod gMethods[] = { { "getService", "(Ljava/lang/String;Ljava/lang/String;Z)L" PACKAGE_PATH "/IHwBinder;", (void *)JHwBinder_native_getService }, + { "setTrebleTestingOverride", "(Z)V", + (void *)JHwBinder_native_setTrebleTestingOverride }, + { "configureRpcThreadpool", "(JZ)V", (void *)JHwBinder_native_configureRpcThreadpool }, diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp index 151dbfce7af3..ff336ee64b54 100644 --- a/core/jni/android_os_HwParcel.cpp +++ b/core/jni/android_os_HwParcel.cpp @@ -122,10 +122,18 @@ void signalExceptionForError(JNIEnv *env, status_t err, bool canThrowRemoteExcep std::stringstream ss; ss << "HwBinder Error: (" << err << ")"; - jniThrowException( - env, - canThrowRemoteException ? "android/os/RemoteException" : "java/lang/RuntimeException", - ss.str().c_str()); + const char* exception = nullptr; + if (canThrowRemoteException) { + if (err == DEAD_OBJECT) { + exception = "android/os/DeadObjectException"; + } else { + exception = "android/os/RemoteException"; + } + } else { + exception = "java/lang/RuntimeException"; + } + + jniThrowException(env, exception, ss.str().c_str()); break; } @@ -292,19 +300,11 @@ static void JHwParcel_native_enforceInterface( return; } - const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL); + const char *interfaceName = env->GetStringUTFChars(interfaceNameObj, NULL); if (interfaceName) { - String8 interfaceNameCopy = String8(String16( - reinterpret_cast<const char16_t *>(interfaceName), - env->GetStringLength(interfaceNameObj))); - - env->ReleaseStringCritical(interfaceNameObj, interfaceName); - interfaceName = NULL; - hardware::Parcel *parcel = JHwParcel::GetNativeContext(env, thiz)->getParcel(); - - bool valid = parcel->enforceInterface(interfaceNameCopy.string()); + bool valid = parcel->enforceInterface(interfaceName); if (!valid) { jniThrowException( @@ -312,6 +312,7 @@ static void JHwParcel_native_enforceInterface( "java/lang/SecurityException", "HWBinder invocation to an incorrect interface"); } + env->ReleaseStringUTFChars(interfaceNameObj, interfaceName); } } diff --git a/core/jni/android_os_MemoryFile.cpp b/core/jni/android_os_MemoryFile.cpp index b21566bbc186..8d91e635454c 100644 --- a/core/jni/android_os_MemoryFile.cpp +++ b/core/jni/android_os_MemoryFile.cpp @@ -19,7 +19,7 @@ #include <cutils/ashmem.h> #include "core_jni_helpers.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <unistd.h> #include <sys/mman.h> diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index e7a2fb428b50..6ec5bce224fc 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -20,7 +20,7 @@ #include "android_os_Parcel.h" #include "android_util_Binder.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <fcntl.h> #include <stdio.h> @@ -510,7 +510,11 @@ static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, j if (fd < 0) return NULL; fd = fcntl(fd, F_DUPFD_CLOEXEC, 0); if (fd < 0) return NULL; - return jniCreateFileDescriptor(env, fd); + jobject jifd = jniCreateFileDescriptor(env, fd); + if (jifd == NULL) { + close(fd); + } + return jifd; } return NULL; } @@ -660,8 +664,8 @@ static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong IPCThreadState* threadState = IPCThreadState::self(); const int32_t oldPolicy = threadState->getStrictModePolicy(); const bool isValid = parcel->enforceInterface( - String16(reinterpret_cast<const char16_t*>(str), - env->GetStringLength(name)), + reinterpret_cast<const char16_t*>(str), + env->GetStringLength(name), threadState); env->ReleaseStringCritical(name, str); if (isValid) { diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp index 236ee6123cde..43c1cfd33fa0 100644 --- a/core/jni/android_os_SELinux.cpp +++ b/core/jni/android_os_SELinux.cpp @@ -15,14 +15,17 @@ */ #define LOG_TAG "SELinuxJNI" + +#include <errno.h> +#include <fcntl.h> + #include <utils/Log.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "jni.h" #include "core_jni_helpers.h" #include "selinux/selinux.h" #include "selinux/android.h" -#include <errno.h> #include <memory> #include <atomic> #include <nativehelper/ScopedLocalRef.h> diff --git a/core/jni/android_os_SharedMemory.cpp b/core/jni/android_os_SharedMemory.cpp index c33405def25e..dc86187d8fea 100644 --- a/core/jni/android_os_SharedMemory.cpp +++ b/core/jni/android_os_SharedMemory.cpp @@ -22,7 +22,7 @@ #include <utils/Log.h> #include <nativehelper/jni_macros.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <nativehelper/ScopedLocalRef.h> #include <algorithm> @@ -69,7 +69,11 @@ jobject SharedMemory_nCreate(JNIEnv* env, jobject, jstring jname, jint size) { return nullptr; } - return jniCreateFileDescriptor(env, fd); + jobject jifd = jniCreateFileDescriptor(env, fd); + if (jifd == nullptr) { + close(fd); + } + return jifd; } jint SharedMemory_nGetSize(JNIEnv* env, jobject, jobject fileDescriptor) { diff --git a/core/jni/android_server_NetworkManagementSocketTagger.cpp b/core/jni/android_server_NetworkManagementSocketTagger.cpp index 58295af50135..afad08a87d37 100644 --- a/core/jni/android_server_NetworkManagementSocketTagger.cpp +++ b/core/jni/android_server_NetworkManagementSocketTagger.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "NMST_QTagUidNative" #include <utils/Log.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "jni.h" #include <utils/misc.h> diff --git a/core/jni/android_text_Hyphenator.cpp b/core/jni/android_text_Hyphenator.cpp index de307737493e..21402b6602eb 100644 --- a/core/jni/android_text_Hyphenator.cpp +++ b/core/jni/android_text_Hyphenator.cpp @@ -14,9 +14,10 @@ * limitations under the License. */ +#include <fcntl.h> #include <sys/mman.h> -#include <sys/types.h> #include <sys/stat.h> +#include <sys/types.h> #include <unistd.h> #include <algorithm> diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 12abc256a20e..e6881b3995a8 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -18,14 +18,13 @@ #define LOG_TAG "asset" #include <inttypes.h> +#include <linux/capability.h> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> -#include <private/android_filesystem_config.h> // for AID_SYSTEM - #include <sstream> #include <string> @@ -46,7 +45,7 @@ #include "core_jni_helpers.h" #include "jni.h" -#include "nativehelper/JNIHelp.h" +#include "nativehelper/JNIPlatformHelp.h" #include "nativehelper/ScopedPrimitiveArray.h" #include "nativehelper/ScopedStringChars.h" #include "nativehelper/ScopedUtfChars.h" 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 9eede83e21e5..2a73d0d5583c 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -55,6 +55,7 @@ #include <signal.h> #include <stdio.h> #include <stdlib.h> +#include <sys/auxv.h> #include <sys/capability.h> #include <sys/cdefs.h> #include <sys/eventfd.h> @@ -76,6 +77,8 @@ #include <android-base/stringprintf.h> #include <android-base/unique_fd.h> #include <bionic/malloc.h> +#include <bionic/mte.h> +#include <bionic/mte_kernel.h> #include <cutils/fs.h> #include <cutils/multiuser.h> #include <cutils/sockets.h> @@ -98,6 +101,19 @@ #include "nativebridge/native_bridge.h" +/* Functions in the callchain during the fork shall not be protected with + Armv8.3-A Pointer Authentication, otherwise child will not be able to return. */ +#ifdef __ARM_FEATURE_PAC_DEFAULT +#ifdef __ARM_FEATURE_BTI_DEFAULT +#define NO_PAC_FUNC __attribute__((target("branch-protection=bti"))) +#else +#define NO_PAC_FUNC __attribute__((target("branch-protection=none"))) +#endif /* __ARM_FEATURE_BTI_DEFAULT */ +#else /* !__ARM_FEATURE_PAC_DEFAULT */ +#define NO_PAC_FUNC +#endif /* __ARM_FEATURE_PAC_DEFAULT */ + + namespace { // TODO (chriswailes): Add a function to initialize native Zygote data. @@ -344,6 +360,8 @@ enum RuntimeFlags : uint32_t { PROFILE_FROM_SHELL = 1 << 15, MEMORY_TAG_LEVEL_MASK = (1 << 19) | (1 << 20), MEMORY_TAG_LEVEL_TBI = 1 << 19, + MEMORY_TAG_LEVEL_ASYNC = 2 << 19, + MEMORY_TAG_LEVEL_SYNC = 3 << 19, GWP_ASAN_LEVEL_MASK = (1 << 21) | (1 << 22), GWP_ASAN_LEVEL_NEVER = 0 << 21, GWP_ASAN_LEVEL_LOTTERY = 1 << 21, @@ -1071,7 +1089,23 @@ static void ClearUsapTable() { gUsapPoolCount = 0; } +NO_PAC_FUNC +static void PAuthKeyChange(JNIEnv* env) { +#ifdef __aarch64__ + unsigned long int hwcaps = getauxval(AT_HWCAP); + if (hwcaps & HWCAP_PACA) { + const unsigned long key_mask = PR_PAC_APIAKEY | PR_PAC_APIBKEY | + PR_PAC_APDAKEY | PR_PAC_APDBKEY | PR_PAC_APGAKEY; + if (prctl(PR_PAC_RESET_KEYS, key_mask, 0, 0, 0) != 0) { + ALOGE("Failed to change the PAC keys: %s", strerror(errno)); + RuntimeAbort(env, __LINE__, "PAC key change failed."); + } + } +#endif +} + // Utility routine to fork a process from the zygote. +NO_PAC_FUNC static pid_t ForkCommon(JNIEnv* env, bool is_system_server, const std::vector<int>& fds_to_close, const std::vector<int>& fds_to_ignore, @@ -1122,6 +1156,7 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server, } // The child process. + PAuthKeyChange(env); PreApplicationInit(); // Clean up any descriptors which must be closed immediately @@ -1599,6 +1634,28 @@ static void BindMountStorageDirs(JNIEnv* env, jobjectArray pkg_data_info_list, } } +#ifdef ANDROID_EXPERIMENTAL_MTE +static void SetTagCheckingLevel(int level) { +#ifdef __aarch64__ + if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) { + return; + } + + int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0); + if (tagged_addr_ctrl < 0) { + ALOGE("prctl(PR_GET_TAGGED_ADDR_CTRL) failed: %s", strerror(errno)); + return; + } + + tagged_addr_ctrl = (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | level; + if (prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) < 0) { + ALOGE("prctl(PR_SET_TAGGED_ADDR_CTRL, %d) failed: %s", tagged_addr_ctrl, + strerror(errno)); + } +#endif +} +#endif + // Utility routine to specialize a zygote child process. static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, @@ -1733,7 +1790,23 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, case RuntimeFlags::MEMORY_TAG_LEVEL_TBI: heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI; break; + case RuntimeFlags::MEMORY_TAG_LEVEL_ASYNC: +#ifdef ANDROID_EXPERIMENTAL_MTE + SetTagCheckingLevel(PR_MTE_TCF_ASYNC); +#endif + heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC; + break; + case RuntimeFlags::MEMORY_TAG_LEVEL_SYNC: +#ifdef ANDROID_EXPERIMENTAL_MTE + SetTagCheckingLevel(PR_MTE_TCF_SYNC); +#endif + // TODO(pcc): Use SYNC here once the allocator supports it. + heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC; + break; default: +#ifdef ANDROID_EXPERIMENTAL_MTE + SetTagCheckingLevel(PR_MTE_TCF_NONE); +#endif heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE; } android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &heap_tagging_level, sizeof(heap_tagging_level)); @@ -2019,6 +2092,7 @@ static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jcl PreApplicationInit(); } +NO_PAC_FUNC static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, @@ -2071,6 +2145,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( return pid; } +NO_PAC_FUNC static jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, @@ -2142,6 +2217,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( * @param is_priority_fork Controls the nice level assigned to the newly created process * @return */ +NO_PAC_FUNC static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env, jclass, jint read_pipe_fd, @@ -2432,6 +2508,14 @@ static jint com_android_internal_os_Zygote_nativeParseSigChld(JNIEnv* env, jclas return -1; } +static jboolean com_android_internal_os_Zygote_nativeSupportsMemoryTagging(JNIEnv* env, jclass) { +#if defined(__aarch64__) + return mte_supported(); +#else + return false; +#endif +} + static jboolean com_android_internal_os_Zygote_nativeSupportsTaggedPointers(JNIEnv* env, jclass) { #ifdef __aarch64__ int res = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0); @@ -2476,6 +2560,8 @@ static const JNINativeMethod gMethods[] = { (void*)com_android_internal_os_Zygote_nativeBoostUsapPriority}, {"nativeParseSigChld", "([BI[I)I", (void*)com_android_internal_os_Zygote_nativeParseSigChld}, + {"nativeSupportsMemoryTagging", "()Z", + (void*)com_android_internal_os_Zygote_nativeSupportsMemoryTagging}, {"nativeSupportsTaggedPointers", "()Z", (void*)com_android_internal_os_Zygote_nativeSupportsTaggedPointers}, }; diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp index 6b893cb94444..ffc1ddc03355 100644 --- a/core/jni/com_google_android_gles_jni_GLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp @@ -21,7 +21,7 @@ #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h index 8bb4d503cc82..eeda275b811c 100644 --- a/core/jni/core_jni_helpers.h +++ b/core/jni/core_jni_helpers.h @@ -17,7 +17,7 @@ #ifndef CORE_JNI_HELPERS #define CORE_JNI_HELPERS -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <nativehelper/scoped_local_ref.h> #include <nativehelper/scoped_utf_chars.h> #include <android_runtime/AndroidRuntime.h> diff --git a/core/jni/eventlog_helper.h b/core/jni/eventlog_helper.h index 3a05195ebc9e..29c023a9bd24 100644 --- a/core/jni/eventlog_helper.h +++ b/core/jni/eventlog_helper.h @@ -24,7 +24,7 @@ #include <android-base/macros.h> #include <log/log_event_list.h> -#include <log/log.h> +#include <log/log_read.h> #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedLocalRef.h> diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp index c72668f84fb1..38981b0caaf7 100644 --- a/core/jni/fd_utils.cpp +++ b/core/jni/fd_utils.cpp @@ -35,6 +35,7 @@ static const char* kPathWhitelist[] = { "/apex/com.android.conscrypt/javalib/conscrypt.jar", "/apex/com.android.ipsec/javalib/ike.jar", + "/apex/com.android.i18n/javalib/core-icu4j.jar", "/apex/com.android.media/javalib/updatable-media.jar", "/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar", "/apex/com.android.os.statsd/javalib/framework-statsd.jar", @@ -85,11 +86,18 @@ bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const { } // Framework jars are allowed. - static const char* kFrameworksPrefix = "/system/framework/"; + static const char* kFrameworksPrefix[] = { + "/system/framework/", + "/system_ext/framework/", + }; + static const char* kJarSuffix = ".jar"; - if (android::base::StartsWith(path, kFrameworksPrefix) - && android::base::EndsWith(path, kJarSuffix)) { - return true; + + for (const auto& frameworks_prefix : kFrameworksPrefix) { + if (android::base::StartsWith(path, frameworks_prefix) + && android::base::EndsWith(path, kJarSuffix)) { + return true; + } } // Jars from the ART APEX are allowed. diff --git a/core/proto/android/bluetooth/enums.proto b/core/proto/android/bluetooth/enums.proto index 22f249820b11..dc60ededf965 100644 --- a/core/proto/android/bluetooth/enums.proto +++ b/core/proto/android/bluetooth/enums.proto @@ -41,6 +41,7 @@ enum EnableDisableReasonEnum { ENABLE_DISABLE_REASON_USER_SWITCH = 8; ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9; ENABLE_DISABLE_REASON_FACTORY_RESET = 10; + ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED = 11; } enum DirectionEnum { diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index 023197baef12..9bbe0caa9e98 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -910,13 +910,8 @@ message GlobalSettingsProto { optional SettingProto storage_full_threshold_bytes = 4 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto storage_cache_percentage = 5 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto storage_cache_max_bytes = 6 [ (android.privacy).dest = DEST_AUTOMATIC ]; - // System VDSO global setting. This links to the "sys.vdso" system property. - // The following values are supported: - // false -> both 32 and 64 bit vdso disabled - // 32 -> 32 bit vdso enabled - // 64 -> 64 bit vdso enabled - // Any other value defaults to both 32 bit and 64 bit true. - optional SettingProto vdso = 7 [ (android.privacy).dest = DEST_AUTOMATIC ]; + // Used to be sys_vdso + reserved 7; // UidCpuPower global setting. This links the sys.uidcpupower system property. // The following values are supported: // 0 -> /proc/uid_cpupower/* are disabled diff --git a/core/proto/android/server/connectivity/Android.bp b/core/proto/android/server/connectivity/Android.bp index 413623963851..50c238b96307 100644 --- a/core/proto/android/server/connectivity/Android.bp +++ b/core/proto/android/server/connectivity/Android.bp @@ -21,4 +21,6 @@ java_library_static { "data_stall_event.proto", ], sdk_version: "system_current", + // this is part of updatable modules(NetworkStack) which targets 29(Q) + min_sdk_version: "29", } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 9945057f0e94..013249335268 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -228,6 +228,8 @@ <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY" /> + <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_READ_STATUS_CHANGED" /> + <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_DELETED_STATUS_CHANGED" /> <protected-broadcast android:name="com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT" /> <protected-broadcast diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a17f356e1fc2..8bbb2cec8a9d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2912,6 +2912,11 @@ empty string is passed in --> <string name="config_wlan_data_service_package" translatable="false"></string> + <!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec + tunnels across service restart. If iwlan tunnels are not persisted across restart, + Framework will clean up dangling data connections when service restarts --> + <bool name="config_wlan_data_service_conn_persistence_on_restart">true</bool> + <!-- Cellular data service class name to bind to by default. If none is specified in an overlay, an empty string is passed in --> <string name="config_wwan_data_service_class" translatable="false"></string> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index ebaf85c64a14..cbc08ba621a9 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -694,6 +694,8 @@ <dimen name="notification_media_image_max_width_low_ram">100dp</dimen> <!-- The size of the right icon image when on low ram --> <dimen name="notification_right_icon_size_low_ram">@dimen/notification_right_icon_size</dimen> + <!-- The maximum size of the grayscale icon --> + <dimen name="notification_grayscale_icon_max_size">256dp</dimen> <dimen name="messaging_avatar_size">@dimen/notification_right_icon_size</dimen> <dimen name="conversation_avatar_size">52dp</dimen> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 06f357e79a62..dcd0b51772a7 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -302,6 +302,7 @@ <java-symbol type="string" name="config_wlan_network_service_package" /> <java-symbol type="string" name="config_wwan_network_service_class" /> <java-symbol type="string" name="config_wlan_network_service_class" /> + <java-symbol type="bool" name="config_wlan_data_service_conn_persistence_on_restart" /> <java-symbol type="string" name="config_wwan_data_service_package" /> <java-symbol type="string" name="config_wlan_data_service_package" /> <java-symbol type="string" name="config_wwan_data_service_class" /> @@ -3363,6 +3364,7 @@ <java-symbol type="dimen" name="notification_media_image_max_width_low_ram"/> <java-symbol type="dimen" name="notification_media_image_max_height_low_ram"/> <java-symbol type="dimen" name="notification_right_icon_size_low_ram"/> + <java-symbol type="dimen" name="notification_grayscale_icon_max_size"/> <java-symbol type="dimen" name="notification_custom_view_max_image_height_low_ram"/> <java-symbol type="dimen" name="notification_custom_view_max_image_width_low_ram"/> diff --git a/core/tests/PlatformCompatFramework/OWNERS b/core/tests/PlatformCompatFramework/OWNERS index 2b7cdb0cbce9..cfd0a4b079ad 100644 --- a/core/tests/PlatformCompatFramework/OWNERS +++ b/core/tests/PlatformCompatFramework/OWNERS @@ -2,6 +2,5 @@ platform-compat-eng+reviews@google.com andreionea@google.com -atrost@google.com mathewi@google.com satayev@google.com diff --git a/core/tests/bluetoothtests/AndroidManifest.xml b/core/tests/bluetoothtests/AndroidManifest.xml index 7f9d8749358c..6849a90f5010 100644 --- a/core/tests/bluetoothtests/AndroidManifest.xml +++ b/core/tests/bluetoothtests/AndroidManifest.xml @@ -15,14 +15,18 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.bluetooth.tests" > + package="com.android.bluetooth.tests" + android:sharedUserId="android.uid.bluetooth" > <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.LOCAL_MAC_ADDRESS" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> + <uses-permission android:name="android.permission.RECEIVE_SMS" /> + <uses-permission android:name="android.permission.READ_SMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java index 4b32ceae0617..89dbe3f75b56 100644 --- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java +++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java @@ -360,6 +360,30 @@ public class BluetoothStressTest extends InstrumentationTestCase { mTestUtils.unpair(mAdapter, device); } + /* Make sure there is at least 1 unread message in the last week on remote device */ + public void testMceSetMessageStatus() { + int iterations = BluetoothTestRunner.sMceSetMessageStatusIterations; + if (iterations == 0) { + return; + } + + BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); + mTestUtils.enable(mAdapter); + mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.MAP_CLIENT, null); + mTestUtils.mceGetUnreadMessage(mAdapter, device); + + for (int i = 0; i < iterations; i++) { + mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.READ); + mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.UNREAD); + } + + /** + * It is hard to find device to support set undeleted status, so just + * set deleted in 1 iteration + **/ + mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.DELETED); + } + private void sleep(long time) { try { Thread.sleep(time); diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestRunner.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestRunner.java index 56e691d8c246..d19c2c3e7e24 100644 --- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestRunner.java +++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestRunner.java @@ -40,6 +40,7 @@ import android.util.Log; * [-e connect_input_iterations <iterations>] \ * [-e connect_pan_iterations <iterations>] \ * [-e start_stop_sco_iterations <iterations>] \ + * [-e mce_set_message_status_iterations <iterations>] \ * [-e pair_address <address>] \ * [-e headset_address <address>] \ * [-e a2dp_address <address>] \ @@ -64,6 +65,7 @@ public class BluetoothTestRunner extends InstrumentationTestRunner { public static int sConnectInputIterations = 100; public static int sConnectPanIterations = 100; public static int sStartStopScoIterations = 100; + public static int sMceSetMessageStatusIterations = 100; public static String sDeviceAddress = ""; public static byte[] sDevicePairPin = {'1', '2', '3', '4'}; @@ -173,6 +175,15 @@ public class BluetoothTestRunner extends InstrumentationTestRunner { } } + val = arguments.getString("mce_set_message_status_iterations"); + if (val != null) { + try { + sMceSetMessageStatusIterations = Integer.parseInt(val); + } catch (NumberFormatException e) { + // Invalid argument, fall back to default value + } + } + val = arguments.getString("device_address"); if (val != null) { sDeviceAddress = val; diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java index ed613c36b89b..409025bc670d 100644 --- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java +++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java @@ -56,6 +56,10 @@ public class BluetoothTestUtils extends Assert { private static final int CONNECT_PROXY_TIMEOUT = 5000; /** Time between polls in ms. */ private static final int POLL_TIME = 100; + /** Timeout to get map message in ms. */ + private static final int GET_UNREAD_MESSAGE_TIMEOUT = 10000; + /** Timeout to set map message status in ms. */ + private static final int SET_MESSAGE_STATUS_TIMEOUT = 2000; private abstract class FlagReceiver extends BroadcastReceiver { private int mExpectedFlags = 0; @@ -98,6 +102,8 @@ public class BluetoothTestUtils extends Assert { private static final int STATE_TURNING_ON_FLAG = 1 << 6; private static final int STATE_ON_FLAG = 1 << 7; private static final int STATE_TURNING_OFF_FLAG = 1 << 8; + private static final int STATE_GET_MESSAGE_FINISHED_FLAG = 1 << 9; + private static final int STATE_SET_MESSAGE_STATUS_FINISHED_FLAG = 1 << 10; public BluetoothReceiver(int expectedFlags) { super(expectedFlags); @@ -231,6 +237,9 @@ public class BluetoothTestUtils extends Assert { case BluetoothProfile.PAN: mConnectionAction = BluetoothPan.ACTION_CONNECTION_STATE_CHANGED; break; + case BluetoothProfile.MAP_CLIENT: + mConnectionAction = BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED; + break; default: mConnectionAction = null; } @@ -308,6 +317,34 @@ public class BluetoothTestUtils extends Assert { } } + + private class MceSetMessageStatusReceiver extends FlagReceiver { + private static final int MESSAGE_RECEIVED_FLAG = 1; + private static final int STATUS_CHANGED_FLAG = 1 << 1; + + public MceSetMessageStatusReceiver(int expectedFlags) { + super(expectedFlags); + } + + @Override + public void onReceive(Context context, Intent intent) { + if (BluetoothMapClient.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) { + String handle = intent.getStringExtra(BluetoothMapClient.EXTRA_MESSAGE_HANDLE); + assertNotNull(handle); + setFiredFlag(MESSAGE_RECEIVED_FLAG); + mMsgHandle = handle; + } else if (BluetoothMapClient.ACTION_MESSAGE_DELETED_STATUS_CHANGED.equals(intent.getAction())) { + int result = intent.getIntExtra(BluetoothMapClient.EXTRA_RESULT_CODE, BluetoothMapClient.RESULT_FAILURE); + assertEquals(result, BluetoothMapClient.RESULT_SUCCESS); + setFiredFlag(STATUS_CHANGED_FLAG); + } else if (BluetoothMapClient.ACTION_MESSAGE_READ_STATUS_CHANGED.equals(intent.getAction())) { + int result = intent.getIntExtra(BluetoothMapClient.EXTRA_RESULT_CODE, BluetoothMapClient.RESULT_FAILURE); + assertEquals(result, BluetoothMapClient.RESULT_SUCCESS); + setFiredFlag(STATUS_CHANGED_FLAG); + } + } + } + private BluetoothProfile.ServiceListener mServiceListener = new BluetoothProfile.ServiceListener() { @Override @@ -326,6 +363,9 @@ public class BluetoothTestUtils extends Assert { case BluetoothProfile.PAN: mPan = (BluetoothPan) proxy; break; + case BluetoothProfile.MAP_CLIENT: + mMce = (BluetoothMapClient) proxy; + break; } } } @@ -346,6 +386,9 @@ public class BluetoothTestUtils extends Assert { case BluetoothProfile.PAN: mPan = null; break; + case BluetoothProfile.MAP_CLIENT: + mMce = null; + break; } } } @@ -362,6 +405,8 @@ public class BluetoothTestUtils extends Assert { private BluetoothHeadset mHeadset = null; private BluetoothHidHost mInput = null; private BluetoothPan mPan = null; + private BluetoothMapClient mMce = null; + private String mMsgHandle = null; /** * Creates a utility instance for testing Bluetooth. @@ -898,7 +943,7 @@ public class BluetoothTestUtils extends Assert { * @param adapter The BT adapter. * @param device The remote device. * @param profile The profile to connect. One of {@link BluetoothProfile#A2DP}, - * {@link BluetoothProfile#HEADSET}, or {@link BluetoothProfile#HID_HOST}. + * {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#HID_HOST} or {@link BluetoothProfile#MAP_CLIENT}.. * @param methodName The method name to printed in the logs. If null, will be * "connectProfile(profile=<profile>, device=<device>)" */ @@ -941,6 +986,8 @@ public class BluetoothTestUtils extends Assert { assertTrue(((BluetoothHeadset)proxy).connect(device)); } else if (profile == BluetoothProfile.HID_HOST) { assertTrue(((BluetoothHidHost)proxy).connect(device)); + } else if (profile == BluetoothProfile.MAP_CLIENT) { + assertTrue(((BluetoothMapClient)proxy).connect(device)); } break; default: @@ -1016,6 +1063,8 @@ public class BluetoothTestUtils extends Assert { assertTrue(((BluetoothHeadset)proxy).disconnect(device)); } else if (profile == BluetoothProfile.HID_HOST) { assertTrue(((BluetoothHidHost)proxy).disconnect(device)); + } else if (profile == BluetoothProfile.MAP_CLIENT) { + assertTrue(((BluetoothMapClient)proxy).disconnect(device)); } break; case BluetoothProfile.STATE_DISCONNECTED: @@ -1373,6 +1422,89 @@ public class BluetoothTestUtils extends Assert { } } + public void mceGetUnreadMessage(BluetoothAdapter adapter, BluetoothDevice device) { + int mask; + String methodName = "getUnreadMessage"; + + if (!adapter.isEnabled()) { + fail(String.format("%s bluetooth not enabled", methodName)); + } + + if (!adapter.getBondedDevices().contains(device)) { + fail(String.format("%s device not paired", methodName)); + } + + mMce = (BluetoothMapClient) connectProxy(adapter, BluetoothProfile.MAP_CLIENT); + assertNotNull(mMce); + + if (mMce.getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) { + fail(String.format("%s device is not connected", methodName)); + } + + mMsgHandle = null; + mask = MceSetMessageStatusReceiver.MESSAGE_RECEIVED_FLAG; + MceSetMessageStatusReceiver receiver = getMceSetMessageStatusReceiver(device, mask); + assertTrue(mMce.getUnreadMessages(device)); + + long s = System.currentTimeMillis(); + while (System.currentTimeMillis() - s < GET_UNREAD_MESSAGE_TIMEOUT) { + if ((receiver.getFiredFlags() & mask) == mask) { + writeOutput(String.format("%s completed", methodName)); + removeReceiver(receiver); + return; + } + sleep(POLL_TIME); + } + int firedFlags = receiver.getFiredFlags(); + removeReceiver(receiver); + fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%s)", + methodName, mMce.getConnectionState(device), BluetoothMapClient.STATE_CONNECTED, firedFlags, mask)); + } + + /** + * Set a message to read/unread/deleted/undeleted + */ + public void mceSetMessageStatus(BluetoothAdapter adapter, BluetoothDevice device, int status) { + int mask; + String methodName = "setMessageStatus"; + + if (!adapter.isEnabled()) { + fail(String.format("%s bluetooth not enabled", methodName)); + } + + if (!adapter.getBondedDevices().contains(device)) { + fail(String.format("%s device not paired", methodName)); + } + + mMce = (BluetoothMapClient) connectProxy(adapter, BluetoothProfile.MAP_CLIENT); + assertNotNull(mMce); + + if (mMce.getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) { + fail(String.format("%s device is not connected", methodName)); + } + + assertNotNull(mMsgHandle); + mask = MceSetMessageStatusReceiver.STATUS_CHANGED_FLAG; + MceSetMessageStatusReceiver receiver = getMceSetMessageStatusReceiver(device, mask); + + assertTrue(mMce.setMessageStatus(device, mMsgHandle, status)); + + long s = System.currentTimeMillis(); + while (System.currentTimeMillis() - s < SET_MESSAGE_STATUS_TIMEOUT) { + if ((receiver.getFiredFlags() & mask) == mask) { + writeOutput(String.format("%s completed", methodName)); + removeReceiver(receiver); + return; + } + sleep(POLL_TIME); + } + + int firedFlags = receiver.getFiredFlags(); + removeReceiver(receiver); + fail(String.format("%s timeout: state=%d (expected %d), flags=0x%x (expected 0x%s)", + methodName, mMce.getConnectionState(device), BluetoothPan.STATE_CONNECTED, firedFlags, mask)); + } + private void addReceiver(BroadcastReceiver receiver, String[] actions) { IntentFilter filter = new IntentFilter(); for (String action: actions) { @@ -1408,7 +1540,8 @@ public class BluetoothTestUtils extends Assert { String[] actions = { BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED, BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED, - BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED}; + BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED, + BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED}; ConnectProfileReceiver receiver = new ConnectProfileReceiver(device, profile, expectedFlags); addReceiver(receiver, actions); @@ -1430,6 +1563,16 @@ public class BluetoothTestUtils extends Assert { return receiver; } + private MceSetMessageStatusReceiver getMceSetMessageStatusReceiver(BluetoothDevice device, + int expectedFlags) { + String[] actions = {BluetoothMapClient.ACTION_MESSAGE_RECEIVED, + BluetoothMapClient.ACTION_MESSAGE_READ_STATUS_CHANGED, + BluetoothMapClient.ACTION_MESSAGE_DELETED_STATUS_CHANGED}; + MceSetMessageStatusReceiver receiver = new MceSetMessageStatusReceiver(expectedFlags); + addReceiver(receiver, actions); + return receiver; + } + private void removeReceiver(BroadcastReceiver receiver) { mContext.unregisterReceiver(receiver); mReceivers.remove(receiver); @@ -1456,6 +1599,10 @@ public class BluetoothTestUtils extends Assert { if (mPan != null) { return mPan; } + case BluetoothProfile.MAP_CLIENT: + if (mMce != null) { + return mMce; + } break; default: return null; @@ -1483,6 +1630,11 @@ public class BluetoothTestUtils extends Assert { sleep(POLL_TIME); } return mPan; + case BluetoothProfile.MAP_CLIENT: + while (mMce == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) { + sleep(POLL_TIME); + } + return mMce; default: return null; } diff --git a/core/tests/coretests/apks/install_jni_lib/Android.bp b/core/tests/coretests/apks/install_jni_lib/Android.bp index f20f59958736..df19fa09adcf 100644 --- a/core/tests/coretests/apks/install_jni_lib/Android.bp +++ b/core/tests/coretests/apks/install_jni_lib/Android.bp @@ -24,4 +24,5 @@ cc_test_library { "-Wall", "-Werror", ], + header_libs: ["jni_headers"] } diff --git a/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java b/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java index d00d052db590..0af8c728aba3 100644 --- a/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java +++ b/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java @@ -154,6 +154,29 @@ public class EuiccProfileInfoTest { } @Test + public void testBuilder_BasedOnAnotherProfileWithEmptyAccessRules() { + EuiccProfileInfo p = + new EuiccProfileInfo.Builder("21430000000000006587") + .setNickname("profile nickname") + .setProfileName("profile name") + .setServiceProviderName("service provider") + .setCarrierIdentifier( + new CarrierIdentifier( + new byte[] {0x23, 0x45, 0x67}, + "123", + "45")) + .setState(EuiccProfileInfo.PROFILE_STATE_ENABLED) + .setProfileClass(EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL) + .setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE) + .setUiccAccessRule(null) + .build(); + + EuiccProfileInfo copied = new EuiccProfileInfo.Builder(p).build(); + + assertEquals(null, copied.getUiccAccessRules()); + } + + @Test public void testEqualsHashCode() { EuiccProfileInfo p = new EuiccProfileInfo.Builder("21430000000000006587") diff --git a/core/tests/coretests/src/android/text/format/DateFormatTest.java b/core/tests/coretests/src/android/text/format/DateFormatTest.java index 5a0a84db5905..a3434e885012 100644 --- a/core/tests/coretests/src/android/text/format/DateFormatTest.java +++ b/core/tests/coretests/src/android/text/format/DateFormatTest.java @@ -16,9 +16,12 @@ package android.text.format; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import android.icu.text.DateFormatSymbols; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; @@ -27,6 +30,7 @@ import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Arrays; import java.util.Locale; @Presubmit @@ -55,4 +59,80 @@ public class DateFormatTest { assertFalse(DateFormat.is24HourLocale(Locale.US)); assertTrue(DateFormat.is24HourLocale(Locale.GERMANY)); } + + @Test + public void testgetIcuDateFormatSymbols() { + DateFormatSymbols dfs = DateFormat.getIcuDateFormatSymbols(Locale.US); + assertEquals("AM", dfs.getAmPmStrings()[0]); + assertEquals("PM", dfs.getAmPmStrings()[1]); + assertEquals("a", dfs.getAmpmNarrowStrings()[0]); + assertEquals("p", dfs.getAmpmNarrowStrings()[1]); + } + + @Test + public void testGetDateFormatOrder() { + // lv and fa use differing orders depending on whether you're using numeric or + // textual months. + Locale lv = new Locale("lv"); + assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder( + best(lv, "yyyy-M-dd")))); + assertEquals("[y, d, M]", Arrays.toString(DateFormat.getDateFormatOrder( + best(lv, "yyyy-MMM-dd")))); + assertEquals("[d, M, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder( + best(lv, "MMM-dd")))); + Locale fa = new Locale("fa"); + assertEquals("[y, M, d]", Arrays.toString(DateFormat.getDateFormatOrder( + best(fa, "yyyy-M-dd")))); + assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder( + best(fa, "yyyy-MMM-dd")))); + assertEquals("[d, M, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder( + best(fa, "MMM-dd")))); + + // English differs on each side of the Atlantic. + Locale enUS = Locale.US; + assertEquals("[M, d, y]", Arrays.toString(DateFormat.getDateFormatOrder( + best(enUS, "yyyy-M-dd")))); + assertEquals("[M, d, y]", Arrays.toString(DateFormat.getDateFormatOrder( + best(enUS, "yyyy-MMM-dd")))); + assertEquals("[M, d, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder( + best(enUS, "MMM-dd")))); + Locale enGB = Locale.UK; + assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder( + best(enGB, "yyyy-M-dd")))); + assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder( + best(enGB, "yyyy-MMM-dd")))); + assertEquals("[d, M, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder( + best(enGB, "MMM-dd")))); + + assertEquals("[y, M, d]", Arrays.toString(DateFormat.getDateFormatOrder( + "yyyy - 'why' '' 'ddd' MMM-dd"))); + + try { + DateFormat.getDateFormatOrder("the quick brown fox jumped over the lazy dog"); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + DateFormat.getDateFormatOrder("'"); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + DateFormat.getDateFormatOrder("yyyy'"); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + DateFormat.getDateFormatOrder("yyyy'MMM"); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + private static String best(Locale l, String skeleton) { + return DateFormat.getBestDateTimePattern(l, skeleton); + } } diff --git a/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java b/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java new file mode 100644 index 000000000000..0f17d27048f3 --- /dev/null +++ b/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java @@ -0,0 +1,671 @@ +/* + * Copyright (C) 2013 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.text.format; + +import static android.icu.util.TimeZone.GMT_ZONE; +import static android.icu.util.ULocale.ENGLISH; +import static android.text.format.DateIntervalFormat.formatDateRange; +import static android.text.format.DateUtils.FORMAT_12HOUR; +import static android.text.format.DateUtils.FORMAT_24HOUR; +import static android.text.format.DateUtils.FORMAT_ABBREV_ALL; +import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH; +import static android.text.format.DateUtils.FORMAT_ABBREV_TIME; +import static android.text.format.DateUtils.FORMAT_ABBREV_WEEKDAY; +import static android.text.format.DateUtils.FORMAT_NO_MONTH_DAY; +import static android.text.format.DateUtils.FORMAT_NO_YEAR; +import static android.text.format.DateUtils.FORMAT_NUMERIC_DATE; +import static android.text.format.DateUtils.FORMAT_SHOW_DATE; +import static android.text.format.DateUtils.FORMAT_SHOW_TIME; +import static android.text.format.DateUtils.FORMAT_SHOW_WEEKDAY; +import static android.text.format.DateUtils.FORMAT_SHOW_YEAR; +import static android.text.format.DateUtils.FORMAT_UTC; + +import static org.junit.Assert.assertEquals; + +import android.icu.util.Calendar; +import android.icu.util.TimeZone; +import android.icu.util.ULocale; +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.function.BiFunction; + +@Presubmit +@SmallTest +@RunWith(AndroidJUnit4.class) +public class DateIntervalFormatTest { + private static final long MINUTE = 60 * 1000; + private static final long HOUR = 60 * MINUTE; + private static final long DAY = 24 * HOUR; + private static final long MONTH = 31 * DAY; + private static final long YEAR = 12 * MONTH; + + // These are the old CTS tests for DateIntervalFormat.formatDateRange. + @Test + public void test_formatDateInterval() throws Exception { + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); + + Calendar c = Calendar.getInstance(tz, ULocale.US); + c.set(Calendar.MONTH, Calendar.JANUARY); + c.set(Calendar.DAY_OF_MONTH, 19); + c.set(Calendar.HOUR_OF_DAY, 3); + c.set(Calendar.MINUTE, 30); + c.set(Calendar.SECOND, 15); + c.set(Calendar.MILLISECOND, 0); + long timeWithCurrentYear = c.getTimeInMillis(); + + c.set(Calendar.YEAR, 2009); + long fixedTime = c.getTimeInMillis(); + + c.set(Calendar.MINUTE, 0); + c.set(Calendar.SECOND, 0); + long onTheHour = c.getTimeInMillis(); + + long noonDuration = (8 * 60 + 30) * 60 * 1000 - 15 * 1000; + long midnightDuration = (3 * 60 + 30) * 60 * 1000 + 15 * 1000; + + ULocale de_DE = new ULocale("de", "DE"); + ULocale en_US = new ULocale("en", "US"); + ULocale es_ES = new ULocale("es", "ES"); + ULocale es_US = new ULocale("es", "US"); + + assertEquals("Monday", + formatDateRange(en_US, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_WEEKDAY)); + assertEquals("January 19", + formatDateRange(en_US, tz, timeWithCurrentYear, timeWithCurrentYear + HOUR, + FORMAT_SHOW_DATE)); + assertEquals("3:30 AM", formatDateRange(en_US, tz, fixedTime, fixedTime, FORMAT_SHOW_TIME)); + assertEquals("January 19, 2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + HOUR, FORMAT_SHOW_YEAR)); + assertEquals("January 19", + formatDateRange(en_US, tz, fixedTime, fixedTime + HOUR, FORMAT_NO_YEAR)); + assertEquals("January", + formatDateRange(en_US, tz, timeWithCurrentYear, timeWithCurrentYear + HOUR, + FORMAT_NO_MONTH_DAY)); + assertEquals("3:30 AM", + formatDateRange(en_US, tz, fixedTime, fixedTime, FORMAT_12HOUR | FORMAT_SHOW_TIME)); + assertEquals("03:30", + formatDateRange(en_US, tz, fixedTime, fixedTime, FORMAT_24HOUR | FORMAT_SHOW_TIME)); + assertEquals("3:30 AM", formatDateRange(en_US, tz, fixedTime, fixedTime, + FORMAT_12HOUR /*| FORMAT_CAP_AMPM*/ | FORMAT_SHOW_TIME)); + assertEquals("12:00 PM", + formatDateRange(en_US, tz, fixedTime + noonDuration, fixedTime + noonDuration, + FORMAT_12HOUR | FORMAT_SHOW_TIME)); + assertEquals("12:00 PM", + formatDateRange(en_US, tz, fixedTime + noonDuration, fixedTime + noonDuration, + FORMAT_12HOUR | FORMAT_SHOW_TIME /*| FORMAT_CAP_NOON*/)); + assertEquals("12:00 PM", + formatDateRange(en_US, tz, fixedTime + noonDuration, fixedTime + noonDuration, + FORMAT_12HOUR /*| FORMAT_NO_NOON*/ | FORMAT_SHOW_TIME)); + assertEquals("12:00 AM", formatDateRange(en_US, tz, fixedTime - midnightDuration, + fixedTime - midnightDuration, + FORMAT_12HOUR | FORMAT_SHOW_TIME /*| FORMAT_NO_MIDNIGHT*/)); + assertEquals("3:30 AM", + formatDateRange(en_US, tz, fixedTime, fixedTime, FORMAT_SHOW_TIME | FORMAT_UTC)); + assertEquals("3 AM", formatDateRange(en_US, tz, onTheHour, onTheHour, + FORMAT_SHOW_TIME | FORMAT_ABBREV_TIME)); + assertEquals("Mon", formatDateRange(en_US, tz, fixedTime, fixedTime + HOUR, + FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_WEEKDAY)); + assertEquals("Jan 19", + formatDateRange(en_US, tz, timeWithCurrentYear, timeWithCurrentYear + HOUR, + FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH)); + assertEquals("Jan 19", + formatDateRange(en_US, tz, timeWithCurrentYear, timeWithCurrentYear + HOUR, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + + assertEquals("1/19/2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * HOUR, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("1/19/2009 – 1/22/2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("1/19/2009 – 4/22/2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("1/19/2009 – 2/9/2012", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + + assertEquals("19.1.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + HOUR, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("19.–22.01.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("19.01. – 22.04.2009", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("19.01.2009 – 09.02.2012", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + + assertEquals("19/1/2009", formatDateRange(es_US, tz, fixedTime, fixedTime + HOUR, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("19/1/2009–22/1/2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("19/1/2009–22/4/2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("19/1/2009–9/2/2012", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + + assertEquals("19/1/2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + HOUR, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("19/1/2009–22/1/2009", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("19/1/2009–22/4/2009", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + assertEquals("19/1/2009–9/2/2012", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE)); + + // These are some random other test cases I came up with. + + assertEquals("January 19 – 22, 2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, 0)); + assertEquals("Jan 19 – 22, 2009", formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("Mon, Jan 19 – Thu, Jan 22, 2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); + assertEquals("Monday, January 19 – Thursday, January 22, 2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY)); + + assertEquals("January 19 – April 22, 2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, 0)); + assertEquals("Jan 19 – Apr 22, 2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("Mon, Jan 19 – Wed, Apr 22, 2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); + assertEquals("January – April 2009", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY)); + + assertEquals("Jan 19, 2009 – Feb 9, 2012", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("Jan 2009 – Feb 2012", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL)); + assertEquals("January 19, 2009 – February 9, 2012", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, 0)); + assertEquals("Monday, January 19, 2009 – Thursday, February 9, 2012", + formatDateRange(en_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY)); + + // The same tests but for de_DE. + + assertEquals("19.–22. Januar 2009", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, 0)); + assertEquals("19.–22. Jan. 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("Mo., 19. – Do., 22. Jan. 2009", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); + assertEquals("Montag, 19. – Donnerstag, 22. Januar 2009", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY)); + + assertEquals("19. Januar – 22. April 2009", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, 0)); + assertEquals("19. Jan. – 22. Apr. 2009", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("Mo., 19. Jan. – Mi., 22. Apr. 2009", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); + assertEquals("Januar–April 2009", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY)); + + assertEquals("19. Jan. 2009 – 9. Feb. 2012", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("Jan. 2009 – Feb. 2012", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL)); + assertEquals("19. Januar 2009 – 9. Februar 2012", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, 0)); + assertEquals("Montag, 19. Januar 2009 – Donnerstag, 9. Februar 2012", + formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY)); + + // The same tests but for es_US. + + assertEquals("19–22 de enero de 2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, 0)); + assertEquals("19–22 de ene. de 2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("lun., 19 de ene. – jue., 22 de ene. de 2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); + assertEquals("lunes, 19 de enero–jueves, 22 de enero de 2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY)); + + assertEquals("19 de enero–22 de abril de 2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, 0)); + assertEquals("19 de ene. – 22 de abr. 2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("lun., 19 de ene. – mié., 22 de abr. de 2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); + assertEquals("enero–abril de 2009", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY)); + + assertEquals("19 de ene. de 2009 – 9 de feb. de 2012", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("ene. de 2009 – feb. de 2012", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL)); + assertEquals("19 de enero de 2009–9 de febrero de 2012", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, 0)); + assertEquals("lunes, 19 de enero de 2009–jueves, 9 de febrero de 2012", + formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY)); + + // The same tests but for es_ES. + + assertEquals("19–22 de enero de 2009", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, 0)); + assertEquals("19–22 ene. 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("lun., 19 ene. – jue., 22 ene. 2009", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, + FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); + assertEquals("lunes, 19 de enero–jueves, 22 de enero de 2009", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY)); + + assertEquals("19 de enero–22 de abril de 2009", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, 0)); + assertEquals("19 ene. – 22 abr. 2009", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("lun., 19 ene. – mié., 22 abr. 2009", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, + FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL)); + assertEquals("enero–abril de 2009", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY)); + + assertEquals("19 ene. 2009 – 9 feb. 2012", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL)); + assertEquals("ene. 2009 – feb. 2012", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, + FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL)); + assertEquals("19 de enero de 2009–9 de febrero de 2012", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, 0)); + assertEquals("lunes, 19 de enero de 2009–jueves, 9 de febrero de 2012", + formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY)); + } + + // http://b/8862241 - we should be able to format dates past 2038. + // See also http://code.google.com/p/android/issues/detail?id=13050. + @Test + public void test8862241() throws Exception { + ULocale l = ULocale.US; + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); + Calendar c = Calendar.getInstance(tz, l); + c.clear(); + c.set(2042, Calendar.JANUARY, 19, 3, 30); + long jan_19_2042 = c.getTimeInMillis(); + c.set(2046, Calendar.OCTOBER, 4, 3, 30); + long oct_4_2046 = c.getTimeInMillis(); + int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL; + assertEquals("Jan 19, 2042 – Oct 4, 2046", + formatDateRange(l, tz, jan_19_2042, oct_4_2046, flags)); + } + + // http://b/10089890 - we should take the given time zone into account. + @Test + public void test10089890() throws Exception { + ULocale l = ULocale.US; + TimeZone utc = TimeZone.getTimeZone("UTC"); + TimeZone pacific = TimeZone.getTimeZone("America/Los_Angeles"); + int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL | FORMAT_SHOW_TIME | FORMAT_24HOUR; + + // The Unix epoch is UTC, so 0 is 1970-01-01T00:00Z... + assertEquals("Jan 1, 1970, 00:00 – Jan 2, 1970, 00:00", + formatDateRange(l, utc, 0, DAY + 1, flags)); + // But MTV is hours behind, so 0 was still the afternoon of the previous day... + assertEquals("Dec 31, 1969, 16:00 – Jan 1, 1970, 16:00", + formatDateRange(l, pacific, 0, DAY, flags)); + } + + // http://b/10318326 - we can drop the minutes in a 12-hour time if they're zero, + // but not if we're using the 24-hour clock. That is: "4 PM" is reasonable, "16" is not. + @Test + public void test10318326() throws Exception { + long midnight = 0; + long teaTime = 16 * HOUR; + + int time12 = FORMAT_12HOUR | FORMAT_SHOW_TIME; + int time24 = FORMAT_24HOUR | FORMAT_SHOW_TIME; + int abbr12 = time12 | FORMAT_ABBREV_ALL; + int abbr24 = time24 | FORMAT_ABBREV_ALL; + + ULocale l = ULocale.US; + TimeZone utc = TimeZone.getTimeZone("UTC"); + + // Full length on-the-hour times. + assertEquals("00:00", formatDateRange(l, utc, midnight, midnight, time24)); + assertEquals("12:00 AM", formatDateRange(l, utc, midnight, midnight, time12)); + assertEquals("16:00", formatDateRange(l, utc, teaTime, teaTime, time24)); + assertEquals("4:00 PM", formatDateRange(l, utc, teaTime, teaTime, time12)); + + // Abbreviated on-the-hour times. + assertEquals("00:00", formatDateRange(l, utc, midnight, midnight, abbr24)); + assertEquals("12 AM", formatDateRange(l, utc, midnight, midnight, abbr12)); + assertEquals("16:00", formatDateRange(l, utc, teaTime, teaTime, abbr24)); + assertEquals("4 PM", formatDateRange(l, utc, teaTime, teaTime, abbr12)); + + // Abbreviated on-the-hour ranges. + assertEquals("00:00 – 16:00", formatDateRange(l, utc, midnight, teaTime, abbr24)); + assertEquals("12 AM – 4 PM", formatDateRange(l, utc, midnight, teaTime, abbr12)); + + // Abbreviated mixed ranges. + assertEquals("00:00 – 16:01", formatDateRange(l, utc, midnight, teaTime + MINUTE, abbr24)); + assertEquals("12:00 AM – 4:01 PM", + formatDateRange(l, utc, midnight, teaTime + MINUTE, abbr12)); + } + + // http://b/10560853 - when the time is not displayed, an end time 0 ms into the next day is + // considered to belong to the previous day. + @Test + public void test10560853_when_time_not_displayed() throws Exception { + ULocale l = ULocale.US; + TimeZone utc = TimeZone.getTimeZone("UTC"); + + long midnight = 0; + long midnightNext = 1 * DAY; + + int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY; + + // An all-day event runs until 0 milliseconds into the next day, but is formatted as if it's + // just the first day. + assertEquals("Thursday, January 1, 1970", + formatDateRange(l, utc, midnight, midnightNext, flags)); + + // Run one millisecond over, though, and you're into the next day. + long nextMorning = 1 * DAY + 1; + assertEquals("Thursday, January 1 – Friday, January 2, 1970", + formatDateRange(l, utc, midnight, nextMorning, flags)); + + // But the same reasoning applies for that day. + long nextMidnight = 2 * DAY; + assertEquals("Thursday, January 1 – Friday, January 2, 1970", + formatDateRange(l, utc, midnight, nextMidnight, flags)); + } + + // http://b/10560853 - when the start and end times are otherwise on the same day, + // an end time 0 ms into the next day is considered to belong to the previous day. + @Test + public void test10560853_for_single_day_events() throws Exception { + ULocale l = ULocale.US; + TimeZone utc = TimeZone.getTimeZone("UTC"); + + int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE; + + assertEquals("January 1, 1970, 22:00 – 00:00", + formatDateRange(l, utc, 22 * HOUR, 24 * HOUR, flags)); + assertEquals("January 1, 1970, 22:00 – January 2, 1970, 00:30", + formatDateRange(l, utc, 22 * HOUR, 24 * HOUR + 30 * MINUTE, flags)); + } + + // The fix for http://b/10560853 didn't work except for the day around the epoch, which was + // all the unit test checked! + @Test + public void test_single_day_events_later_than_epoch() throws Exception { + ULocale l = ULocale.US; + TimeZone utc = TimeZone.getTimeZone("UTC"); + + int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE; + + Calendar c = Calendar.getInstance(utc, l); + c.clear(); + c.set(1980, Calendar.JANUARY, 1, 0, 0); + long jan_1_1980 = c.getTimeInMillis(); + assertEquals("January 1, 1980, 22:00 – 00:00", + formatDateRange(l, utc, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR, flags)); + assertEquals("January 1, 1980, 22:00 – January 2, 1980, 00:30", + formatDateRange(l, utc, jan_1_1980 + 22 * HOUR, + jan_1_1980 + 24 * HOUR + 30 * MINUTE, flags)); + } + + // The fix for http://b/10560853 didn't work except for UTC, which was + // all the unit test checked! + @Test + public void test_single_day_events_not_in_UTC() throws Exception { + ULocale l = ULocale.US; + TimeZone pacific = TimeZone.getTimeZone("America/Los_Angeles"); + + int flags = FORMAT_SHOW_TIME | FORMAT_24HOUR | FORMAT_SHOW_DATE; + + Calendar c = Calendar.getInstance(pacific, l); + c.clear(); + c.set(1980, Calendar.JANUARY, 1, 0, 0); + long jan_1_1980 = c.getTimeInMillis(); + assertEquals("January 1, 1980, 22:00 – 00:00", + formatDateRange(l, pacific, jan_1_1980 + 22 * HOUR, jan_1_1980 + 24 * HOUR, flags)); + + c.set(1980, Calendar.JULY, 1, 0, 0); + long jul_1_1980 = c.getTimeInMillis(); + assertEquals("July 1, 1980, 22:00 – 00:00", + formatDateRange(l, pacific, jul_1_1980 + 22 * HOUR, jul_1_1980 + 24 * HOUR, flags)); + } + + // http://b/10209343 - even if the caller didn't explicitly ask us to include the year, + // we should do so for years other than the current year. + @Test + public void test10209343_when_not_this_year() { + ULocale l = ULocale.US; + TimeZone utc = TimeZone.getTimeZone("UTC"); + + int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_TIME | FORMAT_24HOUR; + + assertEquals("Thursday, January 1, 1970, 00:00", formatDateRange(l, utc, 0L, 0L, flags)); + + long t1833 = ((long) Integer.MIN_VALUE + Integer.MIN_VALUE) * 1000L; + assertEquals("Sunday, November 24, 1833, 17:31", + formatDateRange(l, utc, t1833, t1833, flags)); + + long t1901 = Integer.MIN_VALUE * 1000L; + assertEquals("Friday, December 13, 1901, 20:45", + formatDateRange(l, utc, t1901, t1901, flags)); + + long t2038 = Integer.MAX_VALUE * 1000L; + assertEquals("Tuesday, January 19, 2038, 03:14", + formatDateRange(l, utc, t2038, t2038, flags)); + + long t2106 = (2L + Integer.MAX_VALUE + Integer.MAX_VALUE) * 1000L; + assertEquals("Sunday, February 7, 2106, 06:28", + formatDateRange(l, utc, t2106, t2106, flags)); + } + + // http://b/10209343 - for the current year, we should honor the FORMAT_SHOW_YEAR flags. + @Test + public void test10209343_when_this_year() { + // Construct a date in the current year (whenever the test happens to be run). + ULocale l = ULocale.US; + TimeZone utc = TimeZone.getTimeZone("UTC"); + Calendar c = Calendar.getInstance(utc, l); + c.set(Calendar.MONTH, Calendar.FEBRUARY); + c.set(Calendar.DAY_OF_MONTH, 10); + c.set(Calendar.HOUR_OF_DAY, 0); + long thisYear = c.getTimeInMillis(); + + // You don't get the year if it's this year... + assertEquals("February 10", formatDateRange(l, utc, thisYear, thisYear, FORMAT_SHOW_DATE)); + + // ...unless you explicitly ask for it. + assertEquals(String.format("February 10, %d", c.get(Calendar.YEAR)), + formatDateRange(l, utc, thisYear, thisYear, FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR)); + + // ...or it's not actually this year... + Calendar c2 = (Calendar) c.clone(); + c2.set(Calendar.YEAR, 1980); + long oldYear = c2.getTimeInMillis(); + assertEquals("February 10, 1980", + formatDateRange(l, utc, oldYear, oldYear, FORMAT_SHOW_DATE)); + + // (But you can disable that!) + assertEquals("February 10", + formatDateRange(l, utc, oldYear, oldYear, FORMAT_SHOW_DATE | FORMAT_NO_YEAR)); + + // ...or the start and end years aren't the same... + assertEquals(String.format("February 10, 1980 – February 10, %d", c.get(Calendar.YEAR)), + formatDateRange(l, utc, oldYear, thisYear, FORMAT_SHOW_DATE)); + + // (And you can't avoid that --- icu4c steps in and overrides you.) + assertEquals(String.format("February 10, 1980 – February 10, %d", c.get(Calendar.YEAR)), + formatDateRange(l, utc, oldYear, thisYear, FORMAT_SHOW_DATE | FORMAT_NO_YEAR)); + } + + // http://b/8467515 - yet another y2k38 bug report. + @Test + public void test8467515() throws Exception { + ULocale l = ULocale.US; + TimeZone utc = TimeZone.getTimeZone("UTC"); + int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_YEAR | FORMAT_ABBREV_MONTH + | FORMAT_ABBREV_WEEKDAY; + long t; + + Calendar calendar = Calendar.getInstance(utc, l); + calendar.clear(); + + calendar.set(2038, Calendar.JANUARY, 19, 12, 0, 0); + t = calendar.getTimeInMillis(); + assertEquals("Tue, Jan 19, 2038", formatDateRange(l, utc, t, t, flags)); + + calendar.set(1900, Calendar.JANUARY, 1, 0, 0, 0); + t = calendar.getTimeInMillis(); + assertEquals("Mon, Jan 1, 1900", formatDateRange(l, utc, t, t, flags)); + } + + // http://b/12004664 + @Test + public void test12004664() throws Exception { + TimeZone utc = TimeZone.getTimeZone("UTC"); + Calendar c = Calendar.getInstance(utc, ULocale.US); + c.clear(); + c.set(Calendar.YEAR, 1980); + c.set(Calendar.MONTH, Calendar.FEBRUARY); + c.set(Calendar.DAY_OF_MONTH, 10); + c.set(Calendar.HOUR_OF_DAY, 0); + long thisYear = c.getTimeInMillis(); + + int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_WEEKDAY | FORMAT_SHOW_YEAR; + assertEquals("Sunday, February 10, 1980", + formatDateRange(new ULocale("en", "US"), utc, thisYear, thisYear, flags)); + + // If we supported non-Gregorian calendars, this is what that we'd expect for these + // ULocales. + // This is really the correct behavior, but since java.util.Calendar currently only supports + // the Gregorian calendar, we want to deliberately force icu4c to agree, otherwise we'd have + // a mix of calendars throughout an app's UI depending on whether Java or native code + // formatted + // the date. + // assertEquals("یکشنبه ۲۱ بهمن ۱۳۵۸ ه.ش.", formatDateRange(new ULocale("fa"), utc, + // thisYear, thisYear, flags)); + // assertEquals("AP ۱۳۵۸ سلواغه ۲۱, یکشنبه", formatDateRange(new ULocale("ps"), utc, + // thisYear, thisYear, flags)); + // assertEquals("วันอาทิตย์ 10 กุมภาพันธ์ 2523", formatDateRange(new ULocale("th"), utc, + // thisYear, thisYear, flags)); + + // For now, here are the localized Gregorian strings instead... + assertEquals("یکشنبه ۱۰ فوریهٔ ۱۹۸۰", + formatDateRange(new ULocale("fa"), utc, thisYear, thisYear, flags)); + assertEquals("يونۍ د ۱۹۸۰ د فبروري ۱۰", + formatDateRange(new ULocale("ps"), utc, thisYear, thisYear, flags)); + assertEquals("วันอาทิตย์ที่ 10 กุมภาพันธ์ ค.ศ. 1980", + formatDateRange(new ULocale("th"), utc, thisYear, thisYear, flags)); + } + + // http://b/13234532 + @Test + public void test13234532() throws Exception { + ULocale l = ULocale.US; + TimeZone utc = TimeZone.getTimeZone("UTC"); + + int flags = FORMAT_SHOW_TIME | FORMAT_ABBREV_ALL | FORMAT_12HOUR; + + assertEquals("10 – 11 AM", formatDateRange(l, utc, 10 * HOUR, 11 * HOUR, flags)); + assertEquals("11 AM – 1 PM", formatDateRange(l, utc, 11 * HOUR, 13 * HOUR, flags)); + assertEquals("2 – 3 PM", formatDateRange(l, utc, 14 * HOUR, 15 * HOUR, flags)); + } + + // http://b/20708022 + @Test + public void testEndOfDayOnLastDayOfMonth() throws Exception { + final ULocale locale = new ULocale("en"); + final TimeZone timeZone = TimeZone.getTimeZone("UTC"); + + assertEquals("11:00 PM – 12:00 AM", formatDateRange(locale, timeZone, + 1430434800000L, 1430438400000L, FORMAT_SHOW_TIME)); + } + + // http://b/68847519 + @Test + public void testEndAtMidnight_dateAndTime() { + BiFunction<Long, Long, String> fmt = (from, to) -> formatDateRange( + ENGLISH, GMT_ZONE, from, to, FORMAT_SHOW_DATE | FORMAT_SHOW_TIME | FORMAT_24HOUR); + // If we're showing times and the end-point is midnight the following day, we want the + // behaviour of suppressing the date for the end... + assertEquals("February 27, 2007, 04:00 – 00:00", fmt.apply(1172548800000L, 1172620800000L)); + // ...unless the start-point is also midnight, in which case we need dates to disambiguate. + assertEquals("February 27, 2007, 00:00 – February 28, 2007, 00:00", + fmt.apply(1172534400000L, 1172620800000L)); + // We want to show the date if the end-point is a millisecond after midnight the following + // day, or if it is exactly midnight the day after that. + assertEquals("February 27, 2007, 04:00 – February 28, 2007, 00:00", + fmt.apply(1172548800000L, 1172620800001L)); + assertEquals("February 27, 2007, 04:00 – March 1, 2007, 00:00", + fmt.apply(1172548800000L, 1172707200000L)); + // We want to show the date if the start-point is anything less than a minute after + // midnight, + // since that gets displayed as midnight... + assertEquals("February 27, 2007, 00:00 – February 28, 2007, 00:00", + fmt.apply(1172534459999L, 1172620800000L)); + // ...but not if it is exactly one minute after midnight. + assertEquals("February 27, 2007, 00:01 – 00:00", fmt.apply(1172534460000L, 1172620800000L)); + } + + // http://b/68847519 + @Test + public void testEndAtMidnight_dateOnly() { + BiFunction<Long, Long, String> fmt = (from, to) -> formatDateRange( + ENGLISH, GMT_ZONE, from, to, FORMAT_SHOW_DATE); + // If we're only showing dates and the end-point is midnight of any day, we want the + // behaviour of showing an end date one earlier. So if the end-point is March 2, 2007 00:00, + // show March 1, 2007 instead (whether the start-point is midnight or not). + assertEquals("February 27 – March 1, 2007", fmt.apply(1172534400000L, 1172793600000L)); + assertEquals("February 27 – March 1, 2007", fmt.apply(1172548800000L, 1172793600000L)); + // We want to show the true date if the end-point is a millisecond after midnight. + assertEquals("February 27 – March 2, 2007", fmt.apply(1172534400000L, 1172793600001L)); + + // 2006-02-27 00:00:00.000 GMT - 2007-03-02 00:00:00.000 GMT + assertEquals("February 27, 2006 – March 1, 2007", + fmt.apply(1140998400000L, 1172793600000L)); + + // Spans a leap year's Feb 29th. + assertEquals("February 27 – March 1, 2004", fmt.apply(1077840000000L, 1078185600000L)); + } +} diff --git a/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java b/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java new file mode 100644 index 000000000000..4b3b5735b4f3 --- /dev/null +++ b/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java @@ -0,0 +1,762 @@ +/* + * Copyright (C) 2015 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.text.format; + +import static android.text.format.DateUtils.FORMAT_ABBREV_ALL; +import static android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE; +import static android.text.format.DateUtils.FORMAT_NO_YEAR; +import static android.text.format.DateUtils.FORMAT_NUMERIC_DATE; +import static android.text.format.DateUtils.FORMAT_SHOW_YEAR; +import static android.text.format.RelativeDateTimeFormatter.DAY_IN_MILLIS; +import static android.text.format.RelativeDateTimeFormatter.HOUR_IN_MILLIS; +import static android.text.format.RelativeDateTimeFormatter.MINUTE_IN_MILLIS; +import static android.text.format.RelativeDateTimeFormatter.SECOND_IN_MILLIS; +import static android.text.format.RelativeDateTimeFormatter.WEEK_IN_MILLIS; +import static android.text.format.RelativeDateTimeFormatter.YEAR_IN_MILLIS; +import static android.text.format.RelativeDateTimeFormatter.getRelativeDateTimeString; +import static android.text.format.RelativeDateTimeFormatter.getRelativeTimeSpanString; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +@Presubmit +@SmallTest +@RunWith(AndroidJUnit4.class) +public class RelativeDateTimeFormatterTest { + + // Tests adopted from CTS tests for DateUtils.getRelativeTimeSpanString. + @Test + public void test_getRelativeTimeSpanStringCTS() throws Exception { + Locale en_US = new Locale("en", "US"); + TimeZone tz = TimeZone.getTimeZone("GMT"); + Calendar cal = Calendar.getInstance(tz, en_US); + // Feb 5, 2015 at 10:50 GMT + cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0); + final long baseTime = cal.getTimeInMillis(); + + assertEquals("0 minutes ago", + getRelativeTimeSpanString(en_US, tz, baseTime - SECOND_IN_MILLIS, baseTime, + MINUTE_IN_MILLIS, 0)); + assertEquals("In 0 minutes", + getRelativeTimeSpanString(en_US, tz, baseTime + SECOND_IN_MILLIS, baseTime, + MINUTE_IN_MILLIS, 0)); + + assertEquals("1 minute ago", + getRelativeTimeSpanString(en_US, tz, 0, MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 0)); + assertEquals("In 1 minute", + getRelativeTimeSpanString(en_US, tz, MINUTE_IN_MILLIS, 0, MINUTE_IN_MILLIS, 0)); + + assertEquals("42 minutes ago", + getRelativeTimeSpanString(en_US, tz, baseTime - 42 * MINUTE_IN_MILLIS, baseTime, + MINUTE_IN_MILLIS, 0)); + assertEquals("In 42 minutes", + getRelativeTimeSpanString(en_US, tz, baseTime + 42 * MINUTE_IN_MILLIS, baseTime, + MINUTE_IN_MILLIS, 0)); + + final long TWO_HOURS_IN_MS = 2 * HOUR_IN_MILLIS; + assertEquals("2 hours ago", + getRelativeTimeSpanString(en_US, tz, baseTime - TWO_HOURS_IN_MS, baseTime, + MINUTE_IN_MILLIS, FORMAT_NUMERIC_DATE)); + assertEquals("In 2 hours", + getRelativeTimeSpanString(en_US, tz, baseTime + TWO_HOURS_IN_MS, baseTime, + MINUTE_IN_MILLIS, FORMAT_NUMERIC_DATE)); + + assertEquals("In 42 min.", + getRelativeTimeSpanString(en_US, tz, baseTime + (42 * MINUTE_IN_MILLIS), baseTime, + MINUTE_IN_MILLIS, FORMAT_ABBREV_RELATIVE)); + + assertEquals("Tomorrow", + getRelativeTimeSpanString(en_US, tz, DAY_IN_MILLIS, 0, DAY_IN_MILLIS, 0)); + assertEquals("In 2 days", + getRelativeTimeSpanString(en_US, tz, 2 * DAY_IN_MILLIS, 0, DAY_IN_MILLIS, 0)); + assertEquals("Yesterday", + getRelativeTimeSpanString(en_US, tz, 0, DAY_IN_MILLIS, DAY_IN_MILLIS, 0)); + assertEquals("2 days ago", + getRelativeTimeSpanString(en_US, tz, 0, 2 * DAY_IN_MILLIS, DAY_IN_MILLIS, 0)); + + final long DAY_DURATION = 5 * 24 * 60 * 60 * 1000; + assertEquals("5 days ago", + getRelativeTimeSpanString(en_US, tz, baseTime - DAY_DURATION, baseTime, + DAY_IN_MILLIS, 0)); + } + + private void test_getRelativeTimeSpanString_helper(long delta, long minResolution, int flags, + String expectedInPast, + String expectedInFuture) throws Exception { + Locale en_US = new Locale("en", "US"); + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); + Calendar cal = Calendar.getInstance(tz, en_US); + // Feb 5, 2015 at 10:50 PST + cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0); + final long base = cal.getTimeInMillis(); + + assertEquals(expectedInPast, + getRelativeTimeSpanString(en_US, tz, base - delta, base, minResolution, flags)); + assertEquals(expectedInFuture, + getRelativeTimeSpanString(en_US, tz, base + delta, base, minResolution, flags)); + } + + private void test_getRelativeTimeSpanString_helper(long delta, long minResolution, + String expectedInPast, + String expectedInFuture) throws Exception { + test_getRelativeTimeSpanString_helper(delta, minResolution, 0, expectedInPast, + expectedInFuture); + } + + @Test + public void test_getRelativeTimeSpanString() throws Exception { + + test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, 0, "0 seconds ago", + "0 seconds ago"); + test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, 0, "1 minute ago", + "In 1 minute"); + test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, 0, "1 minute ago", + "In 1 minute"); + test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, 0, "5 days ago", "In 5 days"); + + test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, + "0 seconds ago", + "0 seconds ago"); + test_getRelativeTimeSpanString_helper(1 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, + "1 second ago", + "In 1 second"); + test_getRelativeTimeSpanString_helper(2 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, + "2 seconds ago", + "In 2 seconds"); + test_getRelativeTimeSpanString_helper(25 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, + "25 seconds ago", + "In 25 seconds"); + test_getRelativeTimeSpanString_helper(75 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, + "1 minute ago", + "In 1 minute"); + test_getRelativeTimeSpanString_helper(5000 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, + "1 hour ago", + "In 1 hour"); + + test_getRelativeTimeSpanString_helper(0 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, + "0 minutes ago", + "0 minutes ago"); + test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, + "1 minute ago", + "In 1 minute"); + test_getRelativeTimeSpanString_helper(2 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, + "2 minutes ago", + "In 2 minutes"); + test_getRelativeTimeSpanString_helper(25 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, + "25 minutes ago", + "In 25 minutes"); + test_getRelativeTimeSpanString_helper(75 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, "1 hour ago", + "In 1 hour"); + test_getRelativeTimeSpanString_helper(720 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, + "12 hours ago", + "In 12 hours"); + + test_getRelativeTimeSpanString_helper(0 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "0 hours ago", + "0 hours ago"); + test_getRelativeTimeSpanString_helper(1 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "1 hour ago", + "In 1 hour"); + test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "2 hours ago", + "In 2 hours"); + test_getRelativeTimeSpanString_helper(5 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "5 hours ago", + "In 5 hours"); + test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "20 hours ago", + "In 20 hours"); + + test_getRelativeTimeSpanString_helper(0 * DAY_IN_MILLIS, DAY_IN_MILLIS, "Today", "Today"); + test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday", + "Tomorrow"); + test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday", + "Tomorrow"); + test_getRelativeTimeSpanString_helper(2 * DAY_IN_MILLIS, DAY_IN_MILLIS, "2 days ago", + "In 2 days"); + test_getRelativeTimeSpanString_helper(25 * DAY_IN_MILLIS, DAY_IN_MILLIS, "January 11", + "March 2"); + + test_getRelativeTimeSpanString_helper(0 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "0 weeks ago", + "0 weeks ago"); + test_getRelativeTimeSpanString_helper(1 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "1 week ago", + "In 1 week"); + test_getRelativeTimeSpanString_helper(2 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "2 weeks ago", + "In 2 weeks"); + test_getRelativeTimeSpanString_helper(25 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "25 weeks ago", + "In 25 weeks"); + + // duration >= minResolution + test_getRelativeTimeSpanString_helper(30 * SECOND_IN_MILLIS, 0, "30 seconds ago", + "In 30 seconds"); + test_getRelativeTimeSpanString_helper(30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, + "30 minutes ago", "In 30 minutes"); + test_getRelativeTimeSpanString_helper(30 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, "Yesterday", + "Tomorrow"); + test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, "5 days ago", + "In 5 days"); + test_getRelativeTimeSpanString_helper(30 * WEEK_IN_MILLIS, MINUTE_IN_MILLIS, + "July 10, 2014", + "September 3"); + test_getRelativeTimeSpanString_helper(5 * 365 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, + "February 6, 2010", "February 4, 2020"); + + test_getRelativeTimeSpanString_helper(60 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, + "1 minute ago", + "In 1 minute"); + test_getRelativeTimeSpanString_helper(120 * SECOND_IN_MILLIS - 1, MINUTE_IN_MILLIS, + "1 minute ago", "In 1 minute"); + test_getRelativeTimeSpanString_helper(60 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, "1 hour ago", + "In 1 hour"); + test_getRelativeTimeSpanString_helper(120 * MINUTE_IN_MILLIS - 1, HOUR_IN_MILLIS, + "1 hour ago", + "In 1 hour"); + test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Today", "Today"); + test_getRelativeTimeSpanString_helper(12 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday", + "Today"); + test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday", + "Tomorrow"); + test_getRelativeTimeSpanString_helper(48 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "2 days ago", + "In 2 days"); + test_getRelativeTimeSpanString_helper(45 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "2 days ago", + "In 2 days"); + test_getRelativeTimeSpanString_helper(7 * DAY_IN_MILLIS, WEEK_IN_MILLIS, "1 week ago", + "In 1 week"); + test_getRelativeTimeSpanString_helper(14 * DAY_IN_MILLIS - 1, WEEK_IN_MILLIS, "1 week ago", + "In 1 week"); + + // duration < minResolution + test_getRelativeTimeSpanString_helper(59 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, + "0 minutes ago", + "In 0 minutes"); + test_getRelativeTimeSpanString_helper(59 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, "0 hours ago", + "In 0 hours"); + test_getRelativeTimeSpanString_helper(HOUR_IN_MILLIS - 1, HOUR_IN_MILLIS, "0 hours ago", + "In 0 hours"); + test_getRelativeTimeSpanString_helper(DAY_IN_MILLIS - 1, DAY_IN_MILLIS, "Yesterday", + "Tomorrow"); + test_getRelativeTimeSpanString_helper(20 * SECOND_IN_MILLIS, WEEK_IN_MILLIS, "0 weeks ago", + "In 0 weeks"); + test_getRelativeTimeSpanString_helper(WEEK_IN_MILLIS - 1, WEEK_IN_MILLIS, "0 weeks ago", + "In 0 weeks"); + } + + @Test + public void test_getRelativeTimeSpanStringAbbrev() throws Exception { + int flags = FORMAT_ABBREV_RELATIVE; + + test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, 0, flags, "0 sec. ago", + "0 sec. ago"); + test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, 0, flags, "1 min. ago", + "In 1 min."); + test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, 0, flags, "5 days ago", + "In 5 days"); + + test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags, + "0 sec. ago", "0 sec. ago"); + test_getRelativeTimeSpanString_helper(1 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags, + "1 sec. ago", "In 1 sec."); + test_getRelativeTimeSpanString_helper(2 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags, + "2 sec. ago", "In 2 sec."); + test_getRelativeTimeSpanString_helper(25 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags, + "25 sec. ago", "In 25 sec."); + test_getRelativeTimeSpanString_helper(75 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags, + "1 min. ago", "In 1 min."); + test_getRelativeTimeSpanString_helper(5000 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags, + "1 hr. ago", "In 1 hr."); + + test_getRelativeTimeSpanString_helper(0 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "0 min. ago", "0 min. ago"); + test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "1 min. ago", "In 1 min."); + test_getRelativeTimeSpanString_helper(2 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "2 min. ago", "In 2 min."); + test_getRelativeTimeSpanString_helper(25 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "25 min. ago", "In 25 min."); + test_getRelativeTimeSpanString_helper(75 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "1 hr. ago", "In 1 hr."); + test_getRelativeTimeSpanString_helper(720 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "12 hr. ago", "In 12 hr."); + + test_getRelativeTimeSpanString_helper(0 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags, + "0 hr. ago", "0 hr. ago"); + test_getRelativeTimeSpanString_helper(1 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags, + "1 hr. ago", "In 1 hr."); + test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags, + "2 hr. ago", "In 2 hr."); + test_getRelativeTimeSpanString_helper(5 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags, + "5 hr. ago", "In 5 hr."); + test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags, + "20 hr. ago", "In 20 hr."); + + test_getRelativeTimeSpanString_helper(0 * DAY_IN_MILLIS, DAY_IN_MILLIS, flags, "Today", + "Today"); + test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags, + "Yesterday", "Tomorrow"); + test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags, + "Yesterday", "Tomorrow"); + test_getRelativeTimeSpanString_helper(2 * DAY_IN_MILLIS, DAY_IN_MILLIS, flags, + "2 days ago", "In 2 days"); + test_getRelativeTimeSpanString_helper(25 * DAY_IN_MILLIS, DAY_IN_MILLIS, flags, + "January 11", "March 2"); + + test_getRelativeTimeSpanString_helper(0 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags, + "0 wk. ago", "0 wk. ago"); + test_getRelativeTimeSpanString_helper(1 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags, + "1 wk. ago", "In 1 wk."); + test_getRelativeTimeSpanString_helper(2 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags, + "2 wk. ago", "In 2 wk."); + test_getRelativeTimeSpanString_helper(25 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags, + "25 wk. ago", "In 25 wk."); + + // duration >= minResolution + test_getRelativeTimeSpanString_helper(30 * SECOND_IN_MILLIS, 0, flags, "30 sec. ago", + "In 30 sec."); + test_getRelativeTimeSpanString_helper(30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "30 min. ago", "In 30 min."); + test_getRelativeTimeSpanString_helper(30 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "Yesterday", "Tomorrow"); + test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "5 days ago", "In 5 days"); + test_getRelativeTimeSpanString_helper(30 * WEEK_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "July 10, 2014", "September 3"); + test_getRelativeTimeSpanString_helper(5 * 365 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "February 6, 2010", "February 4, 2020"); + + test_getRelativeTimeSpanString_helper(60 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "1 min. ago", "In 1 min."); + test_getRelativeTimeSpanString_helper(120 * SECOND_IN_MILLIS - 1, MINUTE_IN_MILLIS, flags, + "1 min. ago", "In 1 min."); + test_getRelativeTimeSpanString_helper(60 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, flags, + "1 hr. ago", "In 1 hr."); + test_getRelativeTimeSpanString_helper(120 * MINUTE_IN_MILLIS - 1, HOUR_IN_MILLIS, flags, + "1 hr. ago", "In 1 hr."); + test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags, "Today", + "Today"); + test_getRelativeTimeSpanString_helper(12 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags, + "Yesterday", "Today"); + test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags, + "Yesterday", "Tomorrow"); + test_getRelativeTimeSpanString_helper(48 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags, + "2 days ago", "In 2 days"); + test_getRelativeTimeSpanString_helper(45 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags, + "2 days ago", "In 2 days"); + test_getRelativeTimeSpanString_helper(7 * DAY_IN_MILLIS, WEEK_IN_MILLIS, flags, + "1 wk. ago", "In 1 wk."); + test_getRelativeTimeSpanString_helper(14 * DAY_IN_MILLIS - 1, WEEK_IN_MILLIS, flags, + "1 wk. ago", "In 1 wk."); + + // duration < minResolution + test_getRelativeTimeSpanString_helper(59 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, flags, + "0 min. ago", "In 0 min."); + test_getRelativeTimeSpanString_helper(59 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, flags, + "0 hr. ago", "In 0 hr."); + test_getRelativeTimeSpanString_helper(HOUR_IN_MILLIS - 1, HOUR_IN_MILLIS, flags, + "0 hr. ago", "In 0 hr."); + test_getRelativeTimeSpanString_helper(DAY_IN_MILLIS - 1, DAY_IN_MILLIS, flags, + "Yesterday", "Tomorrow"); + test_getRelativeTimeSpanString_helper(20 * SECOND_IN_MILLIS, WEEK_IN_MILLIS, flags, + "0 wk. ago", "In 0 wk."); + test_getRelativeTimeSpanString_helper(WEEK_IN_MILLIS - 1, WEEK_IN_MILLIS, flags, + "0 wk. ago", "In 0 wk."); + + } + + @Test + public void test_getRelativeTimeSpanStringGerman() throws Exception { + // Bug: 19744876 + // We need to specify the timezone and the time explicitly. Otherwise it + // may not always give a correct answer of "tomorrow" by using + // (now + DAY_IN_MILLIS). + Locale de_DE = new Locale("de", "DE"); + TimeZone tz = TimeZone.getTimeZone("Europe/Berlin"); + Calendar cal = Calendar.getInstance(tz, de_DE); + // Feb 5, 2015 at 10:50 CET + cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0); + final long now = cal.getTimeInMillis(); + + // 42 minutes ago + assertEquals("Vor 42 Minuten", getRelativeTimeSpanString(de_DE, tz, + now - 42 * MINUTE_IN_MILLIS, now, MINUTE_IN_MILLIS, 0)); + // In 42 minutes + assertEquals("In 42 Minuten", getRelativeTimeSpanString(de_DE, tz, + now + 42 * MINUTE_IN_MILLIS, now, MINUTE_IN_MILLIS, 0)); + // Yesterday + assertEquals("Gestern", getRelativeTimeSpanString(de_DE, tz, + now - DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0)); + // The day before yesterday + assertEquals("Vorgestern", getRelativeTimeSpanString(de_DE, tz, + now - 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0)); + // Tomorrow + assertEquals("Morgen", getRelativeTimeSpanString(de_DE, tz, + now + DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0)); + // The day after tomorrow + assertEquals("Übermorgen", getRelativeTimeSpanString(de_DE, tz, + now + 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0)); + } + + @Test + public void test_getRelativeTimeSpanStringFrench() throws Exception { + Locale fr_FR = new Locale("fr", "FR"); + TimeZone tz = TimeZone.getTimeZone("Europe/Paris"); + Calendar cal = Calendar.getInstance(tz, fr_FR); + // Feb 5, 2015 at 10:50 CET + cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0); + final long now = cal.getTimeInMillis(); + + // 42 minutes ago + assertEquals("Il y a 42 minutes", getRelativeTimeSpanString(fr_FR, tz, + now - (42 * MINUTE_IN_MILLIS), now, MINUTE_IN_MILLIS, 0)); + // In 42 minutes + assertEquals("Dans 42 minutes", getRelativeTimeSpanString(fr_FR, tz, + now + (42 * MINUTE_IN_MILLIS), now, MINUTE_IN_MILLIS, 0)); + // Yesterday + assertEquals("Hier", getRelativeTimeSpanString(fr_FR, tz, + now - DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0)); + // The day before yesterday + assertEquals("Avant-hier", getRelativeTimeSpanString(fr_FR, tz, + now - 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0)); + // Tomorrow + assertEquals("Demain", getRelativeTimeSpanString(fr_FR, tz, + now + DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0)); + // The day after tomorrow + assertEquals("Après-demain", getRelativeTimeSpanString(fr_FR, tz, + now + 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0)); + } + + // Tests adopted from CTS tests for DateUtils.getRelativeDateTimeString. + @Test + public void test_getRelativeDateTimeStringCTS() throws Exception { + Locale en_US = Locale.getDefault(); + TimeZone tz = TimeZone.getDefault(); + final long baseTime = System.currentTimeMillis(); + + final long DAY_DURATION = 5 * 24 * 60 * 60 * 1000; + assertNotNull(getRelativeDateTimeString(en_US, tz, baseTime - DAY_DURATION, baseTime, + MINUTE_IN_MILLIS, DAY_IN_MILLIS, + FORMAT_NUMERIC_DATE)); + } + + @Test + public void test_getRelativeDateTimeString() throws Exception { + Locale en_US = new Locale("en", "US"); + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); + Calendar cal = Calendar.getInstance(tz, en_US); + // Feb 5, 2015 at 10:50 PST + cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0); + final long base = cal.getTimeInMillis(); + + assertEquals("5 seconds ago, 10:49 AM", + getRelativeDateTimeString(en_US, tz, base - 5 * SECOND_IN_MILLIS, base, 0, + MINUTE_IN_MILLIS, 0)); + assertEquals("5 min. ago, 10:45 AM", + getRelativeDateTimeString(en_US, tz, base - 5 * MINUTE_IN_MILLIS, base, 0, + HOUR_IN_MILLIS, FORMAT_ABBREV_RELATIVE)); + assertEquals("0 hr. ago, 10:45 AM", + getRelativeDateTimeString(en_US, tz, base - 5 * MINUTE_IN_MILLIS, base, + HOUR_IN_MILLIS, DAY_IN_MILLIS, FORMAT_ABBREV_RELATIVE)); + assertEquals("5 hours ago, 5:50 AM", + getRelativeDateTimeString(en_US, tz, base - 5 * HOUR_IN_MILLIS, base, + HOUR_IN_MILLIS, DAY_IN_MILLIS, 0)); + assertEquals("Yesterday, 7:50 PM", + getRelativeDateTimeString(en_US, tz, base - 15 * HOUR_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE)); + assertEquals("5 days ago, 10:50 AM", + getRelativeDateTimeString(en_US, tz, base - 5 * DAY_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, 0)); + assertEquals("Jan 29, 10:50 AM", + getRelativeDateTimeString(en_US, tz, base - 7 * DAY_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, 0)); + assertEquals("11/27/2014, 10:50 AM", + getRelativeDateTimeString(en_US, tz, base - 10 * WEEK_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, 0)); + assertEquals("11/27/2014, 10:50 AM", + getRelativeDateTimeString(en_US, tz, base - 10 * WEEK_IN_MILLIS, base, 0, + YEAR_IN_MILLIS, 0)); + + // User-supplied flags should be ignored when formatting the date clause. + final int FORMAT_SHOW_WEEKDAY = 0x00002; + assertEquals("11/27/2014, 10:50 AM", + getRelativeDateTimeString(en_US, tz, base - 10 * WEEK_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, + FORMAT_ABBREV_ALL | FORMAT_SHOW_WEEKDAY)); + } + + @Test + public void test_getRelativeDateTimeStringDST() throws Exception { + Locale en_US = new Locale("en", "US"); + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); + Calendar cal = Calendar.getInstance(tz, en_US); + + // DST starts on Mar 9, 2014 at 2:00 AM. + // So 5 hours before 3:15 AM should be formatted as 'Yesterday, 9:15 PM'. + cal.set(2014, Calendar.MARCH, 9, 3, 15, 0); + long base = cal.getTimeInMillis(); + assertEquals("Yesterday, 9:15 PM", + getRelativeDateTimeString(en_US, tz, base - 5 * HOUR_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, 0)); + + // 1 hour after 2:00 AM should be formatted as 'In 1 hour, 4:00 AM'. + cal.set(2014, Calendar.MARCH, 9, 2, 0, 0); + base = cal.getTimeInMillis(); + assertEquals("In 1 hour, 4:00 AM", + getRelativeDateTimeString(en_US, tz, base + 1 * HOUR_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, 0)); + + // DST ends on Nov 2, 2014 at 2:00 AM. Clocks are turned backward 1 hour to + // 1:00 AM. 8 hours before 5:20 AM should be 'Yesterday, 10:20 PM'. + cal.set(2014, Calendar.NOVEMBER, 2, 5, 20, 0); + base = cal.getTimeInMillis(); + assertEquals("Yesterday, 10:20 PM", + getRelativeDateTimeString(en_US, tz, base - 8 * HOUR_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, 0)); + + cal.set(2014, Calendar.NOVEMBER, 2, 0, 45, 0); + base = cal.getTimeInMillis(); + // 45 minutes after 0:45 AM should be 'In 45 minutes, 1:30 AM'. + assertEquals("In 45 minutes, 1:30 AM", + getRelativeDateTimeString(en_US, tz, base + 45 * MINUTE_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, 0)); + // 45 minutes later, it should be 'In 45 minutes, 1:15 AM'. + assertEquals("In 45 minutes, 1:15 AM", + getRelativeDateTimeString(en_US, tz, base + 90 * MINUTE_IN_MILLIS, + base + 45 * MINUTE_IN_MILLIS, 0, WEEK_IN_MILLIS, 0)); + // Another 45 minutes later, it should be 'In 45 minutes, 2:00 AM'. + assertEquals("In 45 minutes, 2:00 AM", + getRelativeDateTimeString(en_US, tz, base + 135 * MINUTE_IN_MILLIS, + base + 90 * MINUTE_IN_MILLIS, 0, WEEK_IN_MILLIS, 0)); + } + + @Test + public void test_getRelativeDateTimeStringItalian() throws Exception { + Locale it_IT = new Locale("it", "IT"); + TimeZone tz = TimeZone.getTimeZone("Europe/Rome"); + Calendar cal = Calendar.getInstance(tz, it_IT); + // 05 febbraio 2015 20:15 + cal.set(2015, Calendar.FEBRUARY, 5, 20, 15, 0); + final long base = cal.getTimeInMillis(); + + assertEquals("5 secondi fa, 20:14", + getRelativeDateTimeString(it_IT, tz, base - 5 * SECOND_IN_MILLIS, base, 0, + MINUTE_IN_MILLIS, 0)); + assertEquals("5 min fa, 20:10", + getRelativeDateTimeString(it_IT, tz, base - 5 * MINUTE_IN_MILLIS, base, 0, + HOUR_IN_MILLIS, FORMAT_ABBREV_RELATIVE)); + assertEquals("0 h fa, 20:10", + getRelativeDateTimeString(it_IT, tz, base - 5 * MINUTE_IN_MILLIS, base, + HOUR_IN_MILLIS, DAY_IN_MILLIS, FORMAT_ABBREV_RELATIVE)); + assertEquals("Ieri, 22:15", + getRelativeDateTimeString(it_IT, tz, base - 22 * HOUR_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE)); + assertEquals("5 giorni fa, 20:15", + getRelativeDateTimeString(it_IT, tz, base - 5 * DAY_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, 0)); + assertEquals("27/11/2014, 20:15", + getRelativeDateTimeString(it_IT, tz, base - 10 * WEEK_IN_MILLIS, base, 0, + WEEK_IN_MILLIS, 0)); + } + + // http://b/5252772: detect the actual date difference + @Test + public void test5252772() throws Exception { + Locale en_US = new Locale("en", "US"); + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); + + // Now is Sep 2, 2011, 10:23 AM PDT. + Calendar nowCalendar = Calendar.getInstance(tz, en_US); + nowCalendar.set(2011, Calendar.SEPTEMBER, 2, 10, 23, 0); + final long now = nowCalendar.getTimeInMillis(); + + // Sep 1, 2011, 10:24 AM + Calendar yesterdayCalendar1 = Calendar.getInstance(tz, en_US); + yesterdayCalendar1.set(2011, Calendar.SEPTEMBER, 1, 10, 24, 0); + long yesterday1 = yesterdayCalendar1.getTimeInMillis(); + assertEquals("Yesterday, 10:24 AM", + getRelativeDateTimeString(en_US, tz, yesterday1, now, MINUTE_IN_MILLIS, + WEEK_IN_MILLIS, 0)); + + // Sep 1, 2011, 10:22 AM + Calendar yesterdayCalendar2 = Calendar.getInstance(tz, en_US); + yesterdayCalendar2.set(2011, Calendar.SEPTEMBER, 1, 10, 22, 0); + long yesterday2 = yesterdayCalendar2.getTimeInMillis(); + assertEquals("Yesterday, 10:22 AM", + getRelativeDateTimeString(en_US, tz, yesterday2, now, MINUTE_IN_MILLIS, + WEEK_IN_MILLIS, 0)); + + // Aug 31, 2011, 10:24 AM + Calendar twoDaysAgoCalendar1 = Calendar.getInstance(tz, en_US); + twoDaysAgoCalendar1.set(2011, Calendar.AUGUST, 31, 10, 24, 0); + long twoDaysAgo1 = twoDaysAgoCalendar1.getTimeInMillis(); + assertEquals("2 days ago, 10:24 AM", + getRelativeDateTimeString(en_US, tz, twoDaysAgo1, now, MINUTE_IN_MILLIS, + WEEK_IN_MILLIS, 0)); + + // Aug 31, 2011, 10:22 AM + Calendar twoDaysAgoCalendar2 = Calendar.getInstance(tz, en_US); + twoDaysAgoCalendar2.set(2011, Calendar.AUGUST, 31, 10, 22, 0); + long twoDaysAgo2 = twoDaysAgoCalendar2.getTimeInMillis(); + assertEquals("2 days ago, 10:22 AM", + getRelativeDateTimeString(en_US, tz, twoDaysAgo2, now, MINUTE_IN_MILLIS, + WEEK_IN_MILLIS, 0)); + + // Sep 3, 2011, 10:22 AM + Calendar tomorrowCalendar1 = Calendar.getInstance(tz, en_US); + tomorrowCalendar1.set(2011, Calendar.SEPTEMBER, 3, 10, 22, 0); + long tomorrow1 = tomorrowCalendar1.getTimeInMillis(); + assertEquals("Tomorrow, 10:22 AM", + getRelativeDateTimeString(en_US, tz, tomorrow1, now, MINUTE_IN_MILLIS, + WEEK_IN_MILLIS, 0)); + + // Sep 3, 2011, 10:24 AM + Calendar tomorrowCalendar2 = Calendar.getInstance(tz, en_US); + tomorrowCalendar2.set(2011, Calendar.SEPTEMBER, 3, 10, 24, 0); + long tomorrow2 = tomorrowCalendar2.getTimeInMillis(); + assertEquals("Tomorrow, 10:24 AM", + getRelativeDateTimeString(en_US, tz, tomorrow2, now, MINUTE_IN_MILLIS, + WEEK_IN_MILLIS, 0)); + + // Sep 4, 2011, 10:22 AM + Calendar twoDaysLaterCalendar1 = Calendar.getInstance(tz, en_US); + twoDaysLaterCalendar1.set(2011, Calendar.SEPTEMBER, 4, 10, 22, 0); + long twoDaysLater1 = twoDaysLaterCalendar1.getTimeInMillis(); + assertEquals("In 2 days, 10:22 AM", + getRelativeDateTimeString(en_US, tz, twoDaysLater1, now, MINUTE_IN_MILLIS, + WEEK_IN_MILLIS, 0)); + + // Sep 4, 2011, 10:24 AM + Calendar twoDaysLaterCalendar2 = Calendar.getInstance(tz, en_US); + twoDaysLaterCalendar2.set(2011, Calendar.SEPTEMBER, 4, 10, 24, 0); + long twoDaysLater2 = twoDaysLaterCalendar2.getTimeInMillis(); + assertEquals("In 2 days, 10:24 AM", + getRelativeDateTimeString(en_US, tz, twoDaysLater2, now, MINUTE_IN_MILLIS, + WEEK_IN_MILLIS, 0)); + } + + // b/19822016: show / hide the year based on the dates in the arguments. + @Test + public void test_bug19822016() throws Exception { + Locale en_US = new Locale("en", "US"); + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); + Calendar cal = Calendar.getInstance(tz, en_US); + // Feb 5, 2012 at 10:50 PST + cal.set(2012, Calendar.FEBRUARY, 5, 10, 50, 0); + long base = cal.getTimeInMillis(); + + assertEquals("Feb 5, 5:50 AM", getRelativeDateTimeString(en_US, tz, + base - 5 * HOUR_IN_MILLIS, base, 0, MINUTE_IN_MILLIS, 0)); + assertEquals("Jan 29, 10:50 AM", getRelativeDateTimeString(en_US, tz, + base - 7 * DAY_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0)); + assertEquals("11/27/2011, 10:50 AM", getRelativeDateTimeString(en_US, tz, + base - 10 * WEEK_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0)); + + assertEquals("January 6", getRelativeTimeSpanString(en_US, tz, + base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0)); + assertEquals("January 6", getRelativeTimeSpanString(en_US, tz, + base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR)); + assertEquals("January 6, 2012", getRelativeTimeSpanString(en_US, tz, + base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR)); + assertEquals("December 7, 2011", getRelativeTimeSpanString(en_US, tz, + base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0)); + assertEquals("December 7, 2011", getRelativeTimeSpanString(en_US, tz, + base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR)); + assertEquals("December 7", getRelativeTimeSpanString(en_US, tz, + base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR)); + + // Feb 5, 2018 at 10:50 PST + cal.set(2018, Calendar.FEBRUARY, 5, 10, 50, 0); + base = cal.getTimeInMillis(); + assertEquals("Feb 5, 5:50 AM", getRelativeDateTimeString(en_US, tz, + base - 5 * HOUR_IN_MILLIS, base, 0, MINUTE_IN_MILLIS, 0)); + assertEquals("Jan 29, 10:50 AM", getRelativeDateTimeString(en_US, tz, + base - 7 * DAY_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0)); + assertEquals("11/27/2017, 10:50 AM", getRelativeDateTimeString(en_US, tz, + base - 10 * WEEK_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0)); + + assertEquals("January 6", getRelativeTimeSpanString(en_US, tz, + base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0)); + assertEquals("January 6", getRelativeTimeSpanString(en_US, tz, + base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR)); + assertEquals("January 6, 2018", getRelativeTimeSpanString(en_US, tz, + base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR)); + assertEquals("December 7, 2017", getRelativeTimeSpanString(en_US, tz, + base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0)); + assertEquals("December 7, 2017", getRelativeTimeSpanString(en_US, tz, + base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR)); + assertEquals("December 7", getRelativeTimeSpanString(en_US, tz, + base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR)); + } + + // Check for missing ICU data. http://b/25821045 + @Test + public void test_bug25821045() { + final TimeZone tz = TimeZone.getDefault(); + final long now = System.currentTimeMillis(); + final long time = now + 1000; + final int minResolution = 1000 * 60; + final int transitionResolution = minResolution; + final int flags = FORMAT_ABBREV_RELATIVE; + // Exercise all available locales, forcing the ICU implementation to pre-cache the data. + // This + // highlights data issues. It can take a while. + for (Locale locale : Locale.getAvailableLocales()) { + // In (e.g.) ICU56 an exception is thrown on the first use for a locale if required + // data for + // the "other" plural is missing. It doesn't matter what is actually formatted. + try { + RelativeDateTimeFormatter.getRelativeDateTimeString( + locale, tz, time, now, minResolution, transitionResolution, flags); + } catch (IllegalStateException e) { + fail("Failed to format for " + locale); + } + } + } + + // Check for ICU data lookup fallback failure. http://b/25883157 + @Test + public void test_bug25883157() { + final Locale locale = new Locale("en", "GB"); + final TimeZone tz = TimeZone.getTimeZone("GMT"); + + final Calendar cal = Calendar.getInstance(tz, locale); + cal.set(2015, Calendar.JUNE, 19, 12, 0, 0); + + final long base = cal.getTimeInMillis(); + final long time = base + 2 * WEEK_IN_MILLIS; + + assertEquals("In 2 wk", getRelativeTimeSpanString( + locale, tz, time, base, WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE)); + } + + // http://b/63745717 + @Test + public void test_combineDateAndTime_apostrophe() { + final Locale locale = new Locale("fr"); + android.icu.text.RelativeDateTimeFormatter icuFormatter = + android.icu.text.RelativeDateTimeFormatter.getInstance(locale); + assertEquals("D à T", icuFormatter.combineDateAndTime("D", "T")); + // Ensure single quote ' and curly braces {} are not interpreted in input values. + assertEquals("D'x' à T{0}", icuFormatter.combineDateAndTime("D'x'", "T{0}")); + } +} diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java index 257b388917e4..bda21c61375e 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java @@ -179,6 +179,21 @@ public class KernelCpuUidBpfMapReaderTest { testOpenAndReadData(changedData); } + @Test + public void testRemoveUidsInRange_firstAndLastAbsent() { + final SparseArray<long[]> data = getTestSparseArray(200, 50); + data.delete(0); + data.delete(5); + mReader.setData(data); + testOpenAndReadData(data); + SparseArray<long[]> changedData = new SparseArray<>(); + for (int i = 6; i < 200; i++) { + changedData.put(i, data.get(i)); + } + mReader.removeUidsInRange(0, 5); + testOpenAndReadData(changedData); + } + private void testOpenAndReadData(SparseArray<long[]> expectedData) { try (BpfMapIterator iter = mReader.open()) { long[] actual; diff --git a/core/tests/hdmitests/Android.bp b/core/tests/hdmitests/Android.bp new file mode 100644 index 000000000000..2194d4b030ce --- /dev/null +++ b/core/tests/hdmitests/Android.bp @@ -0,0 +1,27 @@ +// 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. + +android_test { + name: "HdmiCecTests", + // Include all test java files + srcs: ["src/**/*.java"], + static_libs: [ + "androidx.test.rules", + "frameworks-base-testutils", + "truth-prebuilt", + ], + libs: ["android.test.runner"], + platform_apis: true, + certificate: "platform", +} diff --git a/core/tests/hdmitests/Android.mk b/core/tests/hdmitests/Android.mk deleted file mode 100644 index f155feba0588..000000000000 --- a/core/tests/hdmitests/Android.mk +++ /dev/null @@ -1,31 +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. - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -# Include all test java files -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules frameworks-base-testutils truth-prebuilt - -LOCAL_JAVA_LIBRARIES := android.test.runner -LOCAL_PACKAGE_NAME := HdmiCecTests -LOCAL_PRIVATE_PLATFORM_APIS := true - -LOCAL_CERTIFICATE := platform - -include $(BUILD_PACKAGE) diff --git a/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.bp b/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.bp index 6db0ba5f7387..9e6c17f0247a 100644 --- a/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.bp +++ b/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.bp @@ -26,6 +26,7 @@ cc_test_library { // All of the source files that we will compile. srcs: ["native.cpp"], + header_libs: ["jni_headers"], shared_libs: ["liblog"], cflags: [ diff --git a/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.bp b/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.bp index 582f2a7abfb4..91da6e44a8be 100644 --- a/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.bp +++ b/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.bp @@ -25,6 +25,7 @@ cc_test_library { // All of the source files that we will compile. srcs: ["native.cpp"], + header_libs: ["jni_headers"], shared_libs: ["liblog"], cflags: [ diff --git a/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.bp b/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.bp index 3e043afee7ec..662755dd35b0 100644 --- a/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.bp +++ b/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.bp @@ -27,6 +27,7 @@ cc_test_library { // All of the source files that we will compile. srcs: ["native.cpp"], + header_libs: ["jni_headers"], shared_libs: ["liblog"], cflags: [ diff --git a/core/tests/packagemanagertests/Android.bp b/core/tests/packagemanagertests/Android.bp new file mode 100644 index 000000000000..6f39af8bd468 --- /dev/null +++ b/core/tests/packagemanagertests/Android.bp @@ -0,0 +1,14 @@ +android_test { + name: "FrameworksCorePackageManagerTests", + // We only want this apk build for tests. + // Include all test java files. + srcs: ["src/**/*.java"], + static_libs: [ + "androidx.test.rules", + "frameworks-base-testutils", + "mockito-target-minus-junit4", + ], + libs: ["android.test.runner"], + platform_apis: true, + certificate: "platform", +} diff --git a/core/tests/packagemanagertests/Android.mk b/core/tests/packagemanagertests/Android.mk deleted file mode 100644 index 8c00d14ce856..000000000000 --- a/core/tests/packagemanagertests/Android.mk +++ /dev/null @@ -1,22 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -# We only want this apk build for tests. -LOCAL_MODULE_TAGS := tests - -# Include all test java files. -LOCAL_SRC_FILES := \ - $(call all-java-files-under, src) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx.test.rules \ - frameworks-base-testutils \ - mockito-target-minus-junit4 - -LOCAL_JAVA_LIBRARIES := android.test.runner -LOCAL_PACKAGE_NAME := FrameworksCorePackageManagerTests -LOCAL_PRIVATE_PLATFORM_APIS := true - -LOCAL_CERTIFICATE := platform - -include $(BUILD_PACKAGE) diff --git a/core/tests/privacytests/Android.bp b/core/tests/privacytests/Android.bp new file mode 100644 index 000000000000..7f5699287796 --- /dev/null +++ b/core/tests/privacytests/Android.bp @@ -0,0 +1,14 @@ +android_test { + name: "FrameworksPrivacyLibraryTests", + srcs: ["src/**/*.java"], + static_libs: [ + "junit", + "rappor-tests", + "androidx.test.rules", + "truth-prebuilt", + ], + libs: ["android.test.runner"], + platform_apis: true, + certificate: "platform", + test_suites: ["device-tests"], +} diff --git a/core/tests/privacytests/Android.mk b/core/tests/privacytests/Android.mk deleted file mode 100644 index 7765977c03e8..000000000000 --- a/core/tests/privacytests/Android.mk +++ /dev/null @@ -1,20 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -# We only want this apk build for tests. -LOCAL_MODULE_TAGS := tests - -# Include all test java files. -LOCAL_SRC_FILES := \ - $(call all-java-files-under, src) - -LOCAL_STATIC_JAVA_LIBRARIES := junit rappor-tests androidx.test.rules truth-prebuilt - -LOCAL_JAVA_LIBRARIES := android.test.runner -LOCAL_PACKAGE_NAME := FrameworksPrivacyLibraryTests -LOCAL_PRIVATE_PLATFORM_APIS := true - -LOCAL_CERTIFICATE := platform -LOCAL_COMPATIBILITY_SUITE := device-tests - -include $(BUILD_PACKAGE) diff --git a/core/tests/utiltests/Android.bp b/core/tests/utiltests/Android.bp index f13885e22b22..a9b9c41d4719 100644 --- a/core/tests/utiltests/Android.bp +++ b/core/tests/utiltests/Android.bp @@ -8,7 +8,10 @@ android_test { // We only want this apk build for tests. // Include all test java files. - srcs: ["src/**/*.java"] + ["src/android/util/IRemoteMemoryIntArray.aidl"], + srcs: [ + "src/**/*.java", + "src/android/util/IRemoteMemoryIntArray.aidl", + ], jni_libs: [ "libmemoryintarraytest", diff --git a/core/tests/utiltests/jni/Android.bp b/core/tests/utiltests/jni/Android.bp index b0b09c27e325..6b75471a358a 100644 --- a/core/tests/utiltests/jni/Android.bp +++ b/core/tests/utiltests/jni/Android.bp @@ -14,6 +14,7 @@ cc_library_shared {
name: "libmemoryintarraytest",
+ header_libs: ["jni_headers"],
shared_libs: [
"libcutils",
],
@@ -23,4 +24,4 @@ cc_library_shared { "android_util_MemoryIntArrayTest.cpp",
],
cflags: ["-Werror"],
-}
\ No newline at end of file +}
diff --git a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java index 76aa93f7e8be..edf473eac1b1 100644 --- a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java @@ -16,27 +16,25 @@ package com.android.internal.util; -import java.util.Collection; -import java.util.Iterator; - import android.os.Debug; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.os.test.TestLooper; - -import android.test.suitebuilder.annotation.Suppress; -import com.android.internal.util.State; -import com.android.internal.util.StateMachine; -import com.android.internal.util.StateMachine.LogRec; - import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; +import com.android.internal.util.StateMachine.LogRec; + import junit.framework.TestCase; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Collection; +import java.util.Iterator; + /** * Test for StateMachine. */ @@ -2013,4 +2011,12 @@ public class StateMachineTest extends TestCase { private static void tloge(String s) { Log.e(TAG, s); } + + public void testDumpDoesNotThrowNpeAfterQuit() { + final Hsm1 sm = Hsm1.makeHsm1(); + sm.quitNow(); + final StringWriter stringWriter = new StringWriter(); + final PrintWriter printWriter = new PrintWriter(stringWriter); + sm.dump(null, printWriter, new String[0]); + } } diff --git a/core/xsd/vts/Android.bp b/core/xsd/vts/Android.bp index ca655f18149c..4b43b4136076 100644 --- a/core/xsd/vts/Android.bp +++ b/core/xsd/vts/Android.bp @@ -40,3 +40,7 @@ cc_test { ], test_config: "vts_permission_validate_test.xml", } + +vts_config { + name: "VtsValidatePermission", +} diff --git a/data/fonts/Android.bp b/data/fonts/Android.bp new file mode 100644 index 000000000000..3a3bea43ab86 --- /dev/null +++ b/data/fonts/Android.bp @@ -0,0 +1,38 @@ +// Copyright (C) 2011 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. + +prebuilt_font { + name: "DroidSansMono.ttf", + src: "DroidSansMono.ttf", + required: [ + // Roboto-Regular.ttf provides DroidSans.ttf as a symlink to itself + "Roboto-Regular.ttf", + // Roboto-Bold.ttf provides DroidSans-Bold.ttf as a symlink to itself + "Roboto-Bold.ttf", + ], +} + +prebuilt_font { + name: "AndroidClock.ttf", + src: "AndroidClock.ttf", +} + +///////////////////////////////// +// Copies the font configuration file into system/etc for the product as fonts.xml. +// Additional fonts should be installed to /product/fonts/ alongside a corresponding +// fonts_customiztion.xml in /product/etc/ +prebuilt_etc { + name: "fonts.xml", + src: "fonts.xml", +} diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk index 4226e0882538..a322b829932b 100644 --- a/data/fonts/Android.mk +++ b/data/fonts/Android.mk @@ -12,87 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# We have to use BUILD_PREBUILT instead of PRODUCT_COPY_FIES, -# because MINIMAL_FONT_FOOTPRINT is only available in Android.mks. - LOCAL_PATH := $(call my-dir) -########################################## -# create symlink for given font -# $(1): new font $(2): link target -# should be used with eval: $(eval $(call ...)) -define create-font-symlink -$(PRODUCT_OUT)/system/fonts/$(1) : $(PRODUCT_OUT)/system/fonts/$(2) - @echo "Symlink: $$@ -> $$<" - @mkdir -p $$(dir $$@) - @rm -rf $$@ - $(hide) ln -sf $$(notdir $$<) $$@ -# this magic makes LOCAL_REQUIRED_MODULES work -ALL_MODULES.$(1).INSTALLED := \ - $(ALL_MODULES.$(1).INSTALLED) $(PRODUCT_OUT)/system/fonts/$(1) -endef - -########################################## -# The following fonts are just symlinks, for backward compatibility. -########################################## -$(eval $(call create-font-symlink,DroidSans.ttf,Roboto-Regular.ttf)) -$(eval $(call create-font-symlink,DroidSans-Bold.ttf,Roboto-Bold.ttf)) -$(eval $(call create-font-symlink,DroidSerif-Regular.ttf,NotoSerif-Regular.ttf)) -$(eval $(call create-font-symlink,DroidSerif-Bold.ttf,NotoSerif-Bold.ttf)) -$(eval $(call create-font-symlink,DroidSerif-Italic.ttf,NotoSerif-Italic.ttf)) -$(eval $(call create-font-symlink,DroidSerif-BoldItalic.ttf,NotoSerif-BoldItalic.ttf)) - -extra_font_files := \ - DroidSans.ttf \ - DroidSans-Bold.ttf - -################################ -# Use DroidSansMono to hang extra_font_files on -include $(CLEAR_VARS) -LOCAL_MODULE := DroidSansMono.ttf -LOCAL_SRC_FILES := $(LOCAL_MODULE) -LOCAL_MODULE_CLASS := ETC -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts -LOCAL_REQUIRED_MODULES := $(extra_font_files) -include $(BUILD_PREBUILT) -extra_font_files := - -################################ -# Build the rest of font files as prebuilt. - -# $(1): The source file name in LOCAL_PATH. -# It also serves as the module name and the dest file name. -define build-one-font-module -$(eval include $(CLEAR_VARS))\ -$(eval LOCAL_MODULE := $(1))\ -$(eval LOCAL_SRC_FILES := $(1))\ -$(eval LOCAL_MODULE_CLASS := ETC)\ -$(eval LOCAL_MODULE_TAGS := optional)\ -$(eval LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts)\ -$(eval include $(BUILD_PREBUILT)) -endef - -font_src_files := \ - AndroidClock.ttf - -$(foreach f, $(font_src_files), $(call build-one-font-module, $(f))) - -build-one-font-module := -font_src_files := - -################################ -# Copies the font configuration file into system/etc for the product as fonts.xml. -# Additional fonts should be installed to /product/fonts/ alongside a corresponding -# fonts_customiztion.xml in /product/etc/ -include $(CLEAR_VARS) - -LOCAL_MODULE := fonts.xml -LOCAL_MODULE_CLASS := ETC -LOCAL_PREBUILT_MODULE_FILE := frameworks/base/data/fonts/fonts.xml - -include $(BUILD_PREBUILT) - # Run sanity tests on fonts on checkbuild checkbuild: fontchain_lint diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl index 51500439d3cf..d92dbb2125ab 100644 --- a/data/keyboards/Generic.kl +++ b/data/keyboards/Generic.kl @@ -317,7 +317,7 @@ key 366 DVR # key 367 "KEY_MHP" # key 368 "KEY_LANGUAGE" # key 369 "KEY_TITLE" -# key 370 "KEY_SUBTITLE" +key 370 CAPTIONS # key 371 "KEY_ANGLE" # key 372 "KEY_ZOOM" # key 373 "KEY_MODE" @@ -352,7 +352,7 @@ key 397 CALENDAR key 402 CHANNEL_UP key 403 CHANNEL_DOWN # key 404 "KEY_FIRST" -# key 405 "KEY_LAST" +key 405 LAST_CHANNEL # key 406 "KEY_AB" # key 407 "KEY_NEXT" # key 408 "KEY_RESTART" diff --git a/core/xsd/vts/Android.mk b/data/keyboards/Vendor_0a5c_Product_8502.kl index a5754a494d94..6d4a163d9f0b 100644 --- a/core/xsd/vts/Android.mk +++ b/data/keyboards/Vendor_0a5c_Product_8502.kl @@ -1,5 +1,4 @@ -# -# Copyright (C) 2019 The Android Open Source Project +# 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. @@ -12,11 +11,27 @@ # 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. -# -LOCAL_PATH := $(call my-dir) +# SnakeByte iDroid:con -include $(CLEAR_VARS) +key 304 BUTTON_A +key 305 BUTTON_B +key 306 BUTTON_THUMBL +key 307 BUTTON_X +key 308 BUTTON_Y +key 309 BUTTON_THUMBR +key 310 BUTTON_L1 +key 311 BUTTON_R1 +key 312 BUTTON_L2 +key 313 BUTTON_R2 +key 314 BUTTON_SELECT +key 315 BUTTON_START -LOCAL_MODULE := VtsValidatePermission -include test/vts/tools/build/Android.host_config.mk +axis 0x00 X +axis 0x01 Y +axis 0x02 Z +axis 0x03 RX +axis 0x04 RY +axis 0x05 RZ +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/data/keyboards/Vendor_0f0d_Product_00c1.kl b/data/keyboards/Vendor_0f0d_Product_00c1.kl new file mode 100644 index 000000000000..c74512a3a4b0 --- /dev/null +++ b/data/keyboards/Vendor_0f0d_Product_00c1.kl @@ -0,0 +1,55 @@ +# 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. + +# Device name: HORI CO.,LTD. HORIPAD S +# HORIPAD for Nintendo Switch, USB game controller +# https://hori.co.uk/horipad-for-nintendo-switch/ + +# Button labeled as "Y" but should really produce keycode "X" +key 0x130 BUTTON_X +# Button labeled as "B" but should really produce keycode "A" +key 0x131 BUTTON_A +# Button labeled as "A" but should really produce keycode "B" +key 0x132 BUTTON_B +# Button labeled as "X" but should really product keycode "Y" +key 0x133 BUTTON_Y + +key 0x134 BUTTON_L1 +key 0x135 BUTTON_R1 +key 0x136 BUTTON_L2 +key 0x137 BUTTON_R2 + +# Minus +key 0x138 BUTTON_SELECT +# Plus +key 0x139 BUTTON_START + +# Analog stick buttons +key 0x13a BUTTON_THUMBL +key 0x13b BUTTON_THUMBR + +# Home +key 0x13c HOME +# Capture +key 0x13d BUTTON_MODE + +# Left analog stick +axis 0x00 X +axis 0x01 Y +# Right analog stick +axis 0x02 Z +axis 0x05 RZ +# D-pad +axis 0x10 HAT_X +axis 0x11 HAT_Y diff --git a/drm/jni/android_drm_DrmManagerClient.cpp b/drm/jni/android_drm_DrmManagerClient.cpp index 52ea8e3b161f..e2bb6a6f4d1a 100644 --- a/drm/jni/android_drm_DrmManagerClient.cpp +++ b/drm/jni/android_drm_DrmManagerClient.cpp @@ -19,7 +19,7 @@ #include <utils/Log.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <nativehelper/ScopedLocalRef.h> #include <android_runtime/AndroidRuntime.h> diff --git a/errorprone/Android.bp b/errorprone/Android.bp index 098f4bfa74ac..7d0557d19393 100644 --- a/errorprone/Android.bp +++ b/errorprone/Android.bp @@ -14,10 +14,13 @@ java_library_host { static_libs: [ "//external/error_prone:error_prone_core", - "//external/dagger2:dagger2-auto-service", + ], + + libs: [ + "//external/auto:auto_service_annotations", ], plugins: [ - "//external/dagger2:dagger2-auto-service", + "//external/auto:auto_service_plugin", ], } diff --git a/graphics/java/android/graphics/GraphicsStatsService.java b/graphics/java/android/graphics/GraphicsStatsService.java index 8dfd6ee92a9a..2d6848b618a1 100644 --- a/graphics/java/android/graphics/GraphicsStatsService.java +++ b/graphics/java/android/graphics/GraphicsStatsService.java @@ -16,7 +16,6 @@ package android.graphics; -import android.annotation.SystemApi; import android.app.AlarmManager; import android.app.AppOpsManager; import android.content.Context; @@ -100,7 +99,6 @@ public class GraphicsStatsService extends IGraphicsStats.Stub { private Handler mWriteOutHandler; private boolean mRotateIsScheduled = false; - @SystemApi public GraphicsStatsService(Context context) { mContext = context; mAppOps = context.getSystemService(AppOpsManager.class); diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java index c52fd48459cb..6ad8d2c0aca3 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -17,6 +17,7 @@ package android.security.keystore; import android.annotation.Nullable; +import android.os.Build; import android.security.Credentials; import android.security.KeyPairGeneratorSpec; import android.security.KeyStore; @@ -30,7 +31,6 @@ import com.android.org.bouncycastle.asn1.ASN1InputStream; import com.android.org.bouncycastle.asn1.ASN1Integer; import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier; import com.android.org.bouncycastle.asn1.DERBitString; -import com.android.org.bouncycastle.asn1.DERInteger; import com.android.org.bouncycastle.asn1.DERNull; import com.android.org.bouncycastle.asn1.DERSequence; import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; @@ -50,6 +50,7 @@ import libcore.util.EmptyArray; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -495,6 +496,20 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato if (challenge != null) { KeymasterArguments args = new KeymasterArguments(); args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_CHALLENGE, challenge); + + if (mSpec.isDevicePropertiesAttestationIncluded()) { + args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND, + Build.BRAND.getBytes(StandardCharsets.UTF_8)); + args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE, + Build.DEVICE.getBytes(StandardCharsets.UTF_8)); + args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT, + Build.PRODUCT.getBytes(StandardCharsets.UTF_8)); + args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MANUFACTURER, + Build.MANUFACTURER.getBytes(StandardCharsets.UTF_8)); + args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MODEL, + Build.MODEL.getBytes(StandardCharsets.UTF_8)); + } + return getAttestationChain(privateKeyAlias, keyPair, args); } @@ -604,8 +619,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato private Iterable<byte[]> getAttestationChain(String privateKeyAlias, KeyPair keyPair, KeymasterArguments args) throws ProviderException { - KeymasterCertificateChain outChain = new KeymasterCertificateChain(); - int errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain); + final KeymasterCertificateChain outChain = new KeymasterCertificateChain(); + final int errorCode; + if (mSpec.isDevicePropertiesAttestationIncluded() + && mSpec.getAttestationChallenge() == null) { + throw new ProviderException("An attestation challenge must be provided when requesting " + + "device properties attestation."); + } + errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain); if (errorCode != KeyStore.NO_ERROR) { throw new ProviderException("Failed to generate attestation certificate chain", KeyStore.getKeyStoreException(errorCode)); @@ -680,8 +701,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato sigAlgOid = X9ObjectIdentifiers.ecdsa_with_SHA256; sigAlgId = new AlgorithmIdentifier(sigAlgOid); ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new DERInteger(0)); - v.add(new DERInteger(0)); + v.add(new ASN1Integer(BigInteger.valueOf(0))); + v.add(new ASN1Integer(BigInteger.valueOf(0))); signature = new DERSequence().getEncoded(); break; case KeymasterDefs.KM_ALGORITHM_RSA: diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index a7d0cb84f848..688c4a7b5969 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -25,6 +25,7 @@ import android.app.KeyguardManager; import android.compat.annotation.UnsupportedAppUsage; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; +import android.os.Build; import android.security.GateKeeper; import android.security.KeyStore; import android.text.TextUtils; @@ -266,6 +267,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu private final @KeyProperties.AuthEnum int mUserAuthenticationType; private final boolean mUserPresenceRequired; private final byte[] mAttestationChallenge; + private final boolean mDevicePropertiesAttestationIncluded; private final boolean mUniqueIdIncluded; private final boolean mUserAuthenticationValidWhileOnBody; private final boolean mInvalidatedByBiometricEnrollment; @@ -305,6 +307,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu @KeyProperties.AuthEnum int userAuthenticationType, boolean userPresenceRequired, byte[] attestationChallenge, + boolean devicePropertiesAttestationIncluded, boolean uniqueIdIncluded, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment, @@ -356,6 +359,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; mUserAuthenticationType = userAuthenticationType; mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge); + mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded; mUniqueIdIncluded = uniqueIdIncluded; mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment; @@ -667,6 +671,21 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu } /** + * Returns {@code true} if attestation for the base device properties ({@link Build#BRAND}, + * {@link Build#DEVICE}, {@link Build#MANUFACTURER}, {@link Build#MODEL}, {@link Build#PRODUCT}) + * was requested to be added in the attestation certificate for the generated key. + * + * {@link javax.crypto.KeyGenerator#generateKey()} will throw + * {@link java.security.ProviderException} if device properties attestation fails or is not + * supported. + * + * @see Builder#setDevicePropertiesAttestationIncluded(boolean) + */ + public boolean isDevicePropertiesAttestationIncluded() { + return mDevicePropertiesAttestationIncluded; + } + + /** * @hide This is a system-only API * * Returns {@code true} if the attestation certificate will contain a unique ID field. @@ -769,6 +788,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu KeyProperties.AUTH_BIOMETRIC_STRONG; private boolean mUserPresenceRequired = false; private byte[] mAttestationChallenge = null; + private boolean mDevicePropertiesAttestationIncluded = false; private boolean mUniqueIdIncluded = false; private boolean mUserAuthenticationValidWhileOnBody; private boolean mInvalidatedByBiometricEnrollment = true; @@ -834,6 +854,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserAuthenticationType = sourceSpec.getUserAuthenticationType(); mUserPresenceRequired = sourceSpec.isUserPresenceRequired(); mAttestationChallenge = sourceSpec.getAttestationChallenge(); + mDevicePropertiesAttestationIncluded = + sourceSpec.isDevicePropertiesAttestationIncluded(); mUniqueIdIncluded = sourceSpec.isUniqueIdIncluded(); mUserAuthenticationValidWhileOnBody = sourceSpec.isUserAuthenticationValidWhileOnBody(); mInvalidatedByBiometricEnrollment = sourceSpec.isInvalidatedByBiometricEnrollment(); @@ -1340,6 +1362,31 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu } /** + * Sets whether to include the base device properties in the attestation certificate. + * + * <p>If {@code attestationChallenge} is not {@code null}, the public key certificate for + * this key pair will contain an extension that describes the details of the key's + * configuration and authorizations, including the device properties values (brand, device, + * manufacturer, model, product). These should be the same as in ({@link Build#BRAND}, + * {@link Build#DEVICE}, {@link Build#MANUFACTURER}, {@link Build#MODEL}, + * {@link Build#PRODUCT}). The attestation certificate chain can + * be retrieved with {@link java.security.KeyStore#getCertificateChain(String)}. + * + * <p> If {@code attestationChallenge} is {@code null}, the public key certificate for + * this key pair will not contain the extension with the requested attested values. + * + * <p> {@link javax.crypto.KeyGenerator#generateKey()} will throw + * {@link java.security.ProviderException} if device properties attestation fails or is not + * supported. + */ + @NonNull + public Builder setDevicePropertiesAttestationIncluded( + boolean devicePropertiesAttestationIncluded) { + mDevicePropertiesAttestationIncluded = devicePropertiesAttestationIncluded; + return this; + } + + /** * @hide Only system apps can use this method. * * Sets whether to include a temporary unique ID field in the attestation certificate. @@ -1463,6 +1510,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu mUserAuthenticationType, mUserPresenceRequired, mAttestationChallenge, + mDevicePropertiesAttestationIncluded, mUniqueIdIncluded, mUserAuthenticationValidWhileOnBody, mInvalidatedByBiometricEnrollment, diff --git a/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java b/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java index 9c9773e5d145..69c15cca68bf 100644 --- a/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java @@ -100,6 +100,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { out.writeInt(mSpec.getUserAuthenticationType()); out.writeBoolean(mSpec.isUserPresenceRequired()); out.writeByteArray(mSpec.getAttestationChallenge()); + out.writeBoolean(mSpec.isDevicePropertiesAttestationIncluded()); out.writeBoolean(mSpec.isUniqueIdIncluded()); out.writeBoolean(mSpec.isUserAuthenticationValidWhileOnBody()); out.writeBoolean(mSpec.isInvalidatedByBiometricEnrollment()); @@ -157,6 +158,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { final int userAuthenticationTypes = in.readInt(); final boolean userPresenceRequired = in.readBoolean(); final byte[] attestationChallenge = in.createByteArray(); + final boolean devicePropertiesAttestationIncluded = in.readBoolean(); final boolean uniqueIdIncluded = in.readBoolean(); final boolean userAuthenticationValidWhileOnBody = in.readBoolean(); final boolean invalidatedByBiometricEnrollment = in.readBoolean(); @@ -190,6 +192,7 @@ public final class ParcelableKeyGenParameterSpec implements Parcelable { userAuthenticationTypes, userPresenceRequired, attestationChallenge, + devicePropertiesAttestationIncluded, uniqueIdIncluded, userAuthenticationValidWhileOnBody, invalidatedByBiometricEnrollment, 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/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/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp index 5be2105fe404..568e3b63d67f 100644 --- a/libs/androidfw/ZipUtils.cpp +++ b/libs/androidfw/ZipUtils.cpp @@ -40,7 +40,7 @@ class FileReader : public zip_archive::Reader { explicit FileReader(FILE* fp) : Reader(), mFp(fp), mCurrentOffset(0) { } - bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const { + bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const { // Data is usually requested sequentially, so this helps avoid pointless // fseeks every time we perform a read. There's an impedence mismatch // here because the original API was designed around pread and pwrite. @@ -63,7 +63,7 @@ class FileReader : public zip_archive::Reader { private: FILE* mFp; - mutable uint32_t mCurrentOffset; + mutable off64_t mCurrentOffset; }; class FdReader : public zip_archive::Reader { @@ -71,8 +71,8 @@ class FdReader : public zip_archive::Reader { explicit FdReader(int fd) : mFd(fd) { } - bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const { - return android::base::ReadFullyAtOffset(mFd, buf, len, static_cast<off_t>(offset)); + bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const { + return android::base::ReadFullyAtOffset(mFd, buf, len, offset); } private: @@ -86,8 +86,8 @@ class BufferReader : public zip_archive::Reader { mInputSize(inputSize) { } - bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const { - if (offset + len > mInputSize) { + bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const { + if (mInputSize < len || offset > mInputSize - len) { return false; } diff --git a/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp b/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp new file mode 100644 index 000000000000..77ef8dfb9725 --- /dev/null +++ b/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp @@ -0,0 +1,46 @@ +// 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. + +cc_fuzz { + name: "resourcefile_fuzzer", + srcs: [ + "resourcefile_fuzzer.cpp", + ], + host_supported: true, + corpus: ["corpus/*"], + static_libs: ["libgmock"], + target: { + android: { + shared_libs:[ + "libandroidfw", + "libbase", + "libcutils", + "libutils", + "libziparchive", + "libui", + ], + }, + host: { + static_libs: [ + "libandroidfw", + "libbase", + "libcutils", + "libutils", + "libziparchive", + "liblog", + "libz", + ], + }, + }, +} diff --git a/libs/androidfw/fuzz/resourcefile_fuzzer/corpus/resources.arsc b/libs/androidfw/fuzz/resourcefile_fuzzer/corpus/resources.arsc Binary files differnew file mode 100644 index 000000000000..3cf2ea733d28 --- /dev/null +++ b/libs/androidfw/fuzz/resourcefile_fuzzer/corpus/resources.arsc diff --git a/libs/androidfw/fuzz/resourcefile_fuzzer/resourcefile_fuzzer.cpp b/libs/androidfw/fuzz/resourcefile_fuzzer/resourcefile_fuzzer.cpp new file mode 100644 index 000000000000..96d44ab8e45c --- /dev/null +++ b/libs/androidfw/fuzz/resourcefile_fuzzer/resourcefile_fuzzer.cpp @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#include <string> +#include <memory> + +#include <androidfw/ApkAssets.h> +#include <androidfw/LoadedArsc.h> +#include <androidfw/StringPiece.h> + +#include <fuzzer/FuzzedDataProvider.h> + +using android::ApkAssets; +using android::LoadedArsc; +using android::StringPiece; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + + std::unique_ptr<const LoadedArsc> loaded_arsc = + LoadedArsc::Load(StringPiece(reinterpret_cast<const char*>(data), size)); + + return 0; +}
\ No newline at end of file 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/libs/androidfw/tests/CommonHelpers.h b/libs/androidfw/tests/CommonHelpers.h index 8af13f20fb0d..316a57aa1ae9 100644 --- a/libs/androidfw/tests/CommonHelpers.h +++ b/libs/androidfw/tests/CommonHelpers.h @@ -21,8 +21,6 @@ #include <string> #include "androidfw/ResourceTypes.h" -#include "utils/String16.h" -#include "utils/String8.h" namespace android { @@ -40,10 +38,6 @@ static inline bool operator==(const ResTable_config& a, const ResTable_config& b return a.compare(b) == 0; } -static inline ::std::ostream& operator<<(::std::ostream& out, const String8& str) { - return out << str.string(); -} - static inline ::std::ostream& operator<<(::std::ostream& out, const ResTable_config& c) { return out << c.toString(); } diff --git a/libs/hwui/PathParser.cpp b/libs/hwui/PathParser.cpp index 808921d344da..61d06c2697aa 100644 --- a/libs/hwui/PathParser.cpp +++ b/libs/hwui/PathParser.cpp @@ -16,8 +16,6 @@ #include "PathParser.h" -#include "jni.h" - #include <errno.h> #include <stdlib.h> #include <utils/Log.h> diff --git a/libs/hwui/PathParser.h b/libs/hwui/PathParser.h index f5bebce605fb..878bb7c0f137 100644 --- a/libs/hwui/PathParser.h +++ b/libs/hwui/PathParser.h @@ -22,7 +22,6 @@ #include <android/log.h> #include <cutils/compiler.h> -#include <jni.h> #include <string> diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp index d4e27d812500..e8e89d81bdb7 100644 --- a/libs/hwui/jni/BitmapFactory.cpp +++ b/libs/hwui/jni/BitmapFactory.cpp @@ -16,7 +16,7 @@ #include "Utils.h" #include <HardwareBitmapUploader.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <androidfw/Asset.h> #include <androidfw/ResourceTypes.h> #include <cutils/compiler.h> diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index 49c7fcd468e1..9815e85db880 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -27,7 +27,7 @@ #include <inttypes.h> #include <media/NdkImage.h> #include <media/NdkImageReader.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <pipeline/skia/ShaderCache.h> #include <private/EGL/cache.h> #include <renderthread/CanvasContext.h> diff --git a/libs/hwui/jni/android_nio_utils.cpp b/libs/hwui/jni/android_nio_utils.cpp index c2b09c1d15d7..0663821a5d89 100644 --- a/libs/hwui/jni/android_nio_utils.cpp +++ b/libs/hwui/jni/android_nio_utils.cpp @@ -16,7 +16,7 @@ #include "android_nio_utils.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> namespace android { diff --git a/libs/hwui/jni/android_nio_utils.h b/libs/hwui/jni/android_nio_utils.h index 4aaa0a78c276..4760d9ca8107 100644 --- a/libs/hwui/jni/android_nio_utils.h +++ b/libs/hwui/jni/android_nio_utils.h @@ -17,7 +17,9 @@ #ifndef _ANDROID_NIO_UTILS_H_ #define _ANDROID_NIO_UTILS_H_ -#include <nativehelper/JNIHelp.h> +#include <jni.h> + +#include <cstddef> namespace android { diff --git a/libs/hwui/jni/graphics_jni_helpers.h b/libs/hwui/jni/graphics_jni_helpers.h index b97cc6a10179..78db54acc9e5 100644 --- a/libs/hwui/jni/graphics_jni_helpers.h +++ b/libs/hwui/jni/graphics_jni_helpers.h @@ -18,7 +18,7 @@ #define GRAPHICS_JNI_HELPERS #include <log/log.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <nativehelper/scoped_local_ref.h> #include <nativehelper/scoped_utf_chars.h> #include <string> diff --git a/libs/input/Android.bp b/libs/input/Android.bp index 88d6033ed9fb..5252cd041199 100644 --- a/libs/input/Android.bp +++ b/libs/input/Android.bp @@ -17,6 +17,7 @@ cc_library_shared { srcs: [ "PointerController.cpp", "SpriteController.cpp", + "SpriteIcon.cpp", ], shared_libs: [ diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp index 3b494e9129db..5e480a66c355 100644 --- a/libs/input/PointerController.cpp +++ b/libs/input/PointerController.cpp @@ -24,30 +24,9 @@ #include <log/log.h> -namespace android { - -// --- WeakLooperCallback --- - -class WeakLooperCallback: public LooperCallback { -protected: - virtual ~WeakLooperCallback() { } - -public: - explicit WeakLooperCallback(const wp<LooperCallback>& callback) : - mCallback(callback) { - } +#include <memory> - virtual int handleEvent(int fd, int events, void* data) { - sp<LooperCallback> callback = mCallback.promote(); - if (callback != NULL) { - return callback->handleEvent(fd, events, data); - } - return 0; // the client is gone, remove the callback - } - -private: - wp<LooperCallback> mCallback; -}; +namespace android { // --- PointerController --- @@ -64,29 +43,50 @@ static const nsecs_t POINTER_FADE_DURATION = 500 * 1000000LL; // 500 ms // The number of events to be read at once for DisplayEventReceiver. static const int EVENT_BUFFER_SIZE = 100; -// --- PointerController --- - -PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy, - const sp<Looper>& looper, const sp<SpriteController>& spriteController) : - mPolicy(policy), mLooper(looper), mSpriteController(spriteController) { - mHandler = new WeakMessageHandler(this); - mCallback = new WeakLooperCallback(this); - - if (mDisplayEventReceiver.initCheck() == NO_ERROR) { - mLooper->addFd(mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK, - Looper::EVENT_INPUT, mCallback, nullptr); +std::shared_ptr<PointerController> PointerController::create( + const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper, + const sp<SpriteController>& spriteController) { + std::shared_ptr<PointerController> controller = std::shared_ptr<PointerController>( + new PointerController(policy, looper, spriteController)); + + /* + * Now we need to hook up the constructed PointerController object to its callbacks. + * + * This must be executed after the constructor but before any other methods on PointerController + * in order to ensure that the fully constructed object is visible on the Looper thread, since + * that may be a different thread than where the PointerController is initially constructed. + * + * Unfortunately, this cannot be done as part of the constructor since we need to hand out + * weak_ptr's which themselves cannot be constructed until there's at least one shared_ptr. + */ + + controller->mHandler->pointerController = controller; + controller->mCallback->pointerController = controller; + if (controller->mDisplayEventReceiver.initCheck() == NO_ERROR) { + controller->mLooper->addFd(controller->mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK, + Looper::EVENT_INPUT, controller->mCallback, nullptr); } else { ALOGE("Failed to initialize DisplayEventReceiver."); } + return controller; +} +PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy, + const sp<Looper>& looper, + const sp<SpriteController>& spriteController) + : mPolicy(policy), + mLooper(looper), + mSpriteController(spriteController), + mHandler(new MessageHandler()), + mCallback(new LooperCallback()) { AutoMutex _l(mLock); mLocked.animationPending = false; - mLocked.presentation = PRESENTATION_POINTER; + mLocked.presentation = Presentation::POINTER; mLocked.presentationChanged = false; - mLocked.inactivityTimeout = INACTIVITY_TIMEOUT_NORMAL; + mLocked.inactivityTimeout = InactivityTimeout::NORMAL; mLocked.pointerFadeDirection = 0; mLocked.pointerX = 0; @@ -221,7 +221,7 @@ void PointerController::fade(Transition transition) { removeInactivityTimeoutLocked(); // Start fading. - if (transition == TRANSITION_IMMEDIATE) { + if (transition == Transition::IMMEDIATE) { mLocked.pointerFadeDirection = 0; mLocked.pointerAlpha = 0.0f; updatePointerLocked(); @@ -238,7 +238,7 @@ void PointerController::unfade(Transition transition) { resetInactivityTimeoutLocked(); // Start unfading. - if (transition == TRANSITION_IMMEDIATE) { + if (transition == Transition::IMMEDIATE) { mLocked.pointerFadeDirection = 0; mLocked.pointerAlpha = 1.0f; updatePointerLocked(); @@ -262,7 +262,7 @@ void PointerController::setPresentation(Presentation presentation) { return; } - if (presentation == PRESENTATION_POINTER) { + if (presentation == Presentation::POINTER) { if (mLocked.additionalMouseResources.empty()) { mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources, &mLocked.animationResources, @@ -480,24 +480,35 @@ void PointerController::setCustomPointerIcon(const SpriteIcon& icon) { updatePointerLocked(); } -void PointerController::handleMessage(const Message& message) { +void PointerController::MessageHandler::handleMessage(const Message& message) { + std::shared_ptr<PointerController> controller = pointerController.lock(); + + if (controller == nullptr) { + ALOGE("PointerController instance was released before processing message: what=%d", + message.what); + return; + } switch (message.what) { case MSG_INACTIVITY_TIMEOUT: - doInactivityTimeout(); + controller->doInactivityTimeout(); break; } } -int PointerController::handleEvent(int /* fd */, int events, void* /* data */) { +int PointerController::LooperCallback::handleEvent(int /* fd */, int events, void* /* data */) { + std::shared_ptr<PointerController> controller = pointerController.lock(); + if (controller == nullptr) { + ALOGW("PointerController instance was released with pending callbacks. events=0x%x", + events); + return 0; // Remove the callback, the PointerController is gone anyways + } if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) { - ALOGE("Display event receiver pipe was closed or an error occurred. " - "events=0x%x", events); + ALOGE("Display event receiver pipe was closed or an error occurred. events=0x%x", events); return 0; // remove the callback } if (!(events & Looper::EVENT_INPUT)) { - ALOGW("Received spurious callback for unhandled poll event. " - "events=0x%x", events); + ALOGW("Received spurious callback for unhandled poll event. events=0x%x", events); return 1; // keep the callback } @@ -505,7 +516,7 @@ int PointerController::handleEvent(int /* fd */, int events, void* /* data */) { ssize_t n; nsecs_t timestamp; DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE]; - while ((n = mDisplayEventReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) { + while ((n = controller->mDisplayEventReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) { for (size_t i = 0; i < static_cast<size_t>(n); ++i) { if (buf[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { timestamp = buf[i].header.timestamp; @@ -514,7 +525,7 @@ int PointerController::handleEvent(int /* fd */, int events, void* /* data */) { } } if (gotVsync) { - doAnimate(timestamp); + controller->doAnimate(timestamp); } return 1; // keep the callback } @@ -613,7 +624,7 @@ bool PointerController::doBitmapAnimationLocked(nsecs_t timestamp) { } void PointerController::doInactivityTimeout() { - fade(TRANSITION_GRADUAL); + fade(Transition::GRADUAL); } void PointerController::startAnimationLocked() { @@ -627,8 +638,9 @@ void PointerController::startAnimationLocked() { void PointerController::resetInactivityTimeoutLocked() { mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT); - nsecs_t timeout = mLocked.inactivityTimeout == INACTIVITY_TIMEOUT_SHORT - ? INACTIVITY_TIMEOUT_DELAY_TIME_SHORT : INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL; + nsecs_t timeout = mLocked.inactivityTimeout == InactivityTimeout::SHORT + ? INACTIVITY_TIMEOUT_DELAY_TIME_SHORT + : INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL; mLooper->sendMessageDelayed(timeout, mHandler, MSG_INACTIVITY_TIMEOUT); } @@ -655,7 +667,7 @@ void PointerController::updatePointerLocked() REQUIRES(mLock) { } if (mLocked.pointerIconChanged || mLocked.presentationChanged) { - if (mLocked.presentation == PRESENTATION_POINTER) { + if (mLocked.presentation == Presentation::POINTER) { if (mLocked.requestedPointerType == mPolicy->getDefaultPointerIconId()) { mLocked.pointerSprite->setIcon(mLocked.pointerIcon); } else { @@ -731,7 +743,7 @@ PointerController::Spot* PointerController::removeFirstFadingSpotLocked(std::vec return spot; } } - return NULL; + return nullptr; } void PointerController::releaseSpotLocked(Spot* spot) { @@ -772,7 +784,7 @@ void PointerController::loadResourcesLocked() REQUIRES(mLock) { mLocked.additionalMouseResources.clear(); mLocked.animationResources.clear(); - if (mLocked.presentation == PRESENTATION_POINTER) { + if (mLocked.presentation == Presentation::POINTER) { mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources, &mLocked.animationResources, mLocked.viewport.displayId); } diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h index ebc622bae302..14c0679654c6 100644 --- a/libs/input/PointerController.h +++ b/libs/input/PointerController.h @@ -17,19 +17,20 @@ #ifndef _UI_POINTER_CONTROLLER_H #define _UI_POINTER_CONTROLLER_H -#include "SpriteController.h" - -#include <map> -#include <vector> - -#include <ui/DisplayInfo.h> +#include <PointerControllerInterface.h> +#include <gui/DisplayEventReceiver.h> #include <input/DisplayViewport.h> #include <input/Input.h> -#include <PointerControllerInterface.h> +#include <ui/DisplayInfo.h> #include <utils/BitSet.h> -#include <utils/RefBase.h> #include <utils/Looper.h> -#include <gui/DisplayEventReceiver.h> +#include <utils/RefBase.h> + +#include <map> +#include <memory> +#include <vector> + +#include "SpriteController.h" namespace android { @@ -70,25 +71,22 @@ public: virtual int32_t getCustomPointerIconId() = 0; }; - /* * Tracks pointer movements and draws the pointer sprite to a surface. * * Handles pointer acceleration and animation. */ -class PointerController : public PointerControllerInterface, public MessageHandler, - public LooperCallback { -protected: - virtual ~PointerController(); - +class PointerController : public PointerControllerInterface { public: - enum InactivityTimeout { - INACTIVITY_TIMEOUT_NORMAL = 0, - INACTIVITY_TIMEOUT_SHORT = 1, + static std::shared_ptr<PointerController> create( + const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper, + const sp<SpriteController>& spriteController); + enum class InactivityTimeout { + NORMAL = 0, + SHORT = 1, }; - PointerController(const sp<PointerControllerPolicyInterface>& policy, - const sp<Looper>& looper, const sp<SpriteController>& spriteController); + virtual ~PointerController(); virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const; @@ -113,8 +111,8 @@ public: void reloadPointerResources(); private: - static const size_t MAX_RECYCLED_SPRITES = 12; - static const size_t MAX_SPOTS = 12; + static constexpr size_t MAX_RECYCLED_SPRITES = 12; + static constexpr size_t MAX_SPOTS = 12; enum { MSG_INACTIVITY_TIMEOUT, @@ -130,8 +128,13 @@ private: float x, y; inline Spot(uint32_t id, const sp<Sprite>& sprite) - : id(id), sprite(sprite), alpha(1.0f), scale(1.0f), - x(0.0f), y(0.0f), lastIcon(NULL) { } + : id(id), + sprite(sprite), + alpha(1.0f), + scale(1.0f), + x(0.0f), + y(0.0f), + lastIcon(nullptr) {} void updateSprite(const SpriteIcon* icon, float x, float y, int32_t displayId); @@ -139,12 +142,24 @@ private: const SpriteIcon* lastIcon; }; + class MessageHandler : public virtual android::MessageHandler { + public: + void handleMessage(const Message& message) override; + std::weak_ptr<PointerController> pointerController; + }; + + class LooperCallback : public virtual android::LooperCallback { + public: + int handleEvent(int fd, int events, void* data) override; + std::weak_ptr<PointerController> pointerController; + }; + mutable Mutex mLock; sp<PointerControllerPolicyInterface> mPolicy; sp<Looper> mLooper; sp<SpriteController> mSpriteController; - sp<WeakMessageHandler> mHandler; + sp<MessageHandler> mHandler; sp<LooperCallback> mCallback; DisplayEventReceiver mDisplayEventReceiver; @@ -181,14 +196,15 @@ private: int32_t buttonState; std::map<int32_t /* displayId */, std::vector<Spot*>> spotsByDisplay; - std::vector<sp<Sprite> > recycledSprites; + std::vector<sp<Sprite>> recycledSprites; } mLocked GUARDED_BY(mLock); + PointerController(const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper, + const sp<SpriteController>& spriteController); + bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const; void setPositionLocked(float x, float y); - void handleMessage(const Message& message); - int handleEvent(int fd, int events, void* data); void doAnimate(nsecs_t timestamp); bool doFadingAnimationLocked(nsecs_t timestamp); bool doBitmapAnimationLocked(nsecs_t timestamp); diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp index 804644c230b9..acd8bced0612 100644 --- a/libs/input/SpriteController.cpp +++ b/libs/input/SpriteController.cpp @@ -23,11 +23,6 @@ #include <utils/String8.h> #include <gui/Surface.h> -#include <android/graphics/bitmap.h> -#include <android/graphics/canvas.h> -#include <android/graphics/paint.h> -#include <android/native_window.h> - namespace android { // --- SpriteController --- @@ -130,8 +125,8 @@ void SpriteController::doUpdateSprites() { SpriteUpdate& update = updates.editItemAt(i); if (update.state.surfaceControl == NULL && update.state.wantSurfaceVisible()) { - update.state.surfaceWidth = update.state.icon.bitmap.getInfo().width; - update.state.surfaceHeight = update.state.icon.bitmap.getInfo().height; + update.state.surfaceWidth = update.state.icon.width(); + update.state.surfaceHeight = update.state.icon.height(); update.state.surfaceDrawn = false; update.state.surfaceVisible = false; update.state.surfaceControl = obtainSurface( @@ -152,8 +147,8 @@ void SpriteController::doUpdateSprites() { } if (update.state.wantSurfaceVisible()) { - int32_t desiredWidth = update.state.icon.bitmap.getInfo().width; - int32_t desiredHeight = update.state.icon.bitmap.getInfo().height; + int32_t desiredWidth = update.state.icon.width(); + int32_t desiredHeight = update.state.icon.height(); if (update.state.surfaceWidth < desiredWidth || update.state.surfaceHeight < desiredHeight) { needApplyTransaction = true; @@ -194,36 +189,9 @@ void SpriteController::doUpdateSprites() { if (update.state.surfaceControl != NULL && !update.state.surfaceDrawn && update.state.wantSurfaceVisible()) { sp<Surface> surface = update.state.surfaceControl->getSurface(); - ANativeWindow_Buffer outBuffer; - status_t status = surface->lock(&outBuffer, NULL); - if (status) { - ALOGE("Error %d locking sprite surface before drawing.", status); - } else { - graphics::Paint paint; - paint.setBlendMode(ABLEND_MODE_SRC); - - graphics::Canvas canvas(outBuffer, (int32_t) surface->getBuffersDataSpace()); - canvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint); - - const int iconWidth = update.state.icon.bitmap.getInfo().width; - const int iconHeight = update.state.icon.bitmap.getInfo().height; - - if (outBuffer.width > iconWidth) { - paint.setBlendMode(ABLEND_MODE_CLEAR); // clear to transparent - canvas.drawRect({iconWidth, 0, outBuffer.width, iconHeight}, paint); - } - if (outBuffer.height > iconHeight) { - paint.setBlendMode(ABLEND_MODE_CLEAR); // clear to transparent - canvas.drawRect({0, iconHeight, outBuffer.width, outBuffer.height}, paint); - } - - status = surface->unlockAndPost(); - if (status) { - ALOGE("Error %d unlocking and posting sprite surface after drawing.", status); - } else { - update.state.surfaceDrawn = true; - update.surfaceChanged = surfaceChanged = true; - } + if (update.state.icon.draw(surface)) { + update.state.surfaceDrawn = true; + update.surfaceChanged = surfaceChanged = true; } } } diff --git a/libs/input/SpriteController.h b/libs/input/SpriteController.h index 2513544d4bdf..137b5646feae 100644 --- a/libs/input/SpriteController.h +++ b/libs/input/SpriteController.h @@ -20,9 +20,10 @@ #include <utils/RefBase.h> #include <utils/Looper.h> -#include <android/graphics/bitmap.h> #include <gui/SurfaceComposerClient.h> +#include "SpriteIcon.h" + namespace android { /* @@ -51,35 +52,6 @@ struct SpriteTransformationMatrix { }; /* - * Icon that a sprite displays, including its hotspot. - */ -struct SpriteIcon { - inline SpriteIcon() : style(0), hotSpotX(0), hotSpotY(0) { } - inline SpriteIcon(const graphics::Bitmap& bitmap, int32_t style, float hotSpotX, float hotSpotY) : - bitmap(bitmap), style(style), hotSpotX(hotSpotX), hotSpotY(hotSpotY) { } - - graphics::Bitmap bitmap; - int32_t style; - float hotSpotX; - float hotSpotY; - - inline SpriteIcon copy() const { - return SpriteIcon(bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888), style, hotSpotX, hotSpotY); - } - - inline void reset() { - bitmap.reset(); - style = 0; - hotSpotX = 0; - hotSpotY = 0; - } - - inline bool isValid() const { - return bitmap.isValid() && !bitmap.isEmpty(); - } -}; - -/* * A sprite is a simple graphical object that is displayed on-screen above other layers. * The basic sprite class is an interface. * The implementation is provided by the sprite controller. diff --git a/libs/input/SpriteIcon.cpp b/libs/input/SpriteIcon.cpp new file mode 100644 index 000000000000..b7e51e22a214 --- /dev/null +++ b/libs/input/SpriteIcon.cpp @@ -0,0 +1,60 @@ +/* + * 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. + */ + +#include "SpriteIcon.h" + +#include <android/graphics/bitmap.h> +#include <android/graphics/canvas.h> +#include <android/graphics/paint.h> +#include <android/native_window.h> +#include <log/log.h> + +namespace android { + +bool SpriteIcon::draw(sp<Surface> surface) const { + ANativeWindow_Buffer outBuffer; + status_t status = surface->lock(&outBuffer, NULL); + if (status) { + ALOGE("Error %d locking sprite surface before drawing.", status); + return false; + } + + graphics::Paint paint; + paint.setBlendMode(ABLEND_MODE_SRC); + + graphics::Canvas canvas(outBuffer, (int32_t)surface->getBuffersDataSpace()); + canvas.drawBitmap(bitmap, 0, 0, &paint); + + const int iconWidth = width(); + const int iconHeight = height(); + + if (outBuffer.width > iconWidth) { + paint.setBlendMode(ABLEND_MODE_CLEAR); // clear to transparent + canvas.drawRect({iconWidth, 0, outBuffer.width, iconHeight}, paint); + } + if (outBuffer.height > iconHeight) { + paint.setBlendMode(ABLEND_MODE_CLEAR); // clear to transparent + canvas.drawRect({0, iconHeight, outBuffer.width, outBuffer.height}, paint); + } + + status = surface->unlockAndPost(); + if (status) { + ALOGE("Error %d unlocking and posting sprite surface after drawing.", status); + } + return !status; +} + +} // namespace android diff --git a/libs/input/SpriteIcon.h b/libs/input/SpriteIcon.h new file mode 100644 index 000000000000..a257d7e89ebc --- /dev/null +++ b/libs/input/SpriteIcon.h @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#ifndef _UI_SPRITE_ICON_H +#define _UI_SPRITE_ICON_H + +#include <android/graphics/bitmap.h> +#include <gui/Surface.h> + +namespace android { + +/* + * Icon that a sprite displays, including its hotspot. + */ +struct SpriteIcon { + inline SpriteIcon() : style(0), hotSpotX(0), hotSpotY(0) {} + inline SpriteIcon(const graphics::Bitmap& bitmap, int32_t style, float hotSpotX, float hotSpotY) + : bitmap(bitmap), style(style), hotSpotX(hotSpotX), hotSpotY(hotSpotY) {} + + graphics::Bitmap bitmap; + int32_t style; + float hotSpotX; + float hotSpotY; + + inline SpriteIcon copy() const { + return SpriteIcon(bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888), style, hotSpotX, hotSpotY); + } + + inline void reset() { + bitmap.reset(); + style = 0; + hotSpotX = 0; + hotSpotY = 0; + } + + inline bool isValid() const { return bitmap.isValid() && !bitmap.isEmpty(); } + + inline int32_t width() const { return bitmap.getInfo().width; } + inline int32_t height() const { return bitmap.getInfo().height; } + + // Draw the bitmap onto the given surface. Returns true if it's successful, or false otherwise. + // Note it doesn't set any metadata to the surface. + bool draw(const sp<Surface> surface) const; +}; + +} // namespace android + +#endif // _UI_SPRITE_ICON_H diff --git a/libs/input/tests/PointerController_test.cpp b/libs/input/tests/PointerController_test.cpp index a15742671dc7..6e129a064385 100644 --- a/libs/input/tests/PointerController_test.cpp +++ b/libs/input/tests/PointerController_test.cpp @@ -136,7 +136,7 @@ protected: sp<MockSprite> mPointerSprite; sp<MockPointerControllerPolicyInterface> mPolicy; sp<MockSpriteController> mSpriteController; - sp<PointerController> mPointerController; + std::shared_ptr<PointerController> mPointerController; private: void loopThread(); @@ -160,7 +160,7 @@ PointerControllerTest::PointerControllerTest() : mPointerSprite(new NiceMock<Moc EXPECT_CALL(*mSpriteController, createSprite()) .WillOnce(Return(mPointerSprite)); - mPointerController = new PointerController(mPolicy, mLooper, mSpriteController); + mPointerController = PointerController::create(mPolicy, mLooper, mSpriteController); } PointerControllerTest::~PointerControllerTest() { @@ -193,7 +193,7 @@ void PointerControllerTest::loopThread() { TEST_F(PointerControllerTest, useDefaultCursorTypeByDefault) { ensureDisplayViewportIsSet(); - mPointerController->unfade(PointerController::TRANSITION_IMMEDIATE); + mPointerController->unfade(PointerController::Transition::IMMEDIATE); std::pair<float, float> hotspot = getHotSpotCoordinatesForType(CURSOR_TYPE_DEFAULT); EXPECT_CALL(*mPointerSprite, setVisible(true)); @@ -208,7 +208,7 @@ TEST_F(PointerControllerTest, useDefaultCursorTypeByDefault) { TEST_F(PointerControllerTest, updatePointerIcon) { ensureDisplayViewportIsSet(); - mPointerController->unfade(PointerController::TRANSITION_IMMEDIATE); + mPointerController->unfade(PointerController::Transition::IMMEDIATE); int32_t type = CURSOR_TYPE_ADDITIONAL; std::pair<float, float> hotspot = getHotSpotCoordinatesForType(type); @@ -224,7 +224,7 @@ TEST_F(PointerControllerTest, updatePointerIcon) { TEST_F(PointerControllerTest, setCustomPointerIcon) { ensureDisplayViewportIsSet(); - mPointerController->unfade(PointerController::TRANSITION_IMMEDIATE); + mPointerController->unfade(PointerController::Transition::IMMEDIATE); int32_t style = CURSOR_TYPE_CUSTOM; float hotSpotX = 15; @@ -246,13 +246,13 @@ TEST_F(PointerControllerTest, setCustomPointerIcon) { } TEST_F(PointerControllerTest, doesNotGetResourcesBeforeSettingViewport) { - mPointerController->setPresentation(PointerController::PRESENTATION_POINTER); + mPointerController->setPresentation(PointerController::Presentation::POINTER); mPointerController->setSpots(nullptr, nullptr, BitSet32(), -1); mPointerController->clearSpots(); mPointerController->setPosition(1.0f, 1.0f); mPointerController->move(1.0f, 1.0f); - mPointerController->unfade(PointerController::TRANSITION_IMMEDIATE); - mPointerController->fade(PointerController::TRANSITION_IMMEDIATE); + mPointerController->unfade(PointerController::Transition::IMMEDIATE); + mPointerController->fade(PointerController::Transition::IMMEDIATE); EXPECT_TRUE(mPolicy->noResourcesAreLoaded()); diff --git a/lowpan/tests/Android.bp b/lowpan/tests/Android.bp new file mode 100644 index 000000000000..ad2bc27d1b39 --- /dev/null +++ b/lowpan/tests/Android.bp @@ -0,0 +1,41 @@ +// Copyright (C) 2017 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. + +// Make test APK +// ============================================================ +android_test { + name: "FrameworksLowpanApiTests", + srcs: ["**/*.java"], + // Filter all src files to just java files + jacoco: { + include_filter: ["android.net.lowpan.*"], + exclude_filter: [ + "android.net.lowpan.LowpanInterfaceTest*", + "android.net.lowpan.LowpanManagerTest*", + ], + }, + static_libs: [ + "androidx.test.rules", + "guava", + "mockito-target-minus-junit4", + "frameworks-base-testutils", + ], + libs: [ + "android.test.runner", + "android.test.base", + ], + platform_apis: true, + test_suites: ["device-tests"], + certificate: "platform", +} diff --git a/lowpan/tests/Android.mk b/lowpan/tests/Android.mk deleted file mode 100644 index 832ed2f53f7b..000000000000 --- a/lowpan/tests/Android.mk +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (C) 2017 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. - -LOCAL_PATH:= $(call my-dir) - -# Make test APK -# ============================================================ -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -# This list is generated from the java source files in this module -# The list is a comma separated list of class names with * matching zero or more characters. -# Example: -# Input files: src/com/android/server/lowpan/Test.java src/com/android/server/lowpan/AnotherTest.java -# Generated exclude list: com.android.server.lowpan.Test*,com.android.server.lowpan.AnotherTest* - -# Filter all src files to just java files -local_java_files := $(filter %.java,$(LOCAL_SRC_FILES)) -# Transform java file names into full class names. -# This only works if the class name matches the file name and the directory structure -# matches the package. -local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files))) -# Convert class name list to jacoco exclude list -# This appends a * to all classes and replace the space separators with commas. -# These patterns will match all classes in this module and their inner classes. -jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes))) - -jacoco_include := android.net.lowpan.* - -LOCAL_JACK_COVERAGE_INCLUDE_FILTER := $(jacoco_include) -LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx.test.rules \ - guava \ - mockito-target-minus-junit4 \ - frameworks-base-testutils \ - -LOCAL_JAVA_LIBRARIES := \ - android.test.runner \ - android.test.base \ - -LOCAL_PACKAGE_NAME := FrameworksLowpanApiTests -LOCAL_PRIVATE_PLATFORM_APIS := true -LOCAL_COMPATIBILITY_SUITE := device-tests - -LOCAL_CERTIFICATE := platform -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk -include $(BUILD_PACKAGE) diff --git a/media/OWNERS b/media/OWNERS index a16373ef8c8d..c95ac6c210c0 100644 --- a/media/OWNERS +++ b/media/OWNERS @@ -14,6 +14,7 @@ jsharkey@android.com klhyun@google.com lajos@google.com marcone@google.com +philburk@google.com sungsoo@google.com wonsik@google.com diff --git a/media/java/android/media/MediaMetrics.java b/media/java/android/media/MediaMetrics.java index eaf86bb3936c..3a5216e1c4e7 100644 --- a/media/java/android/media/MediaMetrics.java +++ b/media/java/android/media/MediaMetrics.java @@ -18,7 +18,6 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.TestApi; import android.os.Bundle; import java.nio.ByteBuffer; @@ -583,7 +582,6 @@ public class MediaMetrics { * * @return a Bundle with the keys set according to data in the Item's buffer. */ - @TestApi public Bundle toBundle() { updateHeader(); @@ -596,23 +594,14 @@ public class MediaMetrics { // The following constants are used for tests to extract // the content of the Bundle for CTS testing. - @TestApi public static final String BUNDLE_TOTAL_SIZE = "_totalSize"; - @TestApi public static final String BUNDLE_HEADER_SIZE = "_headerSize"; - @TestApi public static final String BUNDLE_VERSION = "_version"; - @TestApi public static final String BUNDLE_KEY_SIZE = "_keySize"; - @TestApi public static final String BUNDLE_KEY = "_key"; - @TestApi public static final String BUNDLE_PID = "_pid"; - @TestApi public static final String BUNDLE_UID = "_uid"; - @TestApi public static final String BUNDLE_TIMESTAMP = "_timestamp"; - @TestApi public static final String BUNDLE_PROPERTY_COUNT = "_propertyCount"; /** @@ -623,7 +612,6 @@ public class MediaMetrics { * @param buffer contains the byte data serialized according to the byte string version. * @return a Bundle with the keys set according to data in the buffer. */ - @TestApi public static Bundle toBundle(ByteBuffer buffer) { final Bundle bundle = new Bundle(); diff --git a/media/java/android/media/Utils.java b/media/java/android/media/Utils.java index 7a4e7b897de1..ecb6b3d495ad 100644 --- a/media/java/android/media/Utils.java +++ b/media/java/android/media/Utils.java @@ -18,7 +18,6 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.TestApi; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; @@ -440,7 +439,6 @@ public class Utils { * * @param <V> The class of the object returned to the listener. */ - @TestApi public static class ListenerList<V> { /** * The Listener interface for callback. diff --git a/media/java/android/media/audiopolicy/AudioProductStrategy.java b/media/java/android/media/audiopolicy/AudioProductStrategy.java index 090f78e4e4f7..fca3498838ad 100644 --- a/media/java/android/media/audiopolicy/AudioProductStrategy.java +++ b/media/java/android/media/audiopolicy/AudioProductStrategy.java @@ -19,7 +19,6 @@ package android.media.audiopolicy; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.TestApi; import android.media.AudioAttributes; import android.media.AudioSystem; import android.media.MediaRecorder; @@ -108,7 +107,6 @@ public final class AudioProductStrategy implements Parcelable { * @param id the ID for the invalid strategy, always use a different one than in use * @return an invalid instance that cannot successfully be used for volume groups or routing */ - @TestApi @SystemApi public static @NonNull AudioProductStrategy createInvalidAudioProductStrategy(int id) { return new AudioProductStrategy("dummy strategy", id, new AudioAttributesGroup[0]); diff --git a/media/java/android/mtp/MtpStorageManager.java b/media/java/android/mtp/MtpStorageManager.java index e783788d0158..c0eb5e8bbea9 100644 --- a/media/java/android/mtp/MtpStorageManager.java +++ b/media/java/android/mtp/MtpStorageManager.java @@ -229,9 +229,16 @@ public class MtpStorageManager { } private void setParent(MtpObject parent) { + if (this.getStorageId() != parent.getStorageId()) { + mStorage = Preconditions.checkNotNull(parent.getStorage()); + } mParent = parent; } + private MtpStorage getStorage() { + return mStorage; + } + private void setDir(boolean dir) { if (dir != mIsDir) { mIsDir = dir; diff --git a/media/jni/android_media_JetPlayer.cpp b/media/jni/android_media_JetPlayer.cpp index 8a05f85e4285..481f80b278f8 100644 --- a/media/jni/android_media_JetPlayer.cpp +++ b/media/jni/android_media_JetPlayer.cpp @@ -23,7 +23,7 @@ #include <fcntl.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "core_jni_helpers.h" #include <utils/Log.h> diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp index 528dc62c3016..948ebcd9fdd5 100644 --- a/media/jni/android_media_MediaExtractor.cpp +++ b/media/jni/android_media_MediaExtractor.cpp @@ -28,7 +28,7 @@ #include "android_runtime/Log.h" #include "android_util_Binder.h" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android/hardware/cas/1.0/BpHwCas.h> #include <android/hardware/cas/1.0/BnHwCas.h> diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp index 1c9b349a7eed..6fbd29cb8623 100644 --- a/media/jni/android_media_MediaMetadataRetriever.cpp +++ b/media/jni/android_media_MediaMetadataRetriever.cpp @@ -30,7 +30,7 @@ #include <private/media/VideoFrame.h> #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "android_runtime/AndroidRuntime.h" #include "android_media_MediaDataSource.h" #include "android_media_Streams.h" diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp index 262ec76da26e..267917653efb 100644 --- a/media/jni/android_media_MediaMuxer.cpp +++ b/media/jni/android_media_MediaMuxer.cpp @@ -21,7 +21,7 @@ #include "android_media_Streams.h" #include "android_runtime/AndroidRuntime.h" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <unistd.h> #include <fcntl.h> diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 5cb42a9a96cc..e910add86d3c 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -32,7 +32,7 @@ #include <fcntl.h> #include <utils/threads.h> #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "android_runtime/AndroidRuntime.h" #include "android_runtime/android_view_Surface.h" #include "android_runtime/Log.h" diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp index 6eeccf0e5a77..f99dc012be95 100644 --- a/media/jni/android_media_MediaRecorder.cpp +++ b/media/jni/android_media_MediaRecorder.cpp @@ -37,7 +37,7 @@ #include <nativehelper/ScopedUtfChars.h> #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "android_media_AudioErrors.h" #include "android_media_MediaMetricsJNI.h" #include "android_media_MicrophoneInfo.h" diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp index 39ff04ab2a0a..8a1ae9252ca3 100644 --- a/media/jni/android_mtp_MtpServer.cpp +++ b/media/jni/android_mtp_MtpServer.cpp @@ -25,7 +25,7 @@ #include <utils/threads.h> #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "android_runtime/AndroidRuntime.h" #include "private/android_filesystem_config.h" diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp index efeb3352d393..f4d65d0a397f 100644 --- a/media/jni/audioeffect/Visualizer.cpp +++ b/media/jni/audioeffect/Visualizer.cpp @@ -25,6 +25,7 @@ #include <limits.h> #include <audio_utils/fixedfft.h> +#include <cutils/bitops.h> #include <utils/Thread.h> #include "Visualizer.h" diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp index 8f6df3db718b..ca3cc8552990 100644 --- a/media/jni/soundpool/android_media_SoundPool.cpp +++ b/media/jni/soundpool/android_media_SoundPool.cpp @@ -21,7 +21,7 @@ #include <utils/Log.h> #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include "SoundPool.h" diff --git a/media/mca/filterfw/Android.bp b/media/mca/filterfw/Android.bp index 71899cf1653f..0e0ecf331afc 100644 --- a/media/mca/filterfw/Android.bp +++ b/media/mca/filterfw/Android.bp @@ -65,6 +65,8 @@ cc_library_static { "-Wno-unused-parameter", ], + header_libs: ["jni_headers"], + shared_libs: [ "libmedia", "libgui", 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/native/android/sharedmem.cpp b/native/android/sharedmem.cpp index 4410bd6fbeed..338b280a8ebe 100644 --- a/native/android/sharedmem.cpp +++ b/native/android/sharedmem.cpp @@ -16,6 +16,9 @@ #include <jni.h> +#include <fcntl.h> +#include <unistd.h> + #include <android/sharedmem.h> #include <android/sharedmem_jni.h> #include <cutils/ashmem.h> @@ -23,7 +26,6 @@ #include <utils/Errors.h> #include <mutex> -#include <unistd.h> static struct { jclass clazz; diff --git a/native/webview/loader/Android.bp b/native/webview/loader/Android.bp index 0ba256facb6d..dfa5bdde0785 100644 --- a/native/webview/loader/Android.bp +++ b/native/webview/loader/Android.bp @@ -24,6 +24,8 @@ cc_library_shared { cflags: ["-Werror"], + header_libs: ["jni_headers"], + shared_libs: [ "libdl", "liblog", diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index 5f15216e8400..52676c70c55d 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -3712,7 +3712,7 @@ package android.app { ctor public ActionBar.LayoutParams(int); ctor public ActionBar.LayoutParams(android.app.ActionBar.LayoutParams); ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams); - field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=0xffffffff, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.NO_GRAVITY, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.TOP, to="TOP"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.BOTTOM, to="BOTTOM"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.LEFT, to="LEFT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.RIGHT, to="RIGHT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.START, to="START"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.END, to="END"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_VERTICAL, to="CENTER_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_VERTICAL, to="FILL_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_HORIZONTAL, to="CENTER_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_HORIZONTAL, to="FILL_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL, to="FILL")}) public int gravity; + field public int gravity; } public static interface ActionBar.OnMenuVisibilityListener { @@ -10092,7 +10092,7 @@ package android.content { method public final <T> T getSystemService(@NonNull Class<T>); method @Nullable public abstract String getSystemServiceName(@NonNull Class<?>); method @NonNull public final CharSequence getText(@StringRes int); - method @android.view.ViewDebug.ExportedProperty(deepExport=true) public abstract android.content.res.Resources.Theme getTheme(); + method public abstract android.content.res.Resources.Theme getTheme(); method @Deprecated public abstract android.graphics.drawable.Drawable getWallpaper(); method @Deprecated public abstract int getWallpaperDesiredMinimumHeight(); method @Deprecated public abstract int getWallpaperDesiredMinimumWidth(); @@ -11945,7 +11945,7 @@ package android.content.pm { } public abstract class PackageManager { - ctor public PackageManager(); + ctor @Deprecated public PackageManager(); method @Deprecated public abstract void addPackageToPreferred(@NonNull String); method public abstract boolean addPermission(@NonNull android.content.pm.PermissionInfo); method public abstract boolean addPermissionAsync(@NonNull android.content.pm.PermissionInfo); @@ -34376,6 +34376,7 @@ package android.os { field public static final String PRODUCT; field @Deprecated public static final String RADIO; field @Deprecated public static final String SERIAL; + field @NonNull public static final String SKU; field public static final String[] SUPPORTED_32_BIT_ABIS; field public static final String[] SUPPORTED_64_BIT_ABIS; field public static final String[] SUPPORTED_ABIS; @@ -40912,6 +40913,7 @@ package android.security.keystore { method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationType(); method public int getUserAuthenticationValidityDurationSeconds(); + method public boolean isDevicePropertiesAttestationIncluded(); method @NonNull public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); method public boolean isRandomizedEncryptionRequired(); @@ -40933,6 +40935,7 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(@NonNull java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSerialNumber(@NonNull java.math.BigInteger); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSubject(@NonNull javax.security.auth.x500.X500Principal); + method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDevicePropertiesAttestationIncluded(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setDigests(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setInvalidatedByBiometricEnrollment(boolean); @@ -45169,7 +45172,7 @@ package android.telephony { public abstract class CellLocation { ctor public CellLocation(); method public static android.telephony.CellLocation getEmpty(); - method public static void requestLocationUpdate(); + method @Deprecated public static void requestLocationUpdate(); } public abstract class CellSignalStrength { @@ -45616,6 +45619,88 @@ package android.telephony { field public static final int VSNCP_TIMEOUT = 2236; // 0x8bc } + 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_CALL_OVER_WFC_NOT_AVAILABLE = 78; // 0x4e + 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 MEDIA_TIMEOUT = 77; // 0x4d + 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 WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 79; // 0x4f + field public static final int WIFI_LOST = 59; // 0x3b + } + public class IccOpenLogicalChannelResponse implements android.os.Parcelable { method public int describeContents(); method public int getChannel(); @@ -45632,12 +45717,14 @@ package android.telephony { public class MbmsDownloadSession implements java.lang.AutoCloseable { method public void addProgressListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.DownloadProgressListener); + method public void addServiceAnnouncement(@NonNull byte[]); method public void addStatusListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.DownloadStatusListener); method public void cancelDownload(@NonNull android.telephony.mbms.DownloadRequest); method public void close(); method public static android.telephony.MbmsDownloadSession create(@NonNull android.content.Context, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.MbmsDownloadSessionCallback); method @Nullable public static android.telephony.MbmsDownloadSession create(@NonNull android.content.Context, @NonNull java.util.concurrent.Executor, int, @NonNull android.telephony.mbms.MbmsDownloadSessionCallback); method public void download(@NonNull android.telephony.mbms.DownloadRequest); + method public static int getMaximumServiceAnnouncementSize(); method @Nullable public java.io.File getTempFileRootDirectory(); method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(); method public void removeProgressListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull android.telephony.mbms.DownloadProgressListener); @@ -46085,6 +46172,7 @@ package android.telephony { method public static int[] calculateLength(String, boolean); method @Deprecated public static android.telephony.SmsMessage createFromPdu(byte[]); method public static android.telephony.SmsMessage createFromPdu(byte[], String); + method @Nullable public static android.telephony.SmsMessage createSmsSubmitPdu(@NonNull byte[], boolean); method public String getDisplayMessageBody(); method public String getDisplayOriginatingAddress(); method public String getEmailBody(); @@ -46167,7 +46255,7 @@ package android.telephony { public class SubscriptionManager { method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); - method public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); + method @Deprecated public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); method public void addOnSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void addSubscriptionsIntoGroup(@NonNull java.util.List<java.lang.Integer>, @NonNull android.os.ParcelUuid); method public boolean canManageSubscription(android.telephony.SubscriptionInfo); @@ -47248,6 +47336,7 @@ package android.telephony.mbms { public static class MbmsErrors.DownloadErrors { field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191 + field public static final int ERROR_MALFORMED_SERVICE_ANNOUNCEMENT = 404; // 0x194 field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192 field public static final int ERROR_UNKNOWN_FILE_INFO = 403; // 0x193 } @@ -51999,13 +52088,13 @@ package android.view { method @Nullable public CharSequence getAccessibilityPaneTitle(); method @IdRes public int getAccessibilityTraversalAfter(); method @IdRes public int getAccessibilityTraversalBefore(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getAlpha(); + method public float getAlpha(); method public android.view.animation.Animation getAnimation(); method @Nullable public android.graphics.Matrix getAnimationMatrix(); method public android.os.IBinder getApplicationWindowToken(); method @NonNull public int[] getAttributeResolutionStack(@AttrRes int); method @NonNull public java.util.Map<java.lang.Integer,java.lang.Integer> getAttributeSourceResourceMap(); - method @android.view.ViewDebug.ExportedProperty @Nullable public String[] getAutofillHints(); + method @Nullable public String[] getAutofillHints(); method public final android.view.autofill.AutofillId getAutofillId(); method public int getAutofillType(); method @Nullable public android.view.autofill.AutofillValue getAutofillValue(); @@ -52013,8 +52102,8 @@ package android.view { method @Nullable public android.graphics.BlendMode getBackgroundTintBlendMode(); method @Nullable public android.content.res.ColorStateList getBackgroundTintList(); method @Nullable public android.graphics.PorterDuff.Mode getBackgroundTintMode(); - method @android.view.ViewDebug.ExportedProperty(category="layout") public int getBaseline(); - method @android.view.ViewDebug.CapturedViewProperty public final int getBottom(); + method public int getBaseline(); + method public final int getBottom(); method protected float getBottomFadingEdgeStrength(); method protected int getBottomPaddingOffset(); method public float getCameraDistance(); @@ -52022,10 +52111,10 @@ package android.view { method public boolean getClipBounds(android.graphics.Rect); method public final boolean getClipToOutline(); method @Nullable public final android.view.contentcapture.ContentCaptureSession getContentCaptureSession(); - method @android.view.ViewDebug.ExportedProperty(category="accessibility") public CharSequence getContentDescription(); - method @android.view.ViewDebug.CapturedViewProperty public final android.content.Context getContext(); + method public CharSequence getContentDescription(); + method public final android.content.Context getContext(); method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean getDefaultFocusHighlightEnabled(); + method public final boolean getDefaultFocusHighlightEnabled(); method public static int getDefaultSize(int, int); method public android.view.Display getDisplay(); method public final int[] getDrawableState(); @@ -52035,11 +52124,11 @@ package android.view { method @Deprecated public int getDrawingCacheQuality(); method public void getDrawingRect(android.graphics.Rect); method public long getDrawingTime(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getElevation(); + method public float getElevation(); method @StyleRes public int getExplicitStyle(); - method @android.view.ViewDebug.ExportedProperty public boolean getFilterTouchesWhenObscured(); - method @android.view.ViewDebug.ExportedProperty public boolean getFitsSystemWindows(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.NOT_FOCUSABLE, to="NOT_FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE, to="FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE_AUTO, to="FOCUSABLE_AUTO")}, category="focus") public int getFocusable(); + method public boolean getFilterTouchesWhenObscured(); + method public boolean getFitsSystemWindows(); + method public int getFocusable(); method public java.util.ArrayList<android.view.View> getFocusables(int); method public void getFocusedRect(android.graphics.Rect); method public android.graphics.drawable.Drawable getForeground(); @@ -52051,23 +52140,23 @@ package android.view { method public final boolean getGlobalVisibleRect(android.graphics.Rect); method public android.os.Handler getHandler(); method public final boolean getHasOverlappingRendering(); - method @android.view.ViewDebug.ExportedProperty(category="layout") public final int getHeight(); + method public final int getHeight(); method public void getHitRect(android.graphics.Rect); method public int getHorizontalFadingEdgeLength(); method protected int getHorizontalScrollbarHeight(); method @Nullable public android.graphics.drawable.Drawable getHorizontalScrollbarThumbDrawable(); method @Nullable public android.graphics.drawable.Drawable getHorizontalScrollbarTrackDrawable(); - method @android.view.ViewDebug.CapturedViewProperty @IdRes public int getId(); - method @android.view.ViewDebug.ExportedProperty(category="accessibility", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS, to="noHideDescendants")}) public int getImportantForAccessibility(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForAutofill(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForContentCapture(); + method @IdRes public int getId(); + method public int getImportantForAccessibility(); + method public int getImportantForAutofill(); + method public int getImportantForContentCapture(); method public boolean getKeepScreenOn(); method public android.view.KeyEvent.DispatcherState getKeyDispatcherState(); - method @android.view.ViewDebug.ExportedProperty(category="accessibility") @IdRes public int getLabelFor(); + method @IdRes public int getLabelFor(); method public int getLayerType(); - method @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.LAYOUT_DIRECTION_LTR, to="RESOLVED_DIRECTION_LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.LAYOUT_DIRECTION_RTL, to="RESOLVED_DIRECTION_RTL")}) public int getLayoutDirection(); - method @android.view.ViewDebug.ExportedProperty(deepExport=true, prefix="layout_") public android.view.ViewGroup.LayoutParams getLayoutParams(); - method @android.view.ViewDebug.CapturedViewProperty public final int getLeft(); + method public int getLayoutDirection(); + method public android.view.ViewGroup.LayoutParams getLayoutParams(); + method public final int getLeft(); method protected float getLeftFadingEdgeStrength(); method protected int getLeftPaddingOffset(); method public final boolean getLocalVisibleRect(android.graphics.Rect); @@ -52076,10 +52165,10 @@ package android.view { method public void getLocationOnScreen(@Size(2) int[]); method public android.graphics.Matrix getMatrix(); method public final int getMeasuredHeight(); - method @android.view.ViewDebug.ExportedProperty(category="measurement", flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.View.MEASURED_STATE_MASK, equals=android.view.View.MEASURED_STATE_TOO_SMALL, name="MEASURED_STATE_TOO_SMALL")}) public final int getMeasuredHeightAndState(); + method public final int getMeasuredHeightAndState(); method public final int getMeasuredState(); method public final int getMeasuredWidth(); - method @android.view.ViewDebug.ExportedProperty(category="measurement", flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.View.MEASURED_STATE_MASK, equals=android.view.View.MEASURED_STATE_TOO_SMALL, name="MEASURED_STATE_TOO_SMALL")}) public final int getMeasuredWidthAndState(); + method public final int getMeasuredWidthAndState(); method public int getMinimumHeight(); method public int getMinimumWidth(); method @IdRes public int getNextClusterForwardId(); @@ -52102,51 +52191,51 @@ package android.view { method public int getPaddingTop(); method public final android.view.ViewParent getParent(); method public android.view.ViewParent getParentForAccessibility(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getPivotX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getPivotY(); + method public float getPivotX(); + method public float getPivotY(); method public android.view.PointerIcon getPointerIcon(); method public android.content.res.Resources getResources(); method public final boolean getRevealOnFocusHint(); - method @android.view.ViewDebug.CapturedViewProperty public final int getRight(); + method public final int getRight(); method protected float getRightFadingEdgeStrength(); method protected int getRightPaddingOffset(); method public android.view.View getRootView(); method public android.view.WindowInsets getRootWindowInsets(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotation(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotationX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getRotationY(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getScaleX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getScaleY(); + method public float getRotation(); + method public float getRotationX(); + method public float getRotationY(); + method public float getScaleX(); + method public float getScaleY(); method public int getScrollBarDefaultDelayBeforeFade(); method public int getScrollBarFadeDuration(); method public int getScrollBarSize(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_INSIDE_OVERLAY, to="INSIDE_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_INSIDE_INSET, to="INSIDE_INSET"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_OUTSIDE_OVERLAY, to="OUTSIDE_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.View.SCROLLBARS_OUTSIDE_INSET, to="OUTSIDE_INSET")}) public int getScrollBarStyle(); + method public int getScrollBarStyle(); method public int getScrollIndicators(); method public final int getScrollX(); method public final int getScrollY(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") @ColorInt public int getSolidColor(); + method @ColorInt public int getSolidColor(); method @LayoutRes public int getSourceLayoutResId(); - method @android.view.ViewDebug.ExportedProperty(category="accessibility") @Nullable public final CharSequence getStateDescription(); + method @Nullable public final CharSequence getStateDescription(); method public android.animation.StateListAnimator getStateListAnimator(); method protected int getSuggestedMinimumHeight(); method protected int getSuggestedMinimumWidth(); method @NonNull public java.util.List<android.graphics.Rect> getSystemGestureExclusionRects(); method @Deprecated public int getSystemUiVisibility(); - method @android.view.ViewDebug.ExportedProperty public Object getTag(); + method public Object getTag(); method public Object getTag(int); - method @android.view.ViewDebug.ExportedProperty(category="text", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_INHERIT, to="INHERIT"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_GRAVITY, to="GRAVITY"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_TEXT_START, to="TEXT_START"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_TEXT_END, to="TEXT_END"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_VIEW_START, to="VIEW_START"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_ALIGNMENT_VIEW_END, to="VIEW_END")}) public int getTextAlignment(); - method @android.view.ViewDebug.ExportedProperty(category="text", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_INHERIT, to="INHERIT"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG, to="FIRST_STRONG"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_ANY_RTL, to="ANY_RTL"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_LTR, to="LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_RTL, to="RTL"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_LOCALE, to="LOCALE"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG_LTR, to="FIRST_STRONG_LTR"), @android.view.ViewDebug.IntToString(from=android.view.View.TEXT_DIRECTION_FIRST_STRONG_RTL, to="FIRST_STRONG_RTL")}) public int getTextDirection(); + method public int getTextAlignment(); + method public int getTextDirection(); method @Nullable public CharSequence getTooltipText(); - method @android.view.ViewDebug.CapturedViewProperty public final int getTop(); + method public final int getTop(); method protected float getTopFadingEdgeStrength(); method protected int getTopPaddingOffset(); method public android.view.TouchDelegate getTouchDelegate(); method public java.util.ArrayList<android.view.View> getTouchables(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTransitionAlpha(); - method @android.view.ViewDebug.ExportedProperty public String getTransitionName(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationY(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getTranslationZ(); + method public float getTransitionAlpha(); + method public String getTransitionName(); + method public float getTranslationX(); + method public float getTranslationY(); + method public float getTranslationZ(); method public long getUniqueDrawingId(); method public int getVerticalFadingEdgeLength(); method public int getVerticalScrollbarPosition(); @@ -52154,8 +52243,8 @@ package android.view { method @Nullable public android.graphics.drawable.Drawable getVerticalScrollbarTrackDrawable(); method public int getVerticalScrollbarWidth(); method public android.view.ViewTreeObserver getViewTreeObserver(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.VISIBLE, to="VISIBLE"), @android.view.ViewDebug.IntToString(from=android.view.View.INVISIBLE, to="INVISIBLE"), @android.view.ViewDebug.IntToString(from=android.view.View.GONE, to="GONE")}) public int getVisibility(); - method @android.view.ViewDebug.ExportedProperty(category="layout") public final int getWidth(); + method public int getVisibility(); + method public final int getWidth(); method protected int getWindowAttachCount(); method public android.view.WindowId getWindowId(); method @Nullable public android.view.WindowInsetsController getWindowInsetsController(); @@ -52163,18 +52252,18 @@ package android.view { method public android.os.IBinder getWindowToken(); method public int getWindowVisibility(); method public void getWindowVisibleDisplayFrame(android.graphics.Rect); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getX(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getY(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getZ(); + method public float getX(); + method public float getY(); + method public float getZ(); method public boolean hasExplicitFocusable(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean hasFocus(); + method public boolean hasFocus(); method public boolean hasFocusable(); method public boolean hasNestedScrollingParent(); method public boolean hasOnClickListeners(); method public boolean hasOnLongClickListeners(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean hasOverlappingRendering(); + method public boolean hasOverlappingRendering(); method public boolean hasPointerCapture(); - method @android.view.ViewDebug.ExportedProperty(category="layout") public boolean hasTransientState(); + method public boolean hasTransientState(); method public boolean hasWindowFocus(); method public static android.view.View inflate(android.content.Context, @LayoutRes int, android.view.ViewGroup); method @Deprecated public void invalidate(android.graphics.Rect); @@ -52184,50 +52273,50 @@ package android.view { method public void invalidateOutline(); method public boolean isAccessibilityFocused(); method public boolean isAccessibilityHeading(); - method @android.view.ViewDebug.ExportedProperty public boolean isActivated(); + method public boolean isActivated(); method public boolean isAttachedToWindow(); - method @android.view.ViewDebug.ExportedProperty public boolean isClickable(); + method public boolean isClickable(); method public boolean isContextClickable(); method public boolean isDirty(); - method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isDrawingCacheEnabled(); + method @Deprecated public boolean isDrawingCacheEnabled(); method public boolean isDuplicateParentStateEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isEnabled(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusable(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusableInTouchMode(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean isFocused(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isFocusedByDefault(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isForceDarkAllowed(); - method @android.view.ViewDebug.ExportedProperty public boolean isHapticFeedbackEnabled(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isHardwareAccelerated(); + method public boolean isEnabled(); + method public final boolean isFocusable(); + method public final boolean isFocusableInTouchMode(); + method public boolean isFocused(); + method public final boolean isFocusedByDefault(); + method public boolean isForceDarkAllowed(); + method public boolean isHapticFeedbackEnabled(); + method public boolean isHardwareAccelerated(); method public boolean isHorizontalFadingEdgeEnabled(); method public boolean isHorizontalScrollBarEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isHovered(); + method public boolean isHovered(); method public boolean isImportantForAccessibility(); method public final boolean isImportantForAutofill(); method public final boolean isImportantForContentCapture(); method public boolean isInEditMode(); method public boolean isInLayout(); - method @android.view.ViewDebug.ExportedProperty public boolean isInTouchMode(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public final boolean isKeyboardNavigationCluster(); + method public boolean isInTouchMode(); + method public final boolean isKeyboardNavigationCluster(); method public boolean isLaidOut(); method public boolean isLayoutDirectionResolved(); method public boolean isLayoutRequested(); method public boolean isLongClickable(); method public boolean isNestedScrollingEnabled(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean isOpaque(); + method public boolean isOpaque(); method protected boolean isPaddingOffsetRequired(); method public boolean isPaddingRelative(); method public boolean isPivotSet(); - method @android.view.ViewDebug.ExportedProperty public boolean isPressed(); + method public boolean isPressed(); method public boolean isSaveEnabled(); method public boolean isSaveFromParentEnabled(); method public boolean isScreenReaderFocusable(); method public boolean isScrollContainer(); method public boolean isScrollbarFadingEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isSelected(); + method public boolean isSelected(); method public final boolean isShowingLayoutBounds(); method public boolean isShown(); - method @android.view.ViewDebug.ExportedProperty public boolean isSoundEffectsEnabled(); + method public boolean isSoundEffectsEnabled(); method public final boolean isTemporarilyDetached(); method public boolean isTextAlignmentResolved(); method public boolean isTextDirectionResolved(); @@ -52518,8 +52607,8 @@ package android.view { method public void unscheduleDrawable(android.graphics.drawable.Drawable); method public final void updateDragShadow(android.view.View.DragShadowBuilder); method @CallSuper protected boolean verifyDrawable(@NonNull android.graphics.drawable.Drawable); - method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean willNotCacheDrawing(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean willNotDraw(); + method @Deprecated public boolean willNotCacheDrawing(); + method public boolean willNotDraw(); field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2 field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0 field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1 @@ -52960,9 +53049,9 @@ package android.view { method public static int getChildMeasureSpec(int, int, int); method protected boolean getChildStaticTransformation(android.view.View, android.view.animation.Transformation); method public boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean getClipChildren(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") public boolean getClipToPadding(); - method @android.view.ViewDebug.ExportedProperty(category="focus", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_BEFORE_DESCENDANTS, to="FOCUS_BEFORE_DESCENDANTS"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_AFTER_DESCENDANTS, to="FOCUS_AFTER_DESCENDANTS"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.FOCUS_BLOCK_DESCENDANTS, to="FOCUS_BLOCK_DESCENDANTS")}) public int getDescendantFocusability(); + method public boolean getClipChildren(); + method public boolean getClipToPadding(); + method public int getDescendantFocusability(); method public android.view.View getFocusedChild(); method public android.view.animation.LayoutAnimationController getLayoutAnimation(); method public android.view.animation.Animation.AnimationListener getLayoutAnimationListener(); @@ -52970,14 +53059,14 @@ package android.view { method public android.animation.LayoutTransition getLayoutTransition(); method public int getNestedScrollAxes(); method public android.view.ViewGroupOverlay getOverlay(); - method @Deprecated @android.view.ViewDebug.ExportedProperty(category="drawing", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_NO_CACHE, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_ANIMATION_CACHE, to="ANIMATION"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_SCROLLING_CACHE, to="SCROLLING"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.PERSISTENT_ALL_CACHES, to="ALL")}) public int getPersistentDrawingCache(); - method @android.view.ViewDebug.ExportedProperty(category="focus") public boolean getTouchscreenBlocksFocus(); + method @Deprecated public int getPersistentDrawingCache(); + method public boolean getTouchscreenBlocksFocus(); method public int indexOfChild(android.view.View); method @Deprecated public final void invalidateChild(android.view.View, android.graphics.Rect); method @Deprecated public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect); method @Deprecated public boolean isAlwaysDrawnWithCacheEnabled(); method @Deprecated public boolean isAnimationCacheEnabled(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") protected boolean isChildrenDrawingOrderEnabled(); + method protected boolean isChildrenDrawingOrderEnabled(); method @Deprecated protected boolean isChildrenDrawnWithCacheEnabled(); method public boolean isLayoutSuppressed(); method public boolean isMotionEventSplittingEnabled(); @@ -53068,9 +53157,9 @@ package android.view { field @Deprecated public static final int FILL_PARENT = -1; // 0xffffffff field public static final int MATCH_PARENT = -1; // 0xffffffff field public static final int WRAP_CONTENT = -2; // 0xfffffffe - field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.MATCH_PARENT, to="MATCH_PARENT"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.WRAP_CONTENT, to="WRAP_CONTENT")}) public int height; + field public int height; field public android.view.animation.LayoutAnimationController.AnimationParameters layoutAnimationParameters; - field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.MATCH_PARENT, to="MATCH_PARENT"), @android.view.ViewDebug.IntToString(from=android.view.ViewGroup.LayoutParams.WRAP_CONTENT, to="WRAP_CONTENT")}) public int width; + field public int width; } public static class ViewGroup.MarginLayoutParams extends android.view.ViewGroup.LayoutParams { @@ -53086,10 +53175,10 @@ package android.view { method public void setMarginEnd(int); method public void setMarginStart(int); method public void setMargins(int, int, int, int); - field @android.view.ViewDebug.ExportedProperty(category="layout") public int bottomMargin; - field @android.view.ViewDebug.ExportedProperty(category="layout") public int leftMargin; - field @android.view.ViewDebug.ExportedProperty(category="layout") public int rightMargin; - field @android.view.ViewDebug.ExportedProperty(category="layout") public int topMargin; + field public int bottomMargin; + field public int leftMargin; + field public int rightMargin; + field public int topMargin; } public static interface ViewGroup.OnHierarchyChangeListener { @@ -53886,11 +53975,11 @@ package android.view { field public float alpha; field public float buttonBrightness; field public float dimAmount; - field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, name="ALLOW_LOCK_WHILE_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND, equals=android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND, name="DIM_BEHIND"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND, equals=android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND, name="BLUR_BEHIND"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, name="NOT_FOCUSABLE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, name="NOT_TOUCHABLE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, equals=android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, name="NOT_TOUCH_MODAL"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, equals=android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, name="TOUCHABLE_WHEN_WAKING"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, name="KEEP_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, name="LAYOUT_IN_SCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, name="LAYOUT_NO_LIMITS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN, name="FULLSCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, equals=android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, name="FORCE_NOT_FULLSCREEN"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DITHER, equals=android.view.WindowManager.LayoutParams.FLAG_DITHER, name="DITHER"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SECURE, equals=android.view.WindowManager.LayoutParams.FLAG_SECURE, name="SECURE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SCALED, equals=android.view.WindowManager.LayoutParams.FLAG_SCALED, name="SCALED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, equals=android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES, name="IGNORE_CHEEK_PRESSES"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, name="LAYOUT_INSET_DECOR"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, equals=android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, name="ALT_FOCUSABLE_IM"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, equals=android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, name="WATCH_OUTSIDE_TOUCH"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, equals=android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, name="SHOW_WHEN_LOCKED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER, equals=android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER, name="SHOW_WALLPAPER"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, equals=android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, name="TURN_SCREEN_ON"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, equals=android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, name="DISMISS_KEYGUARD"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, equals=android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, name="SPLIT_TOUCH"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, equals=android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, name="HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN, name="LOCAL_FOCUS_MODE"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, equals=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, name="TRANSLUCENT_STATUS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, equals=android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, name="TRANSLUCENT_NAVIGATION"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE, equals=android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE, name="LOCAL_FOCUS_MODE"), @android.view.ViewDebug.FlagToString(mask=0x20000000, equals=0x20000000, name="FLAG_SLIPPERY"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR, equals=android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR, name="FLAG_LAYOUT_ATTACHED_IN_DECOR"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, equals=android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, name="DRAWS_SYSTEM_BAR_BACKGROUNDS")}, formatToHexString=true) public int flags; + field public int flags; field public int format; field public int gravity; field public float horizontalMargin; - field @android.view.ViewDebug.ExportedProperty public float horizontalWeight; + field public float horizontalWeight; field public int layoutInDisplayCutoutMode; field @Deprecated public int memoryType; field public String packageName; @@ -53903,12 +53992,12 @@ package android.view { field public int softInputMode; field @Deprecated public int systemUiVisibility; field public android.os.IBinder token; - field @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION, to="BASE_APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION, to="APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING, to="APPLICATION_STARTING"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION, to="DRAWN_APPLICATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, to="APPLICATION_PANEL"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA, to="APPLICATION_MEDIA"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, to="APPLICATION_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=0x3ed, to="APPLICATION_ABOVE_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG, to="APPLICATION_ATTACHED_DIALOG"), @android.view.ViewDebug.IntToString(from=0x3ec, to="APPLICATION_MEDIA_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR, to="STATUS_BAR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR, to="SEARCH_BAR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PHONE, to="PHONE"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, to="SYSTEM_ALERT"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_TOAST, to="TOAST"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, to="SYSTEM_OVERLAY"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE, to="PRIORITY_PHONE"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG, to="SYSTEM_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, to="KEYGUARD_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, to="SYSTEM_ERROR"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD, to="INPUT_METHOD"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG, to="INPUT_METHOD_DIALOG"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_WALLPAPER, to="WALLPAPER"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, to="STATUS_BAR_PANEL"), @android.view.ViewDebug.IntToString(from=0x7df, to="SECURE_SYSTEM_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7e0, to="DRAG"), @android.view.ViewDebug.IntToString(from=0x7e1, to="STATUS_BAR_SUB_PANEL"), @android.view.ViewDebug.IntToString(from=0x7e2, to="POINTER"), @android.view.ViewDebug.IntToString(from=0x7e3, to="NAVIGATION_BAR"), @android.view.ViewDebug.IntToString(from=0x7e4, to="VOLUME_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7e5, to="BOOT_PROGRESS"), @android.view.ViewDebug.IntToString(from=0x7e6, to="INPUT_CONSUMER"), @android.view.ViewDebug.IntToString(from=0x7e8, to="NAVIGATION_BAR_PANEL"), @android.view.ViewDebug.IntToString(from=0x7ea, to="DISPLAY_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7eb, to="MAGNIFICATION_OVERLAY"), @android.view.ViewDebug.IntToString(from=0x7f5, to="PRESENTATION"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION, to="PRIVATE_PRESENTATION"), @android.view.ViewDebug.IntToString(from=0x7ef, to="VOICE_INTERACTION"), @android.view.ViewDebug.IntToString(from=0x7f1, to="VOICE_INTERACTION_STARTING"), @android.view.ViewDebug.IntToString(from=0x7f2, to="DOCK_DIVIDER"), @android.view.ViewDebug.IntToString(from=0x7f3, to="QS_DIALOG"), @android.view.ViewDebug.IntToString(from=0x7f4, to="SCREENSHOT"), @android.view.ViewDebug.IntToString(from=android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, to="APPLICATION_OVERLAY")}) public int type; + field public int type; field public float verticalMargin; - field @android.view.ViewDebug.ExportedProperty public float verticalWeight; + field public float verticalWeight; field public int windowAnimations; - field @android.view.ViewDebug.ExportedProperty public int x; - field @android.view.ViewDebug.ExportedProperty public int y; + field public int x; + field public int y; } public final class WindowMetrics { @@ -56645,21 +56734,21 @@ package android.webkit { method public void flingScroll(int, int); method @Deprecated public void freeMemory(); method @Nullable public android.net.http.SslCertificate getCertificate(); - method @android.view.ViewDebug.ExportedProperty(category="webview") public int getContentHeight(); + method public int getContentHeight(); method @Nullable public static android.content.pm.PackageInfo getCurrentWebViewPackage(); method @Nullable public android.graphics.Bitmap getFavicon(); method @NonNull public android.webkit.WebView.HitTestResult getHitTestResult(); method @Deprecated @Nullable public String[] getHttpAuthUsernamePassword(String, String); - method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getOriginalUrl(); + method @Nullable public String getOriginalUrl(); method public int getProgress(); method public boolean getRendererPriorityWaivedWhenNotVisible(); method public int getRendererRequestedPriority(); method @NonNull public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl(); - method @Deprecated @android.view.ViewDebug.ExportedProperty(category="webview") public float getScale(); + method @Deprecated public float getScale(); method @NonNull public android.webkit.WebSettings getSettings(); method @NonNull public android.view.textclassifier.TextClassifier getTextClassifier(); - method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getTitle(); - method @android.view.ViewDebug.ExportedProperty(category="webview") @Nullable public String getUrl(); + method @Nullable public String getTitle(); + method @Nullable public String getUrl(); method @Nullable public android.webkit.WebChromeClient getWebChromeClient(); method @NonNull public static ClassLoader getWebViewClassLoader(); method @NonNull public android.webkit.WebViewClient getWebViewClient(); @@ -56861,7 +56950,7 @@ package android.widget { method public void fling(int); method public android.widget.AbsListView.LayoutParams generateLayoutParams(android.util.AttributeSet); method @ColorInt public int getBottomEdgeEffectColor(); - method @android.view.ViewDebug.ExportedProperty(category="drawing") @ColorInt public int getCacheColorHint(); + method @ColorInt public int getCacheColorHint(); method public int getCheckedItemCount(); method public long[] getCheckedItemIds(); method public int getCheckedItemPosition(); @@ -56871,7 +56960,7 @@ package android.widget { method public int getListPaddingLeft(); method public int getListPaddingRight(); method public int getListPaddingTop(); - method @android.view.ViewDebug.ExportedProperty public android.view.View getSelectedView(); + method public android.view.View getSelectedView(); method public android.graphics.drawable.Drawable getSelector(); method public CharSequence getTextFilter(); method @ColorInt public int getTopEdgeEffectColor(); @@ -56881,13 +56970,13 @@ package android.widget { method public void invalidateViews(); method public boolean isDrawSelectorOnTop(); method public boolean isFastScrollAlwaysVisible(); - method @android.view.ViewDebug.ExportedProperty public boolean isFastScrollEnabled(); + method public boolean isFastScrollEnabled(); method protected boolean isInFilterMode(); method public boolean isItemChecked(int); - method @android.view.ViewDebug.ExportedProperty public boolean isScrollingCacheEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isSmoothScrollbarEnabled(); - method @android.view.ViewDebug.ExportedProperty public boolean isStackFromBottom(); - method @android.view.ViewDebug.ExportedProperty public boolean isTextFilterEnabled(); + method public boolean isScrollingCacheEnabled(); + method public boolean isSmoothScrollbarEnabled(); + method public boolean isStackFromBottom(); + method public boolean isTextFilterEnabled(); method protected void layoutChildren(); method public void onFilterComplete(int); method public void onGlobalLayout(); @@ -57084,7 +57173,7 @@ package android.widget { ctor public AdapterView(android.content.Context, android.util.AttributeSet, int); ctor public AdapterView(android.content.Context, android.util.AttributeSet, int, int); method public abstract T getAdapter(); - method @android.view.ViewDebug.CapturedViewProperty public int getCount(); + method public int getCount(); method public android.view.View getEmptyView(); method public int getFirstVisiblePosition(); method public Object getItemAtPosition(int); @@ -57095,8 +57184,8 @@ package android.widget { method @Nullable public final android.widget.AdapterView.OnItemSelectedListener getOnItemSelectedListener(); method public int getPositionForView(android.view.View); method public Object getSelectedItem(); - method @android.view.ViewDebug.CapturedViewProperty public long getSelectedItemId(); - method @android.view.ViewDebug.CapturedViewProperty public int getSelectedItemPosition(); + method public long getSelectedItemId(); + method public int getSelectedItemPosition(); method public abstract android.view.View getSelectedView(); method public boolean performItemClick(android.view.View, int, long); method public abstract void setAdapter(T); @@ -57397,7 +57486,7 @@ package android.widget { method @Nullable public android.graphics.BlendMode getCheckMarkTintBlendMode(); method @Nullable public android.content.res.ColorStateList getCheckMarkTintList(); method @Nullable public android.graphics.PorterDuff.Mode getCheckMarkTintMode(); - method @android.view.ViewDebug.ExportedProperty public boolean isChecked(); + method public boolean isChecked(); method public void setCheckMarkDrawable(@DrawableRes int); method public void setCheckMarkDrawable(@Nullable android.graphics.drawable.Drawable); method public void setCheckMarkTintBlendMode(@Nullable android.graphics.BlendMode); @@ -57438,7 +57527,7 @@ package android.widget { method @Nullable public android.graphics.BlendMode getButtonTintBlendMode(); method @Nullable public android.content.res.ColorStateList getButtonTintList(); method @Nullable public android.graphics.PorterDuff.Mode getButtonTintMode(); - method @android.view.ViewDebug.ExportedProperty public boolean isChecked(); + method public boolean isChecked(); method public void setButtonDrawable(@DrawableRes int); method public void setButtonDrawable(@Nullable android.graphics.drawable.Drawable); method public void setButtonTintBlendMode(@Nullable android.graphics.BlendMode); @@ -57827,7 +57916,7 @@ package android.widget { method public int getColumnWidth(); method public int getGravity(); method public int getHorizontalSpacing(); - method @android.view.ViewDebug.ExportedProperty public int getNumColumns(); + method public int getNumColumns(); method public int getRequestedColumnWidth(); method public int getRequestedHorizontalSpacing(); method public int getStretchMode(); @@ -58018,8 +58107,8 @@ package android.widget { ctor public LinearLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams); ctor public LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams); method public String debug(String); - field @android.view.ViewDebug.ExportedProperty(category="layout", mapping={@android.view.ViewDebug.IntToString(from=0xffffffff, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.NO_GRAVITY, to="NONE"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.TOP, to="TOP"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.BOTTOM, to="BOTTOM"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.LEFT, to="LEFT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.RIGHT, to="RIGHT"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.START, to="START"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.END, to="END"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_VERTICAL, to="CENTER_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_VERTICAL, to="FILL_VERTICAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER_HORIZONTAL, to="CENTER_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL_HORIZONTAL, to="FILL_HORIZONTAL"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.CENTER, to="CENTER"), @android.view.ViewDebug.IntToString(from=android.view.Gravity.FILL, to="FILL")}) public int gravity; - field @android.view.ViewDebug.ExportedProperty(category="layout") public float weight; + field public int gravity; + field public float weight; } public interface ListAdapter extends android.widget.Adapter { @@ -58408,13 +58497,13 @@ package android.widget { method @Nullable public android.content.res.ColorStateList getIndeterminateTintList(); method @Nullable public android.graphics.PorterDuff.Mode getIndeterminateTintMode(); method public android.view.animation.Interpolator getInterpolator(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMax(); + method public int getMax(); method @Px public int getMaxHeight(); method @Px public int getMaxWidth(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public int getMin(); + method public int getMin(); method @Px public int getMinHeight(); method @Px public int getMinWidth(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public int getProgress(); + method public int getProgress(); method @Nullable public android.graphics.BlendMode getProgressBackgroundTintBlendMode(); method @Nullable public android.content.res.ColorStateList getProgressBackgroundTintList(); method @Nullable public android.graphics.PorterDuff.Mode getProgressBackgroundTintMode(); @@ -58422,14 +58511,14 @@ package android.widget { method @Nullable public android.graphics.BlendMode getProgressTintBlendMode(); method @Nullable public android.content.res.ColorStateList getProgressTintList(); method @Nullable public android.graphics.PorterDuff.Mode getProgressTintMode(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public int getSecondaryProgress(); + method public int getSecondaryProgress(); method @Nullable public android.graphics.BlendMode getSecondaryProgressTintBlendMode(); method @Nullable public android.content.res.ColorStateList getSecondaryProgressTintList(); method @Nullable public android.graphics.PorterDuff.Mode getSecondaryProgressTintMode(); method public final void incrementProgressBy(int); method public final void incrementSecondaryProgressBy(int); method public boolean isAnimating(); - method @android.view.ViewDebug.ExportedProperty(category="progress") public boolean isIndeterminate(); + method public boolean isIndeterminate(); method public void onRestoreInstanceState(android.os.Parcelable); method public android.os.Parcelable onSaveInstanceState(); method public void setIndeterminate(boolean); @@ -58580,7 +58669,7 @@ package android.widget { method public int getRule(int); method public int[] getRules(); method public void removeRule(int); - field @android.view.ViewDebug.ExportedProperty(category="layout") public boolean alignWithParent; + field public boolean alignWithParent; } public class RemoteViews implements android.view.LayoutInflater.Filter android.os.Parcelable { @@ -59139,8 +59228,8 @@ package android.widget { ctor public TableRow.LayoutParams(int); ctor public TableRow.LayoutParams(android.view.ViewGroup.LayoutParams); ctor public TableRow.LayoutParams(android.view.ViewGroup.MarginLayoutParams); - field @android.view.ViewDebug.ExportedProperty(category="layout") public int column; - field @android.view.ViewDebug.ExportedProperty(category="layout") public int span; + field public int column; + field public int span; } @android.widget.RemoteViews.RemoteView public class TextClock extends android.widget.TextView { @@ -59148,8 +59237,8 @@ package android.widget { ctor public TextClock(android.content.Context, android.util.AttributeSet); ctor public TextClock(android.content.Context, android.util.AttributeSet, int); ctor public TextClock(android.content.Context, android.util.AttributeSet, int, int); - method @android.view.ViewDebug.ExportedProperty public CharSequence getFormat12Hour(); - method @android.view.ViewDebug.ExportedProperty public CharSequence getFormat24Hour(); + method public CharSequence getFormat12Hour(); + method public CharSequence getFormat24Hour(); method public String getTimeZone(); method public boolean is24HourModeEnabled(); method public void refreshTime(); @@ -59208,7 +59297,7 @@ package android.widget { method protected boolean getDefaultEditable(); method protected android.text.method.MovementMethod getDefaultMovementMethod(); method public android.text.Editable getEditableText(); - method @android.view.ViewDebug.ExportedProperty public android.text.TextUtils.TruncateAt getEllipsize(); + method public android.text.TextUtils.TruncateAt getEllipsize(); method public CharSequence getError(); method public int getExtendedPaddingBottom(); method public int getExtendedPaddingTop(); @@ -59219,7 +59308,7 @@ package android.widget { method public boolean getFreezesText(); method public int getGravity(); method @ColorInt public int getHighlightColor(); - method @android.view.ViewDebug.CapturedViewProperty public CharSequence getHint(); + method public CharSequence getHint(); method public final android.content.res.ColorStateList getHintTextColors(); method public int getHyphenationFrequency(); method public int getImeActionId(); @@ -59255,14 +59344,14 @@ package android.widget { method public android.text.TextPaint getPaint(); method public int getPaintFlags(); method public String getPrivateImeOptions(); - method @android.view.ViewDebug.ExportedProperty(category="text") public int getSelectionEnd(); - method @android.view.ViewDebug.ExportedProperty(category="text") public int getSelectionStart(); + method public int getSelectionEnd(); + method public int getSelectionStart(); method @ColorInt public int getShadowColor(); method public float getShadowDx(); method public float getShadowDy(); method public float getShadowRadius(); method public final boolean getShowSoftInputOnFocus(); - method @android.view.ViewDebug.CapturedViewProperty public CharSequence getText(); + method public CharSequence getText(); method @NonNull public android.view.textclassifier.TextClassifier getTextClassifier(); method public final android.content.res.ColorStateList getTextColors(); method @Nullable public android.graphics.drawable.Drawable getTextCursorDrawable(); @@ -59274,7 +59363,7 @@ package android.widget { method @Nullable public android.graphics.drawable.Drawable getTextSelectHandle(); method @Nullable public android.graphics.drawable.Drawable getTextSelectHandleLeft(); method @Nullable public android.graphics.drawable.Drawable getTextSelectHandleRight(); - method @android.view.ViewDebug.ExportedProperty(category="text") public float getTextSize(); + method public float getTextSize(); method public int getTextSizeUnit(); method public int getTotalPaddingBottom(); method public int getTotalPaddingEnd(); diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index 256bf33f9cc8..9e66800f13c3 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -7849,6 +7849,7 @@ package android.provider { field public static final String NAMESPACE_AUTOFILL = "autofill"; field public static final String NAMESPACE_BIOMETRICS = "biometrics"; field public static final String NAMESPACE_BLOBSTORE = "blobstore"; + field public static final String NAMESPACE_BLUETOOTH = "bluetooth"; field public static final String NAMESPACE_CONNECTIVITY = "connectivity"; field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; field @Deprecated public static final String NAMESPACE_DEX_BOOT = "dex_boot"; @@ -8648,7 +8649,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(@Nullable String, @Nullable String) throws java.lang.IllegalArgumentException, java.lang.NumberFormatException, java.lang.UnsupportedOperationException; + method public int encodeSmdxSubjectAndReasonCode(@Nullable String, @Nullable 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); @@ -9085,7 +9086,7 @@ package android.telecom { } public static class CallScreeningService.CallResponse.Builder { - method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean); } public abstract class Conference extends android.telecom.Conferenceable { @@ -9541,85 +9542,6 @@ package android.telephony { 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(); @@ -11395,6 +11317,7 @@ 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 addServiceAnnouncement(int, @NonNull byte[]); 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; diff --git a/non-updatable-api/system-lint-baseline.txt b/non-updatable-api/system-lint-baseline.txt index 2829243e830b..395ddc16913d 100644 --- a/non-updatable-api/system-lint-baseline.txt +++ b/non-updatable-api/system-lint-baseline.txt @@ -1,74 +1,88 @@ // Baseline format: 1.0 ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions(): - Method should return Collection<CharSequence> (or subclass) instead of raw array; was `java.lang.CharSequence[]` + + + +BuilderSetStyle: android.net.IpSecTransform.Builder#buildTunnelModeTransform(java.net.InetAddress, android.net.IpSecManager.SecurityParameterIndex): + Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.IpSecTransform.Builder.buildTunnelModeTransform(java.net.InetAddress,android.net.IpSecManager.SecurityParameterIndex) GenericException: android.app.prediction.AppPredictor#finalize(): - Methods must not throw generic exceptions (`java.lang.Throwable`) + GenericException: android.hardware.location.ContextHubClient#finalize(): - Methods must not throw generic exceptions (`java.lang.Throwable`) + GenericException: android.net.IpSecManager.IpSecTunnelInterface#finalize(): - Methods must not throw generic exceptions (`java.lang.Throwable`) + GenericException: android.service.autofill.augmented.FillWindow#finalize(): - Methods must not throw generic exceptions (`java.lang.Throwable`) + KotlinKeyword: android.app.Notification#when: - Avoid field names that are Kotlin hard keywords ("when"); see https://android.github.io/kotlin-guides/interop.html#no-hard-keywords + + + +MissingGetterMatchingBuilder: android.security.keystore.KeyGenParameterSpec.Builder#setUid(int): + android.security.keystore.KeyGenParameterSpec does not declare a `getUid()` method matching method android.security.keystore.KeyGenParameterSpec.Builder.setUid(int) +MissingGetterMatchingBuilder: android.service.autofill.Dataset.Builder#setFieldInlinePresentation(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, java.util.regex.Pattern, android.service.autofill.InlinePresentation): + android.service.autofill.Dataset does not declare a `getFieldInlinePresentation()` method matching method android.service.autofill.Dataset.Builder.setFieldInlinePresentation(android.view.autofill.AutofillId,android.view.autofill.AutofillValue,java.util.regex.Pattern,android.service.autofill.InlinePresentation) +MissingGetterMatchingBuilder: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean): + android.telecom.CallScreeningService.CallResponse does not declare a `shouldScreenCallViaAudioProcessing()` method matching method android.telecom.CallScreeningService.CallResponse.Builder.setShouldScreenCallViaAudioProcessing(boolean) +MissingGetterMatchingBuilder: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String): + android.telephony.mbms.DownloadRequest does not declare a `getServiceId()` method matching method android.telephony.mbms.DownloadRequest.Builder.setServiceId(String) MissingNullability: android.media.soundtrigger.SoundTriggerDetectionService#onUnbind(android.content.Intent) parameter #0: - Missing nullability on parameter `intent` in method `onUnbind` + MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #0: - Missing nullability on parameter `inputId` in method `onEvent` + MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #1: - Missing nullability on parameter `eventType` in method `onEvent` + MissingNullability: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle) parameter #2: - Missing nullability on parameter `eventArgs` in method `onEvent` + MissingNullability: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context) parameter #0: - Missing nullability on parameter `base` in method `attachBaseContext` + MissingNullability: android.provider.ContactsContract.MetadataSync#CONTENT_URI: - Missing nullability on field `CONTENT_URI` in class `class android.provider.ContactsContract.MetadataSync` + MissingNullability: android.provider.ContactsContract.MetadataSync#METADATA_AUTHORITY_URI: - Missing nullability on field `METADATA_AUTHORITY_URI` in class `class android.provider.ContactsContract.MetadataSync` + MissingNullability: android.provider.ContactsContract.MetadataSyncState#CONTENT_URI: - Missing nullability on field `CONTENT_URI` in class `class android.provider.ContactsContract.MetadataSyncState` + MissingNullability: android.provider.SearchIndexablesProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #0: - Missing nullability on parameter `context` in method `attachInfo` + MissingNullability: android.provider.SearchIndexablesProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo) parameter #1: - Missing nullability on parameter `info` in method `attachInfo` + MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#onUnbind(android.content.Intent) parameter #0: - Missing nullability on parameter `intent` in method `onUnbind` + MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0: - Missing nullability on parameter `fd` in method `dump` + MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1: - Missing nullability on parameter `pw` in method `dump` + MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2: - Missing nullability on parameter `args` in method `dump` + MissingNullability: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context) parameter #0: - Missing nullability on parameter `base` in method `attachBaseContext` + MissingNullability: android.telephony.NetworkService#onUnbind(android.content.Intent) parameter #0: - Missing nullability on parameter `intent` in method `onUnbind` + MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringDaily(java.time.ZonedDateTime) parameter #0: - Missing nullability on parameter `start` in method `createRecurringDaily` + MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringMonthly(java.time.ZonedDateTime) parameter #0: - Missing nullability on parameter `start` in method `createRecurringMonthly` + MissingNullability: android.telephony.SubscriptionPlan.Builder#createRecurringWeekly(java.time.ZonedDateTime) parameter #0: - Missing nullability on parameter `start` in method `createRecurringWeekly` + MissingNullability: android.telephony.data.DataService#onUnbind(android.content.Intent) parameter #0: - Missing nullability on parameter `intent` in method `onUnbind` + MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String): - Missing nullability on method `setServiceId` return + MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0: - Missing nullability on parameter `serviceId` in method `setServiceId` + ProtectedMember: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context): - Protected methods not allowed; must be public: method android.printservice.recommendation.RecommendationService.attachBaseContext(android.content.Context)} + ProtectedMember: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]): - Protected methods not allowed; must be public: method android.service.contentcapture.ContentCaptureService.dump(java.io.FileDescriptor,java.io.PrintWriter,String[])} + ProtectedMember: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context): - Protected methods not allowed; must be public: method android.service.notification.NotificationAssistantService.attachBaseContext(android.content.Context)} + SamShouldBeLast: android.accounts.AccountManager#addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler): @@ -168,7 +182,7 @@ SamShouldBeLast: android.media.AudioRecordingMonitor#registerAudioRecordingCallb SamShouldBeLast: android.media.AudioRouting#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler): SamShouldBeLast: android.media.AudioTrack#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler): - SAM-compatible parameters (such as parameter 1, "listener", in android.media.AudioTrack.addOnRoutingChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions + SamShouldBeLast: android.media.MediaRecorder#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler): SamShouldBeLast: android.media.MediaRecorder#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback): diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp index 32b33a758535..8598f74e1441 100644 --- a/packages/CarSystemUI/Android.bp +++ b/packages/CarSystemUI/Android.bp @@ -49,7 +49,7 @@ android_library { "androidx.lifecycle_lifecycle-extensions", "SystemUI-tags", "SystemUI-proto", - "dagger2-2.19", + "dagger2", "//external/kotlinc:kotlin-annotations", ], @@ -59,7 +59,7 @@ android_library { manifest: "AndroidManifest.xml", - plugins: ["dagger2-compiler-2.19"], + plugins: ["dagger2-compiler"], } @@ -104,7 +104,7 @@ android_library { "mockito-target-inline-minus-junit4", "testables", "truth-prebuilt", - "dagger2-2.19", + "dagger2", "//external/kotlinc:kotlin-annotations", ], libs: [ @@ -118,7 +118,7 @@ android_library { "com.android.systemui", ], - plugins: ["dagger2-compiler-2.19"], + plugins: ["dagger2-compiler"], } android_app { @@ -157,7 +157,7 @@ android_app { kotlincflags: ["-Xjvm-default=enable"], - plugins: ["dagger2-compiler-2.19"], + plugins: ["dagger2-compiler"], required: ["privapp_whitelist_com.android.systemui"], } diff --git a/packages/CarrierDefaultApp/OWNERS b/packages/CarrierDefaultApp/OWNERS index 0d8e69b447e8..56688409bf78 100644 --- a/packages/CarrierDefaultApp/OWNERS +++ b/packages/CarrierDefaultApp/OWNERS @@ -1,8 +1,8 @@ +set noparent tgunn@google.com breadley@google.com hallliu@google.com rgreenwalt@google.com -mpq@google.com amitmahajan@google.com fionaxu@google.com jackyu@google.com @@ -12,3 +12,6 @@ shuoq@google.com refuhoo@google.com nazaninb@google.com sarahchin@google.com +dbright@google.com +xiaotonj@google.com + diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java index 50542818e0d7..6fab9e4641b6 100644 --- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java +++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java @@ -106,6 +106,7 @@ public class CaptivePortalLoginActivity extends Activity { webSettings.setSupportZoom(true); webSettings.setBuiltInZoomControls(true); webSettings.setDomStorageEnabled(true); + webSettings.setAllowFileAccess(false); mWebViewClient = new MyWebViewClient(); mWebView.setWebViewClient(mWebViewClient); mWebView.setWebChromeClient(new MyWebChromeClient()); diff --git a/packages/CtsShim/Android.bp b/packages/CtsShim/Android.bp index 7728464f8652..49608b3856e0 100644 --- a/packages/CtsShim/Android.bp +++ b/packages/CtsShim/Android.bp @@ -43,6 +43,16 @@ android_app_import { }, }, presigned: true, + + apex_available: [ + "//apex_available:platform", + "com.android.apex.cts.shim.v1", + "com.android.apex.cts.shim.v2", + "com.android.apex.cts.shim.v2_legacy", + "com.android.apex.cts.shim.v2_no_hashtree", + "com.android.apex.cts.shim.v2_sdk_target_p", + "com.android.apex.cts.shim.v3", + ], } //########################################################## @@ -71,4 +81,14 @@ android_app_import { }, }, presigned: true, + + apex_available: [ + "//apex_available:platform", + "com.android.apex.cts.shim.v1", + "com.android.apex.cts.shim.v2", + "com.android.apex.cts.shim.v2_legacy", + "com.android.apex.cts.shim.v2_no_hashtree", + "com.android.apex.cts.shim.v2_sdk_target_p", + "com.android.apex.cts.shim.v3", + ], } diff --git a/packages/CtsShim/build/jni/Android.bp b/packages/CtsShim/build/jni/Android.bp index 44775828e535..4a1973cc0b46 100644 --- a/packages/CtsShim/build/jni/Android.bp +++ b/packages/CtsShim/build/jni/Android.bp @@ -17,6 +17,7 @@ cc_library_shared { name: "libshim_jni", srcs: ["Shim.c"], + header_libs: ["jni_headers"], sdk_version: "24", apex_available: [ "//apex_available:platform", diff --git a/packages/InputDevices/res/raw/keyboard_layout_belarusian.kcm b/packages/InputDevices/res/raw/keyboard_layout_belarusian.kcm new file mode 100644 index 000000000000..3deb9dd14bd4 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_belarusian.kcm @@ -0,0 +1,343 @@ +# 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. + +# Belarusian keyboard layout. +# This is a typical Belarusian PC keyboard layout. +# As an added convenience, English characters are accessible using ralt (Alt Gr). +# + +type OVERLAY +map key 86 BACKSLASH +### ROW 1 +key GRAVE { + label: '\u0401' + base: '\u0451' + shift, capslock: '\u0401' + ralt: '`' + ralt+shift: '~' +} +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '!' +} +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} +key 3 { + label: '3' + base: '3' + shift: '\u2116' + ralt: '#' +} +key 4 { + label: '4' + base: '4' + shift: ';' + ralt: '$' +} +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '%' +} +key 6 { + label: '6' + base: '6' + shift: ':' + ralt: '^' +} +key 7 { + label: '7' + base: '7' + shift: '?' + ralt: '&' +} +key 8 { + label: '8' + base: '8' + shift: '*' + ralt: '*' +} +key 9 { + label: '9' + base: '9' + shift: '(' + ralt: '(' +} +key 0 { + label: '0' + base: '0' + shift: ')' + ralt: ')' +} +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '-' + ralt+shift: '_' +} +key EQUALS { + label: '=' + base: '=' + shift: '+' + ralt: '=' + ralt+shift: '+' +} +### ROW 2 +key Q { + label: '\u0419' + base: '\u0439' + shift, capslock: '\u0419' + ralt: 'q' + ralt+shift, ralt+capslock: 'Q' +} +key W { + label: '\u0426' + base: '\u0446' + shift, capslock: '\u0426' + ralt: 'w' + ralt+shift, ralt+capslock: 'W' +} +key E { + label: '\u0423' + base: '\u0443' + shift, capslock: '\u0423' + ralt: 'e' + ralt+shift, ralt+capslock: 'E' +} +key R { + label: '\u041a' + base: '\u043a' + shift, capslock: '\u041a' + ralt: 'r' + ralt+shift, ralt+capslock: 'R' +} +key T { + label: '\u0415' + base: '\u0435' + shift, capslock: '\u0415' + ralt: 't' + ralt+shift, ralt+capslock: 'T' +} +key Y { + label: '\u041d' + base: '\u043d' + shift, capslock: '\u041d' + ralt: 'y' + ralt+shift, ralt+capslock: 'Y' +} +key U { + label: '\u0413' + base: '\u0433' + shift, capslock: '\u0413' + ralt: 'u' + ralt+shift, ralt+capslock: 'U' +} +key I { + label: '\u0428' + base: '\u0448' + shift, capslock: '\u0428' + ralt: 'i' + ralt+shift, ralt+capslock: 'I' +} +key O { + label: '\u040E' + base: '\u045E' + shift, capslock: '\u040E' + ralt: 'o' + ralt+shift, ralt+capslock: 'O' +} +key P { + label: '\u0417' + base: '\u0437' + shift, capslock: '\u0417' + ralt: 'p' + ralt+shift, ralt+capslock: 'P' +} +key LEFT_BRACKET { + label: '\u0425' + base: '\u0445' + shift, capslock: '\u0425' + ralt: '[' + ralt+shift: '{' +} +key RIGHT_BRACKET { + label: '\u0027' + base: '\u0027' + shift, capslock: '\u0027' + ralt: ']' + ralt+shift: '}' +} +### ROW 3 +key A { + label: '\u0424' + base: '\u0444' + shift, capslock: '\u0424' + ralt: 'a' + ralt+shift, ralt+capslock: 'A' +} +key S { + label: '\u042b' + base: '\u044b' + shift, capslock: '\u042b' + ralt: 's' + ralt+shift, ralt+capslock: 'S' +} +key D { + label: '\u0412' + base: '\u0432' + shift, capslock: '\u0412' + ralt: 'd' + ralt+shift, ralt+capslock: 'D' +} +key F { + label: '\u0410' + base: '\u0430' + shift, capslock: '\u0410' + ralt: 'f' + ralt+shift, ralt+capslock: 'F' +} +key G { + label: '\u041f' + base: '\u043f' + shift, capslock: '\u041f' + ralt: 'g' + ralt+shift, ralt+capslock: 'G' +} +key H { + label: '\u0420' + base: '\u0440' + shift, capslock: '\u0420' + ralt: 'h' + ralt+shift, ralt+capslock: 'H' +} +key J { + label: '\u041e' + base: '\u043e' + shift, capslock: '\u041e' + ralt: 'j' + ralt+shift, ralt+capslock: 'J' +} +key K { + label: '\u041b' + base: '\u043b' + shift, capslock: '\u041b' + ralt: 'k' + ralt+shift, ralt+capslock: 'K' +} +key L { + label: '\u0414' + base: '\u0434' + shift, capslock: '\u0414' + ralt: 'l' + ralt+shift, ralt+capslock: 'L' +} +key SEMICOLON { + label: '\u0416' + base: '\u0436' + shift, capslock: '\u0416' + ralt: ';' + ralt+shift: ':' +} +key APOSTROPHE { + label: '\u042d' + base: '\u044d' + shift, capslock: '\u042d' + ralt: '\'' + ralt+shift: '"' +} +key BACKSLASH { + label: '\\' + base: '\\' + shift: '/' + ralt: '|' +} +### ROW 4 +key Z { + label: '\u042f' + base: '\u044f' + shift, capslock: '\u042f' + ralt: 'z' + ralt+shift, ralt+capslock: 'Z' +} +key X { + label: '\u0427' + base: '\u0447' + shift, capslock: '\u0427' + ralt: 'x' + ralt+shift, ralt+capslock: 'X' +} +key C { + label: '\u0421' + base: '\u0441' + shift, capslock: '\u0421' + ralt: 'c' + ralt+shift, ralt+capslock: 'C' +} +key V { + label: '\u041c' + base: '\u043c' + shift, capslock: '\u041c' + ralt: 'v' + ralt+shift, ralt+capslock: 'V' +} +key B { + label: '\u0406' + base: '\u0456' + shift, capslock: '\u0406' + ralt: 'b' + ralt+shift, ralt+capslock: 'B' +} +key N { + label: '\u0422' + base: '\u0442' + shift, capslock: '\u0422' + ralt: 'n' + ralt+shift, ralt+capslock: 'N' +} +key M { + label: '\u042c' + base: '\u044c' + shift, capslock: '\u042c' + ralt: 'm' + ralt+shift, ralt+capslock: 'M' +} +key COMMA { + label: '\u0411' + base: '\u0431' + shift, capslock: '\u0411' + ralt: ',' + ralt+shift: '<' +} +key PERIOD { + label: '\u042e' + base: '\u044e' + shift, capslock: '\u042e' + ralt: '.' + ralt+shift: '>' +} +key SLASH { + label: '.' + base: '.' + shift: ',' + ralt: '/' + ralt+shift: '?' +} diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml index 5fdc4a6a4505..ac70c945297b 100644 --- a/packages/InputDevices/res/values/strings.xml +++ b/packages/InputDevices/res/values/strings.xml @@ -128,4 +128,7 @@ <!-- Polish keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_polish">Polish</string> + + <!-- Belarusian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_belarusian">Belarusian</string> </resources> diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml index 1807aeae0da3..68ca093e45b1 100644 --- a/packages/InputDevices/res/xml/keyboard_layouts.xml +++ b/packages/InputDevices/res/xml/keyboard_layouts.xml @@ -163,4 +163,8 @@ <keyboard-layout android:name="keyboard_layout_polish" android:label="@string/keyboard_layout_polish" android:keyboardLayout="@raw/keyboard_layout_polish" /> + + <keyboard-layout android:name="keyboard_layout_belarusian" + android:label="@string/keyboard_layout_belarusian" + android:keyboardLayout="@raw/keyboard_layout_belarusian" /> </keyboard-layouts> diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp index 9420954748c4..75bd32ec0301 100644 --- a/packages/PackageInstaller/Android.bp +++ b/packages/PackageInstaller/Android.bp @@ -20,6 +20,7 @@ android_app { certificate: "platform", privileged: true, platform_apis: true, + rename_resources_package: false, static_libs: [ "xz-java", diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS index d7bd6a49d75b..8eafbdfdf6bc 100644 --- a/packages/SettingsLib/OWNERS +++ b/packages/SettingsLib/OWNERS @@ -5,10 +5,8 @@ emilychuang@google.com evanlaird@google.com juliacr@google.com leifhendrik@google.com -rafftsai@google.com tmfang@google.com virgild@google.com -zhfan@google.com # Exempt resource files (because they are in a flat directory and too hard to manage via OWNERS) per-file *.xml=* diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index db219c9ce74e..287f80472478 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -688,8 +688,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/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java index d48aa246ecba..e5fd0ba5d9bc 100644 --- a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java +++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java @@ -32,12 +32,11 @@ import androidx.annotation.VisibleForTesting; import androidx.core.text.BidiFormatter; import androidx.core.text.TextDirectionHeuristicsCompat; +import com.android.i18n.timezone.CountryTimeZones; +import com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping; +import com.android.i18n.timezone.TimeZoneFinder; import com.android.settingslib.R; -import libcore.timezone.CountryTimeZones; -import libcore.timezone.CountryTimeZones.TimeZoneMapping; -import libcore.timezone.TimeZoneFinder; - import org.xmlpull.v1.XmlPullParserException; import java.util.ArrayList; @@ -242,7 +241,16 @@ public class ZoneGetter { final TimeZoneNames.NameType nameType = tz.inDaylightTime(now) ? TimeZoneNames.NameType.LONG_DAYLIGHT : TimeZoneNames.NameType.LONG_STANDARD; - return names.getDisplayName(tz.getID(), nameType, now.getTime()); + return names.getDisplayName(getCanonicalZoneId(tz), nameType, now.getTime()); + } + + private static String getCanonicalZoneId(TimeZone timeZone) { + final String id = timeZone.getID(); + final String canonicalId = android.icu.util.TimeZone.getCanonicalID(id); + if (canonicalId != null) { + return canonicalId; + } + return id; } private static void appendWithTtsSpan(SpannableStringBuilder builder, CharSequence content, diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java index ac7a12187fd6..121f5492a5ab 100644 --- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java +++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java @@ -38,7 +38,10 @@ public class LicenseHtmlLoaderCompat extends AsyncLoaderCompat<File> { "/odm/etc/NOTICE.xml.gz", "/oem/etc/NOTICE.xml.gz", "/product/etc/NOTICE.xml.gz", - "/system_ext/etc/NOTICE.xml.gz"}; + "/system_ext/etc/NOTICE.xml.gz", + "/vendor_dlkm/etc/NOTICE.xml.gz", + "/odm_dlkm/etc/NOTICE.xml.gz", + }; static final String NOTICE_HTML_FILE_NAME = "NOTICE.html"; private final Context mContext; diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java index d7e76a14c768..b7ae3dca5c16 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java @@ -214,6 +214,9 @@ public class WifiStatusTracker { } private void updateStatusLabel() { + if (mWifiManager == null) { + return; + } NetworkCapabilities networkCapabilities; final Network currentWifiNetwork = mWifiManager.getCurrentNetwork(); if (currentWifiNetwork != null && currentWifiNetwork.equals(mDefaultNetwork)) { diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index aae72e55b549..1d25b1aafd70 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -1413,9 +1413,6 @@ class SettingsProtoDumpUtil { Settings.Global.SYS_STORAGE_CACHE_MAX_BYTES, GlobalSettingsProto.Sys.STORAGE_CACHE_MAX_BYTES); dumpSetting(s, p, - Settings.Global.SYS_VDSO, - GlobalSettingsProto.Sys.VDSO); - dumpSetting(s, p, Settings.Global.SYS_UIDCPUPOWER, GlobalSettingsProto.Sys.UIDCPUPOWER); p.end(sysToken); diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index eb7ad72eb1ba..b90b9c1208ae 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -464,7 +464,6 @@ public class SettingsBackupTest { Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES, Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES, Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE, - Settings.Global.SYS_VDSO, Settings.Global.SYS_UIDCPUPOWER, Settings.Global.SYS_TRACED, Settings.Global.FPS_DEVISOR, diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 3100e2fce085..7f7afcbf11f5 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -370,6 +370,7 @@ <receiver android:name=".BugreportRequestedReceiver" + android:exported="true" android:permission="android.permission.TRIGGER_SHELL_BUGREPORT"> <intent-filter> <action android:name="com.android.internal.intent.action.BUGREPORT_REQUESTED" /> @@ -378,6 +379,7 @@ <receiver android:name=".HeapDumpReceiver" + android:exported="true" android:permission="android.permission.DUMP"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> diff --git a/packages/Shell/tests/AndroidManifest.xml b/packages/Shell/tests/AndroidManifest.xml index e845ef95b28e..23877fd7a66a 100644 --- a/packages/Shell/tests/AndroidManifest.xml +++ b/packages/Shell/tests/AndroidManifest.xml @@ -27,6 +27,7 @@ android:label="ActionSendMultipleConsumer" android:theme="@android:style/Theme.NoDisplay" android:noHistory="true" + android:exported="true" android:excludeFromRecents="true"> <intent-filter> <action android:name="android.intent.action.SEND_MULTIPLE" /> diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 7a27676237a1..6ecf303c6dc8 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -68,14 +68,14 @@ android_library { "iconloader_base", "SystemUI-tags", "SystemUI-proto", - "dagger2-2.19", + "dagger2", "jsr330" ], manifest: "AndroidManifest.xml", kotlincflags: ["-Xjvm-default=enable"], - plugins: ["dagger2-compiler-2.19"], + plugins: ["dagger2-compiler"], } filegroup { @@ -139,7 +139,7 @@ android_library { "mockito-target-extended-minus-junit4", "testables", "truth-prebuilt", - "dagger2-2.19", + "dagger2", "jsr330" ], libs: [ @@ -151,7 +151,7 @@ android_library { "--extra-packages", "com.android.systemui", ], - plugins: ["dagger2-compiler-2.19"], + plugins: ["dagger2-compiler"], } android_app { diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS index 28491d6e7e1f..17d2f9c89c30 100644 --- a/packages/SystemUI/OWNERS +++ b/packages/SystemUI/OWNERS @@ -44,7 +44,7 @@ winsonc@google.com zakcohen@google.com #Android Auto -stenning@google.com +hseog@google.com #Android TV rgl@google.com diff --git a/packages/SystemUI/docs/dagger.md b/packages/SystemUI/docs/dagger.md index c440fba10135..bb68647ceb00 100644 --- a/packages/SystemUI/docs/dagger.md +++ b/packages/SystemUI/docs/dagger.md @@ -206,11 +206,31 @@ public CustomView(@Named(VIEW_CONTEXT) Context themedViewContext, AttributeSet a ## Updating Dagger2 +We depend on the Dagger source found in external/dagger2. We should automatically pick up on updates +when that repository is updated. + +*Deprecated:* + Binaries can be downloaded from https://repo1.maven.org/maven2/com/google/dagger/ and then loaded into [/prebuilts/tools/common/m2/repository/com/google/dagger/](http://cs/android/prebuilts/tools/common/m2/repository/com/google/dagger/) +The following commands should work, substituting in the version that you are looking for: + +```` +cd prebuilts/tools/common/m2/repository/com/google/dagger/ + +wget -r -np -nH --cut-dirs=4 -erobots=off -R "index.html*" -U "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" https://repo1.maven.org/maven2/com/google/dagger/dagger/2.28.1/ + +wget -r -np -nH --cut-dirs=4 -erobots=off -R "index.html*" -U "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" https://repo1.maven.org/maven2/com/google/dagger/dagger-compiler/2.28.1/ + +wget -r -np -nH --cut-dirs=4 -erobots=off -R "index.html*" -U "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" https://repo1.maven.org/maven2/com/google/dagger/dagger-spi/2.28.1/ + +wget -r -np -nH --cut-dirs=4 -erobots=off -R "index.html*" -U "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" https://repo1.maven.org/maven2/com/google/dagger/dagger-producers/2.28.1/ +```` +Then update `prebuilts/tools/common/m2/Android.bp` to point at your new jars. + ## TODO List - Eliminate usages of Dependency#get 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/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java index 1e99a7b733e2..f683a639af10 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java @@ -312,6 +312,7 @@ public class SystemServicesModule { @Provides @Singleton + @Nullable static WifiManager provideWifiManager(Context context) { return context.getSystemService(WifiManager.class); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index 8ba60840a666..7ae8fbc928a6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -66,11 +66,13 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements dialog.setTitle(com.android.internal.R.string.data_saver_enable_title); dialog.setMessage(com.android.internal.R.string.data_saver_description); dialog.setPositiveButton(com.android.internal.R.string.data_saver_enable_button, - (OnClickListener) (dialogInterface, which) -> toggleDataSaver()); + (OnClickListener) (dialogInterface, which) -> { + toggleDataSaver(); + Prefs.putBoolean(mContext, Prefs.Key.QS_DATA_SAVER_DIALOG_SHOWN, true); + }); dialog.setNegativeButton(com.android.internal.R.string.cancel, null); dialog.setShowForAllUsers(true); dialog.show(); - Prefs.putBoolean(mContext, Prefs.Key.QS_DATA_SAVER_DIALOG_SHOWN, true); } private void toggleDataSaver() { 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 4bee075ac63b..7da913592286 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java @@ -39,6 +39,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 BroadcastDispatcher mBroadcastDispatcher; @@ -109,8 +111,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/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java index 673aa3903156..85a3bc91dc7e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java @@ -142,7 +142,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { .expandableNotificationRow(row) .notificationEntry(entry) .onDismissRunnable(onDismissRunnable) - .rowContentBindStage(mRowContentBindStage) .onExpandClickListener(mPresenter) .build(); ExpandableNotificationRowController rowController = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java index 9846f2dcd170..321656df504a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java @@ -25,7 +25,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController; -import com.android.systemui.statusbar.notification.row.RowContentBindStage; import com.android.systemui.statusbar.phone.StatusBar; import dagger.Binds; @@ -57,8 +56,6 @@ public interface ExpandableNotificationRowComponent { @BindsInstance Builder onDismissRunnable(@DismissRunnable Runnable runnable); @BindsInstance - Builder rowContentBindStage(RowContentBindStage rowContentBindStage); - @BindsInstance Builder onExpandClickListener(ExpandableNotificationRow.OnExpandClickListener presenter); ExpandableNotificationRowComponent build(); } 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 f41a27cf4c64..4ac3a9b6b40a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -24,6 +24,7 @@ import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_NO import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_OUT; import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE; +import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -175,7 +176,7 @@ public class NetworkControllerImpl extends BroadcastReceiver public NetworkControllerImpl(Context context, @Background Looper bgLooper, DeviceProvisionedController deviceProvisionedController, BroadcastDispatcher broadcastDispatcher, ConnectivityManager connectivityManager, - TelephonyManager telephonyManager, WifiManager wifiManager, + TelephonyManager telephonyManager, @Nullable WifiManager wifiManager, NetworkScoreManager networkScoreManager) { this(context, connectivityManager, telephonyManager, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt index 8948fd07379b..da77fbcea294 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt @@ -64,8 +64,8 @@ class NotificationSectionsFeatureManagerTest : SysuiTestCase() { DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_USE_PEOPLE_FILTERING, "false", false) assertFalse("People filtering should be disabled", manager!!.isFilteringEnabled()) - assertTrue("Expecting 2 buckets when people filtering is disabled", - manager!!.getNumberOfBuckets() == 2) + assertTrue("Expecting 5 buckets when people filtering is disabled", + manager!!.getNumberOfBuckets() == 5) } @Test @@ -74,7 +74,7 @@ class NotificationSectionsFeatureManagerTest : SysuiTestCase() { DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_USE_PEOPLE_FILTERING, "true", false) assertTrue("People filtering should be enabled", manager!!.isFilteringEnabled()) - assertTrue("Expecting 5 buckets when people filtering is enabled", - manager!!.getNumberOfBuckets() == 5) + assertTrue("Expecting 6 buckets when people filtering is enabled", + manager!!.getNumberOfBuckets() == 6) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java index 3ea0e5639c71..2198edd0d8bb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java @@ -87,6 +87,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; @@ -121,8 +122,8 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { @Mock private NotificationGutsManager mGutsManager; @Mock private NotificationRemoteInputManager mRemoteInputManager; @Mock private NotificationMediaManager mNotificationMediaManager; - @Mock private ExpandableNotificationRowComponent.Builder - mExpandableNotificationRowComponentBuilder; + @Mock(answer = Answers.RETURNS_SELF) + private ExpandableNotificationRowComponent.Builder mExpandableNotificationRowComponentBuilder; @Mock private ExpandableNotificationRowComponent mExpandableNotificationRowComponent; @Mock private FalsingManager mFalsingManager; @Mock private KeyguardBypassController mKeyguardBypassController; @@ -211,21 +212,9 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { when(mExpandableNotificationRowComponentBuilder .expandableNotificationRow(viewCaptor.capture())) .thenReturn(mExpandableNotificationRowComponentBuilder); - when(mExpandableNotificationRowComponentBuilder - .notificationEntry(any())) - .thenReturn(mExpandableNotificationRowComponentBuilder); - when(mExpandableNotificationRowComponentBuilder - .onDismissRunnable(any())) - .thenReturn(mExpandableNotificationRowComponentBuilder); - when(mExpandableNotificationRowComponentBuilder - .rowContentBindStage(any())) - .thenReturn(mExpandableNotificationRowComponentBuilder); - when(mExpandableNotificationRowComponentBuilder - .onExpandClickListener(any())) - .thenReturn(mExpandableNotificationRowComponentBuilder); - when(mExpandableNotificationRowComponentBuilder.build()) .thenReturn(mExpandableNotificationRowComponent); + when(mExpandableNotificationRowComponent.getExpandableNotificationRowController()) .thenAnswer((Answer<ExpandableNotificationRowController>) invocation -> new ExpandableNotificationRowController( diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp index 12daa6142d5c..40f394a3f789 100644 --- a/packages/Tethering/Android.bp +++ b/packages/Tethering/Android.bp @@ -25,9 +25,10 @@ java_defaults { ], static_libs: [ "androidx.annotation_annotation", - "netd_aidl_interface-java", + "netd_aidl_interface-unstable-java", "netlink-client", - "networkstack-aidl-interfaces-java", + // TODO: use networkstack-client instead of just including the AIDL interface + "networkstack-aidl-interfaces-unstable-java", "android.hardware.tetheroffload.config-V1.0-java", "android.hardware.tetheroffload.control-V1.0-java", "net-utils-framework-common", diff --git a/packages/Tethering/common/TetheringLib/api/module-lib-current.txt b/packages/Tethering/common/TetheringLib/api/module-lib-current.txt index 754584e70fad..6ddb122936e7 100644 --- a/packages/Tethering/common/TetheringLib/api/module-lib-current.txt +++ b/packages/Tethering/common/TetheringLib/api/module-lib-current.txt @@ -1,24 +1,6 @@ // 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"; @@ -38,69 +20,15 @@ package android.net { 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 { @@ -109,21 +37,5 @@ package android.net { 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/src/android/net/ITetheringConnector.aidl b/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl index 8be79645bde3..cf094aac2cbe 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl +++ b/packages/Tethering/common/TetheringLib/src/android/net/ITetheringConnector.aidl @@ -22,25 +22,31 @@ import android.os.ResultReceiver; /** @hide */ oneway interface ITetheringConnector { - void tether(String iface, String callerPkg, IIntResultListener receiver); + void tether(String iface, String callerPkg, String callingAttributionTag, + IIntResultListener receiver); - void untether(String iface, String callerPkg, IIntResultListener receiver); + void untether(String iface, String callerPkg, String callingAttributionTag, + IIntResultListener receiver); - void setUsbTethering(boolean enable, String callerPkg, IIntResultListener receiver); + void setUsbTethering(boolean enable, String callerPkg, + String callingAttributionTag, IIntResultListener receiver); void startTethering(in TetheringRequestParcel request, String callerPkg, - IIntResultListener receiver); + String callingAttributionTag, IIntResultListener receiver); - void stopTethering(int type, String callerPkg, IIntResultListener receiver); + void stopTethering(int type, String callerPkg, String callingAttributionTag, + IIntResultListener receiver); void requestLatestTetheringEntitlementResult(int type, in ResultReceiver receiver, - boolean showEntitlementUi, String callerPkg); + boolean showEntitlementUi, String callerPkg, String callingAttributionTag); void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg); void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg); - void isTetheringSupported(String callerPkg, IIntResultListener receiver); + void isTetheringSupported(String callerPkg, String callingAttributionTag, + IIntResultListener receiver); - void stopAllTethering(String callerPkg, IIntResultListener receiver); + void stopAllTethering(String callerPkg, String callingAttributionTag, + IIntResultListener receiver); } diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java index 48be0d96425c..645b00001330 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java @@ -16,8 +16,6 @@ package android.net; -import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; - import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -36,7 +34,6 @@ import java.util.Objects; * @hide */ @SystemApi -@SystemApi(client = MODULE_LIBRARIES) @TestApi public final class TetheredClient implements Parcelable { @NonNull diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java index 4f053cb65c38..88e0b4253446 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java @@ -55,7 +55,6 @@ import java.util.function.Supplier; * @hide */ @SystemApi -@SystemApi(client = MODULE_LIBRARIES) @TestApi public class TetheringManager { private static final String TAG = TetheringManager.class.getSimpleName(); @@ -492,7 +491,7 @@ public class TetheringManager { return dispatcher.waitForResult((connector, listener) -> { try { - connector.tether(iface, callerPkg, listener); + connector.tether(iface, callerPkg, getAttributionTag(), listener); } catch (RemoteException e) { throw new IllegalStateException(e); } @@ -500,6 +499,13 @@ public class TetheringManager { } /** + * @return the context's attribution tag + */ + private @Nullable String getAttributionTag() { + return null; + } + + /** * Stop tethering the named interface. * * @deprecated The only usages is PanService. It uses this for legacy reasons @@ -517,7 +523,7 @@ public class TetheringManager { return dispatcher.waitForResult((connector, listener) -> { try { - connector.untether(iface, callerPkg, listener); + connector.untether(iface, callerPkg, getAttributionTag(), listener); } catch (RemoteException e) { throw new IllegalStateException(e); } @@ -544,7 +550,8 @@ public class TetheringManager { return dispatcher.waitForResult((connector, listener) -> { try { - connector.setUsbTethering(enable, callerPkg, listener); + connector.setUsbTethering(enable, callerPkg, getAttributionTag(), + listener); } catch (RemoteException e) { throw new IllegalStateException(e); } @@ -743,7 +750,8 @@ public class TetheringManager { }); } }; - getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener)); + getConnector(c -> c.startTethering(request.getParcel(), callerPkg, + getAttributionTag(), listener)); } /** @@ -783,7 +791,8 @@ public class TetheringManager { final String callerPkg = mContext.getOpPackageName(); Log.i(TAG, "stopTethering caller:" + callerPkg); - getConnector(c -> c.stopTethering(type, callerPkg, new IIntResultListener.Stub() { + getConnector(c -> c.stopTethering(type, callerPkg, getAttributionTag(), + new IIntResultListener.Stub() { @Override public void onResult(int resultCode) { // TODO: provide an API to obtain result @@ -869,7 +878,7 @@ public class TetheringManager { Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg); getConnector(c -> c.requestLatestTetheringEntitlementResult( - type, receiver, showEntitlementUi, callerPkg)); + type, receiver, showEntitlementUi, callerPkg, getAttributionTag())); } /** @@ -1320,7 +1329,7 @@ public class TetheringManager { final RequestDispatcher dispatcher = new RequestDispatcher(); final int ret = dispatcher.waitForResult((connector, listener) -> { try { - connector.isTetheringSupported(callerPkg, listener); + connector.isTetheringSupported(callerPkg, getAttributionTag(), listener); } catch (RemoteException e) { throw new IllegalStateException(e); } @@ -1343,14 +1352,15 @@ public class TetheringManager { final String callerPkg = mContext.getOpPackageName(); Log.i(TAG, "stopAllTethering caller:" + callerPkg); - getConnector(c -> c.stopAllTethering(callerPkg, new IIntResultListener.Stub() { - @Override - public void onResult(int resultCode) { - // TODO: add an API parameter to send result to caller. - // This has never been possible as stopAllTethering has always been void and never - // taken a callback object. The only indication that callers have is if the call - // results in a TETHER_STATE_CHANGE broadcast. - } - })); + getConnector(c -> c.stopAllTethering(callerPkg, getAttributionTag(), + new IIntResultListener.Stub() { + @Override + public void onResult(int resultCode) { + // TODO: add an API parameter to send result to caller. + // This has never been possible as stopAllTethering has always been void + // and never taken a callback object. The only indication that callers have + // is if the call results in a TETHER_STATE_CHANGE broadcast. + } + })); } } diff --git a/packages/Tethering/jni/android_net_util_TetheringUtils.cpp b/packages/Tethering/jni/android_net_util_TetheringUtils.cpp index 549344064405..f6eb40a842d5 100644 --- a/packages/Tethering/jni/android_net_util_TetheringUtils.cpp +++ b/packages/Tethering/jni/android_net_util_TetheringUtils.cpp @@ -18,6 +18,7 @@ #include <error.h> #include <jni.h> #include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIHelpCompat.h> #include <nativehelper/ScopedUtfChars.h> #include <net/if.h> #include <netinet/icmp6.h> diff --git a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java index 160a166b632b..aa58a4b6a320 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java @@ -15,6 +15,8 @@ */ package com.android.networkstack.tethering; +import static java.util.Arrays.asList; + import android.content.Context; import android.net.ConnectivityManager; import android.net.IpPrefix; @@ -34,9 +36,10 @@ import com.android.internal.util.IndentingPrintWriter; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Random; +import java.util.Set; /** * This class coordinate IP addresses conflict problem. @@ -60,8 +63,8 @@ public class PrivateAddressCoordinator { // Upstream monitor would be stopped when tethering is down. When tethering restart, downstream // address may be requested before coordinator get current upstream notification. To ensure // coordinator do not select conflict downstream prefix, mUpstreamPrefixMap would not be cleared - // when tethering is down. Instead coordinator would remove all depcreted upstreams from - // mUpstreamPrefixMap when tethering is starting. See #maybeRemoveDeprectedUpstreams(). + // when tethering is down. Instead tethering would remove all deprecated upstreams from + // mUpstreamPrefixMap when tethering is starting. See #maybeRemoveDeprecatedUpstreams(). private final ArrayMap<Network, List<IpPrefix>> mUpstreamPrefixMap; private final ArraySet<IpServer> mDownstreams; // IANA has reserved the following three blocks of the IP address space for private intranets: @@ -124,15 +127,16 @@ public class PrivateAddressCoordinator { mUpstreamPrefixMap.remove(network); } - private void maybeRemoveDeprectedUpstreams() { - if (!mDownstreams.isEmpty() || mUpstreamPrefixMap.isEmpty()) return; + /** + * Maybe remove deprecated upstream records, this would be called once tethering started without + * any exiting tethered downstream. + */ + public void maybeRemoveDeprecatedUpstreams() { + if (mUpstreamPrefixMap.isEmpty()) return; - final ArrayList<Network> toBeRemoved = new ArrayList<>(); - List<Network> allNetworks = Arrays.asList(mConnectivityMgr.getAllNetworks()); - for (int i = 0; i < mUpstreamPrefixMap.size(); i++) { - final Network network = mUpstreamPrefixMap.keyAt(i); - if (!allNetworks.contains(network)) toBeRemoved.add(network); - } + // Remove all upstreams that are no longer valid networks + final Set<Network> toBeRemoved = new HashSet<>(mUpstreamPrefixMap.keySet()); + toBeRemoved.removeAll(asList(mConnectivityMgr.getAllNetworks())); mUpstreamPrefixMap.removeAll(toBeRemoved); } @@ -143,8 +147,6 @@ public class PrivateAddressCoordinator { */ @Nullable public LinkAddress requestDownstreamAddress(final IpServer ipServer) { - maybeRemoveDeprectedUpstreams(); - // Address would be 192.168.[subAddress]/24. final byte[] bytes = mTetheringPrefix.getRawAddress(); final int subAddress = getRandomSubAddr(); @@ -237,7 +239,6 @@ public class PrivateAddressCoordinator { } void dump(final IndentingPrintWriter pw) { - pw.decreaseIndent(); pw.println("mUpstreamPrefixMap:"); pw.increaseIndent(); for (int i = 0; i < mUpstreamPrefixMap.size(); i++) { diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index 3695ec65d5c0..7508a653599d 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -1751,6 +1751,7 @@ public class Tethering { return; } + mPrivateAddressCoordinator.maybeRemoveDeprecatedUpstreams(); mUpstreamNetworkMonitor.startObserveAllNetworks(); // TODO: De-duplicate with updateUpstreamWanted() below. diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java index 593d04a06b93..a0198cc9c126 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java @@ -273,8 +273,9 @@ public class TetheringNotificationUpdater { mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), 0 /* requestCode */, new Intent(Settings.ACTION_TETHER_SETTINGS) - .setPackage(getSettingsPackageName(mContext.getPackageManager())), - Intent.FLAG_ACTIVITY_NEW_TASK | PendingIntent.FLAG_IMMUTABLE, + .setPackage(getSettingsPackageName(mContext.getPackageManager())) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), + PendingIntent.FLAG_IMMUTABLE, null /* options */); showNotification(R.drawable.stat_sys_tether_general, title, message, @@ -317,8 +318,9 @@ public class TetheringNotificationUpdater { mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), 0 /* requestCode */, new Intent(Settings.ACTION_TETHER_SETTINGS) - .setPackage(getSettingsPackageName(mContext.getPackageManager())), - Intent.FLAG_ACTIVITY_NEW_TASK | PendingIntent.FLAG_IMMUTABLE, + .setPackage(getSettingsPackageName(mContext.getPackageManager())) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), + PendingIntent.FLAG_IMMUTABLE, null /* options */); showNotification(R.drawable.stat_sys_tether_general, title, message, diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java index d084ca0966e8..613328d1c148 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java @@ -102,8 +102,9 @@ public class TetheringService extends Service { } @Override - public void tether(String iface, String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void tether(String iface, String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { listener.onResult(mTethering.tether(iface)); @@ -111,8 +112,9 @@ public class TetheringService extends Service { } @Override - public void untether(String iface, String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void untether(String iface, String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { listener.onResult(mTethering.untether(iface)); @@ -120,8 +122,9 @@ public class TetheringService extends Service { } @Override - public void setUsbTethering(boolean enable, String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void setUsbTethering(boolean enable, String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { listener.onResult(mTethering.setUsbTethering(enable)); @@ -130,8 +133,9 @@ public class TetheringService extends Service { @Override public void startTethering(TetheringRequestParcel request, String callerPkg, - IIntResultListener listener) { + String callingAttributionTag, IIntResultListener listener) { if (checkAndNotifyCommonError(callerPkg, + callingAttributionTag, request.exemptFromEntitlementCheck /* onlyAllowPrivileged */, listener)) { return; @@ -141,8 +145,9 @@ public class TetheringService extends Service { } @Override - public void stopTethering(int type, String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void stopTethering(int type, String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { mTethering.stopTethering(type); @@ -152,8 +157,8 @@ public class TetheringService extends Service { @Override public void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver, - boolean showEntitlementUi, String callerPkg) { - if (checkAndNotifyCommonError(callerPkg, receiver)) return; + boolean showEntitlementUi, String callerPkg, String callingAttributionTag) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, receiver)) return; mTethering.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi); } @@ -183,8 +188,9 @@ public class TetheringService extends Service { } @Override - public void stopAllTethering(String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void stopAllTethering(String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { mTethering.untetherAll(); @@ -193,8 +199,9 @@ public class TetheringService extends Service { } @Override - public void isTetheringSupported(String callerPkg, IIntResultListener listener) { - if (checkAndNotifyCommonError(callerPkg, listener)) return; + public void isTetheringSupported(String callerPkg, String callingAttributionTag, + IIntResultListener listener) { + if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return; try { listener.onResult(TETHER_ERROR_NO_ERROR); @@ -207,14 +214,18 @@ public class TetheringService extends Service { mTethering.dump(fd, writer, args); } - private boolean checkAndNotifyCommonError(String callerPkg, IIntResultListener listener) { - return checkAndNotifyCommonError(callerPkg, false /* onlyAllowPrivileged */, listener); + private boolean checkAndNotifyCommonError(final String callerPkg, + final String callingAttributionTag, final IIntResultListener listener) { + return checkAndNotifyCommonError(callerPkg, callingAttributionTag, + false /* onlyAllowPrivileged */, listener); } private boolean checkAndNotifyCommonError(final String callerPkg, - final boolean onlyAllowPrivileged, final IIntResultListener listener) { + final String callingAttributionTag, final boolean onlyAllowPrivileged, + final IIntResultListener listener) { try { - if (!hasTetherChangePermission(callerPkg, onlyAllowPrivileged)) { + if (!hasTetherChangePermission(callerPkg, callingAttributionTag, + onlyAllowPrivileged)) { listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); return true; } @@ -229,8 +240,10 @@ public class TetheringService extends Service { return false; } - private boolean checkAndNotifyCommonError(String callerPkg, ResultReceiver receiver) { - if (!hasTetherChangePermission(callerPkg, false /* onlyAllowPrivileged */)) { + private boolean checkAndNotifyCommonError(final String callerPkg, + final String callingAttributionTag, final ResultReceiver receiver) { + if (!hasTetherChangePermission(callerPkg, callingAttributionTag, + false /* onlyAllowPrivileged */)) { receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null); return true; } @@ -256,7 +269,7 @@ public class TetheringService extends Service { } private boolean hasTetherChangePermission(final String callerPkg, - final boolean onlyAllowPrivileged) { + final String callingAttributionTag, final boolean onlyAllowPrivileged) { if (onlyAllowPrivileged && !hasNetworkStackPermission()) return false; if (hasTetherPrivilegedPermission()) return true; @@ -264,11 +277,12 @@ public class TetheringService extends Service { if (mTethering.isTetherProvisioningRequired()) return false; int uid = Binder.getCallingUid(); + // If callerPkg's uid is not same as Binder.getCallingUid(), // checkAndNoteWriteSettingsOperation will return false and the operation will be // denied. return mService.checkAndNoteWriteSettingsOperation(mService, uid, callerPkg, - false /* throwException */); + callingAttributionTag, false /* throwException */); } private boolean hasTetherAccessPermission() { @@ -287,7 +301,8 @@ public class TetheringService extends Service { */ @VisibleForTesting boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid, - @NonNull String callingPackage, boolean throwException) { + @NonNull String callingPackage, @Nullable String callingAttributionTag, + boolean throwException) { return Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPackage, throwException); } diff --git a/packages/Tethering/tests/privileged/Android.bp b/packages/Tethering/tests/privileged/Android.bp new file mode 100644 index 000000000000..a0fb24603a93 --- /dev/null +++ b/packages/Tethering/tests/privileged/Android.bp @@ -0,0 +1,30 @@ +// +// 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: "TetheringPrivilegedTests", + srcs: [ + "src/**/*.java", + "src/**/*.kt", + ], + certificate: "networkstack", + platform_apis: true, + test_suites: [ + "general-tests", + "mts", + ], + compile_multilib: "both", +} diff --git a/packages/Tethering/tests/privileged/AndroidManifest.xml b/packages/Tethering/tests/privileged/AndroidManifest.xml new file mode 100644 index 000000000000..49eba15d13d4 --- /dev/null +++ b/packages/Tethering/tests/privileged/AndroidManifest.xml @@ -0,0 +1,32 @@ +<?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.privileged" + android:sharedUserId="android.uid.networkstack"> + + <!-- Note: do not add any privileged or signature permissions that are granted + to the network stack and its shared uid apps. Otherwise, the test APK will + install, but when the device is rebooted, it will bootloop because this + test APK is not in the privileged permission allow list --> + + <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.privileged" + android:label="Tethering privileged tests"> + </instrumentation> +</manifest> diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java index f4d248914aed..071a290e657b 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java @@ -27,6 +27,7 @@ import android.os.Binder; import android.os.IBinder; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; public class MockTetheringService extends TetheringService { private final Tethering mTethering = mock(Tethering.class); @@ -43,7 +44,8 @@ public class MockTetheringService extends TetheringService { @Override boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid, - @NonNull String callingPackage, boolean throwException) { + @NonNull String callingPackage, @Nullable String callingAttributionTag, + boolean throwException) { // Test this does not verify the calling package / UID, as calling package could be shell // and not match the UID. return context.checkCallingOrSelfPermission(WRITE_SETTINGS) == PERMISSION_GRANTED; diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java index 93efd49a6d69..2c0df6fc6327 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java @@ -127,10 +127,15 @@ public final class PrivateAddressCoordinatorTest { mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); } + private int getBluetoothSubAddress() { + final byte[] rawAddress = mBluetoothPrefix.getRawAddress(); + int bluetoothSubNet = rawAddress[2] & 0xff; + return (bluetoothSubNet << 8) + 0x5; + } + @Test public void testReserveBluetoothPrefix() throws Exception { - final int fakeSubAddr = 0x2c05; - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr); + when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(getBluetoothSubAddress()); LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer); final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(address); @@ -146,7 +151,7 @@ public final class PrivateAddressCoordinatorTest { LinkAddress address = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer); final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(address); - assertEquals("Wrong wifi perfix: ", predefinedPrefix, hotspotPrefix); + assertEquals("Wrong wifi prefix: ", predefinedPrefix, hotspotPrefix); when(mHotspotIpServer.getAddress()).thenReturn(address); address = mPrivateAddressCoordinator.requestDownstreamAddress( @@ -159,7 +164,7 @@ public final class PrivateAddressCoordinatorTest { address = mPrivateAddressCoordinator.requestDownstreamAddress( mUsbIpServer); final IpPrefix allowUseFreePrefix = PrefixUtils.asIpPrefix(address); - assertEquals("Fail to reselect available perfix: ", predefinedPrefix, allowUseFreePrefix); + assertEquals("Fail to reselect available prefix: ", predefinedPrefix, allowUseFreePrefix); } private LinkProperties buildUpstreamLinkProperties(boolean withIPv4, boolean withIPv6, @@ -202,7 +207,7 @@ public final class PrivateAddressCoordinatorTest { final LinkAddress hotspotAddr = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer); final IpPrefix hotspotPrefix = PrefixUtils.asIpPrefix(hotspotAddr); - assertEquals("Wrong wifi perfix: ", predefinedPrefix, hotspotPrefix); + assertEquals("Wrong wifi prefix: ", predefinedPrefix, hotspotPrefix); when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddr); // 2. Update v6 only mobile network, hotspot prefix should not be removed. List<String> testConflicts; diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java index 22d894bf471e..7bba67b05f88 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java @@ -18,7 +18,6 @@ package com.android.networkstack.tethering; import static android.Manifest.permission.ACCESS_NETWORK_STATE; import static android.Manifest.permission.TETHER_PRIVILEGED; -import static android.Manifest.permission.UPDATE_APP_OPS_STATS; import static android.Manifest.permission.WRITE_SETTINGS; import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION; @@ -62,6 +61,7 @@ import org.mockito.MockitoAnnotations; public final class TetheringServiceTest { private static final String TEST_IFACE_NAME = "test_wlan0"; private static final String TEST_CALLER_PKG = "com.android.shell"; + private static final String TEST_ATTRIBUTION_TAG = null; @Mock private ITetheringEventCallback mITetheringEventCallback; @Rule public ServiceTestRule mServiceTestRule; private Tethering mTethering; @@ -135,7 +135,7 @@ public final class TetheringServiceTest { } private void runAsWriteSettings(final TestTetheringCall test) throws Exception { - runTetheringCall(test, WRITE_SETTINGS, UPDATE_APP_OPS_STATS); + runTetheringCall(test, WRITE_SETTINGS); } private void runTetheringCall(final TestTetheringCall test, String... permissions) @@ -157,7 +157,7 @@ public final class TetheringServiceTest { private void runTether(final TestTetheringResult result) throws Exception { when(mTethering.tether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR); - mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, result); + mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); verify(mTethering).isTetheringSupported(); verify(mTethering).tether(TEST_IFACE_NAME); result.assertResult(TETHER_ERROR_NO_ERROR); @@ -166,7 +166,8 @@ public final class TetheringServiceTest { @Test public void testTether() throws Exception { runAsNoPermission((result) -> { - mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, result); + mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, + result); verify(mTethering).isTetherProvisioningRequired(); result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); verifyNoMoreInteractionsForTethering(); @@ -186,7 +187,8 @@ public final class TetheringServiceTest { private void runUnTether(final TestTetheringResult result) throws Exception { when(mTethering.untether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR); - mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, result); + mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, + result); verify(mTethering).isTetheringSupported(); verify(mTethering).untether(TEST_IFACE_NAME); result.assertResult(TETHER_ERROR_NO_ERROR); @@ -195,7 +197,8 @@ public final class TetheringServiceTest { @Test public void testUntether() throws Exception { runAsNoPermission((result) -> { - mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, result); + mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, + result); verify(mTethering).isTetherProvisioningRequired(); result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); verifyNoMoreInteractionsForTethering(); @@ -215,7 +218,8 @@ public final class TetheringServiceTest { private void runSetUsbTethering(final TestTetheringResult result) throws Exception { when(mTethering.setUsbTethering(true /* enable */)).thenReturn(TETHER_ERROR_NO_ERROR); - mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG, result); + mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG, + TEST_ATTRIBUTION_TAG, result); verify(mTethering).isTetheringSupported(); verify(mTethering).setUsbTethering(true /* enable */); result.assertResult(TETHER_ERROR_NO_ERROR); @@ -224,7 +228,8 @@ public final class TetheringServiceTest { @Test public void testSetUsbTethering() throws Exception { runAsNoPermission((result) -> { - mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG, result); + mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG, + TEST_ATTRIBUTION_TAG, result); verify(mTethering).isTetherProvisioningRequired(); result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); verifyNoMoreInteractionsForTethering(); @@ -245,7 +250,8 @@ public final class TetheringServiceTest { private void runStartTethering(final TestTetheringResult result, final TetheringRequestParcel request) throws Exception { - mTetheringConnector.startTethering(request, TEST_CALLER_PKG, result); + mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, + result); verify(mTethering).isTetheringSupported(); verify(mTethering).startTethering(eq(request), eq(result)); } @@ -256,7 +262,8 @@ public final class TetheringServiceTest { request.tetheringType = TETHERING_WIFI; runAsNoPermission((result) -> { - mTetheringConnector.startTethering(request, TEST_CALLER_PKG, result); + mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, + result); verify(mTethering).isTetherProvisioningRequired(); result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); verifyNoMoreInteractionsForTethering(); @@ -279,7 +286,8 @@ public final class TetheringServiceTest { final TetheringRequestParcel request = new TetheringRequestParcel(); request.tetheringType = TETHERING_WIFI; request.exemptFromEntitlementCheck = true; - mTetheringConnector.startTethering(request, TEST_CALLER_PKG, result); + mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, + result); result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); verifyNoMoreInteractionsForTethering(); } @@ -304,7 +312,8 @@ public final class TetheringServiceTest { } private void runStopTethering(final TestTetheringResult result) throws Exception { - mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, result); + mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, + TEST_ATTRIBUTION_TAG, result); verify(mTethering).isTetheringSupported(); verify(mTethering).stopTethering(TETHERING_WIFI); result.assertResult(TETHER_ERROR_NO_ERROR); @@ -313,7 +322,8 @@ public final class TetheringServiceTest { @Test public void testStopTethering() throws Exception { runAsNoPermission((result) -> { - mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, result); + mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, + TEST_ATTRIBUTION_TAG, result); verify(mTethering).isTetherProvisioningRequired(); result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); verifyNoMoreInteractionsForTethering(); @@ -334,7 +344,7 @@ public final class TetheringServiceTest { private void runRequestLatestTetheringEntitlementResult() throws Exception { final MyResultReceiver result = new MyResultReceiver(null); mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result, - true /* showEntitlementUi */, TEST_CALLER_PKG); + true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG); verify(mTethering).isTetheringSupported(); verify(mTethering).requestLatestTetheringEntitlementResult(eq(TETHERING_WIFI), eq(result), eq(true) /* showEntitlementUi */); @@ -345,7 +355,7 @@ public final class TetheringServiceTest { // Run as no permission. final MyResultReceiver result = new MyResultReceiver(null); mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result, - true /* showEntitlementUi */, TEST_CALLER_PKG); + true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG); verify(mTethering).isTetherProvisioningRequired(); result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); verifyNoMoreInteractions(mTethering); @@ -417,7 +427,7 @@ public final class TetheringServiceTest { } private void runStopAllTethering(final TestTetheringResult result) throws Exception { - mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, result); + mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); verify(mTethering).isTetheringSupported(); verify(mTethering).untetherAll(); result.assertResult(TETHER_ERROR_NO_ERROR); @@ -426,7 +436,7 @@ public final class TetheringServiceTest { @Test public void testStopAllTethering() throws Exception { runAsNoPermission((result) -> { - mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, result); + mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); verify(mTethering).isTetherProvisioningRequired(); result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); verifyNoMoreInteractionsForTethering(); @@ -445,7 +455,7 @@ public final class TetheringServiceTest { } private void runIsTetheringSupported(final TestTetheringResult result) throws Exception { - mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, result); + mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result); verify(mTethering).isTetheringSupported(); result.assertResult(TETHER_ERROR_NO_ERROR); } @@ -453,7 +463,8 @@ public final class TetheringServiceTest { @Test public void testIsTetheringSupported() throws Exception { runAsNoPermission((result) -> { - mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, result); + mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, + result); verify(mTethering).isTetherProvisioningRequired(); result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); verifyNoMoreInteractionsForTethering(); diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java index 64538c7d97c1..1b710d00d0c7 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java @@ -1897,7 +1897,7 @@ public class TetheringTest { 0, upstreamNetwork); mLooper.dispatchAll(); - // verify trun off usb tethering + // verify turn off usb tethering verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); mTethering.interfaceRemoved(TEST_USB_IFNAME); mLooper.dispatchAll(); @@ -1935,9 +1935,9 @@ public class TetheringTest { 0, upstreamNetwork); mLooper.dispatchAll(); - // verify trun off usb tethering + // verify turn off usb tethering verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); - // verify trun off ethernet tethering + // verify turn off ethernet tethering verify(mockRequest).release(); mTethering.interfaceRemoved(TEST_USB_IFNAME); ethCallback.onUnavailable(); diff --git a/packages/overlays/IconShapeHeartOverlay/AndroidManifest.xml b/packages/overlays/IconShapeHeartOverlay/AndroidManifest.xml index 82bff7d53d95..8fb19df33178 100644 --- a/packages/overlays/IconShapeHeartOverlay/AndroidManifest.xml +++ b/packages/overlays/IconShapeHeartOverlay/AndroidManifest.xml @@ -21,6 +21,7 @@ android:versionName="1.0"> <overlay android:targetPackage="android" + android:targetName="IconShapeCustomization" android:category="android.theme.customization.adaptive_icon_shape" android:priority="1"/> diff --git a/packages/overlays/IconShapePebbleOverlay/AndroidManifest.xml b/packages/overlays/IconShapePebbleOverlay/AndroidManifest.xml index d719a97e28f2..6842dde36264 100644 --- a/packages/overlays/IconShapePebbleOverlay/AndroidManifest.xml +++ b/packages/overlays/IconShapePebbleOverlay/AndroidManifest.xml @@ -21,6 +21,7 @@ android:versionName="1.0"> <overlay android:targetPackage="android" + android:targetName="IconShapeCustomization" android:category="android.theme.customization.adaptive_icon_shape" android:priority="1"/> diff --git a/packages/services/PacProcessor/AndroidManifest.xml b/packages/services/PacProcessor/AndroidManifest.xml index 6740c169ff21..ad1326194a4d 100644 --- a/packages/services/PacProcessor/AndroidManifest.xml +++ b/packages/services/PacProcessor/AndroidManifest.xml @@ -5,7 +5,9 @@ <uses-permission android:name="android.permission.INTERNET" /> <application - android:label="@string/app_name"> + android:label="@string/app_name" + android:defaultToDeviceProtectedStorage="true" + android:directBootAware="true"> <service android:name=".PacService" android:exported="true"> diff --git a/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl b/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl index 4e54aba5c3bf..1bbc90d604f9 100644 --- a/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl +++ b/packages/services/PacProcessor/src/com/android/net/IProxyService.aidl @@ -21,7 +21,4 @@ interface IProxyService String resolvePacFile(String host, String url); oneway void setPacFile(String scriptContents); - - oneway void startPacSystem(); - oneway void stopPacSystem(); } diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java index 7aea721617b9..5a7de9f70b49 100644 --- a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java +++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java @@ -88,15 +88,5 @@ public class PacService extends Service { } mLibpac.setCurrentProxyScript(script); } - - @Override - public void startPacSystem() throws RemoteException { - //TODO: remove - } - - @Override - public void stopPacSystem() throws RemoteException { - //TODO: remove - } } } diff --git a/proto/Android.bp b/proto/Android.bp index 01a72eaa6bf8..86d8ee3a662f 100644 --- a/proto/Android.bp +++ b/proto/Android.bp @@ -26,6 +26,8 @@ java_library_static { }, srcs: ["src/metrics_constants/metrics_constants.proto"], sdk_version: "system_current", + // this is part of updatable modules(CaptivePortalLogin) which targets 29(Q) + min_sdk_version: "29", } filegroup { diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk index a4bea661583b..95697e6f8bac 100644 --- a/rs/jni/Android.mk +++ b/rs/jni/Android.mk @@ -19,10 +19,10 @@ LOCAL_SHARED_LIBRARIES := \ libjnigraphics LOCAL_HEADER_LIBRARIES := \ + jni_headers \ libbase_headers LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) \ frameworks/rs LOCAL_CFLAGS += -Wno-unused-parameter diff --git a/services/Android.bp b/services/Android.bp index 00676e332656..40b925de95d6 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -125,7 +125,6 @@ droidstubs { " --hide InternalClasses" + // com.android.* classes are okay in this interface // TODO: remove the --hide options below " --hide-package com.google.android.startop.iorap" + - " --hide ReferencesHidden" + " --hide DeprecationMismatch" + " --hide HiddenTypedefConstant", visibility: ["//visibility:private"], @@ -158,4 +157,7 @@ java_library { srcs: [":services-stubs.sources"], installable: false, static_libs: ["android_module_lib_stubs_current"], + sdk_version: "none", + system_modules: "none", + java_version: "1.8", } diff --git a/services/backup/OWNERS b/services/backup/OWNERS index 9c21e8fe5e45..7c7e74285bf5 100644 --- a/services/backup/OWNERS +++ b/services/backup/OWNERS @@ -1,9 +1,12 @@ +# Bug component: 656484 + +aabhinav@google.com alsutton@google.com -anniemeng@google.com -brufino@google.com bryanmawhinney@google.com -ctate@google.com -jorlow@google.com +jstemmer@google.com nathch@google.com +niagra@google.com +niamhfw@google.com +philippov@google.com rthakohov@google.com - +tobiast@google.com diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 8dd4fa6d8fd1..65ac7844ec2b 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -166,6 +166,7 @@ public final class BatteryService extends SystemService { private int mLastInvalidCharger; private int mLowBatteryWarningLevel; + private int mLastLowBatteryWarningLevel; private int mLowBatteryCloseWarningLevel; private int mShutdownBatteryTemperature; @@ -314,6 +315,7 @@ public final class BatteryService extends SystemService { final ContentResolver resolver = mContext.getContentResolver(); int defWarnLevel = mContext.getResources().getInteger( com.android.internal.R.integer.config_lowBatteryWarningLevel); + mLastLowBatteryWarningLevel = mLowBatteryWarningLevel; mLowBatteryWarningLevel = Settings.Global.getInt(resolver, Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel); if (mLowBatteryWarningLevel == 0) { @@ -358,7 +360,8 @@ public final class BatteryService extends SystemService { return !plugged && mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN && mHealthInfo.batteryLevel <= mLowBatteryWarningLevel - && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel); + && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel + || mHealthInfo.batteryLevel > mLastLowBatteryWarningLevel); } private boolean shouldShutdownLocked() { diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 0d4efed25da3..2e4d44cef416 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -63,6 +63,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.os.UserManagerInternal.UserRestrictionsListener; +import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.text.TextUtils; @@ -114,6 +115,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { 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 DELAY_BEFORE_RESTART_DUE_TO_INIT_FLAGS_CHANGED_MS = 300; private static final int MESSAGE_ENABLE = 1; private static final int MESSAGE_DISABLE = 2; @@ -133,6 +135,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private static final int MESSAGE_ADD_PROXY_DELAYED = 400; private static final int MESSAGE_BIND_PROFILE_SERVICE = 401; private static final int MESSAGE_RESTORE_USER_SETTING = 500; + private static final int MESSAGE_INIT_FLAGS_CHANGED = 600; private static final int RESTORE_SETTING_TO_ON = 1; private static final int RESTORE_SETTING_TO_OFF = 0; @@ -278,6 +281,30 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } }; + private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener = + new DeviceConfig.OnPropertiesChangedListener() { + @Override + public void onPropertiesChanged(DeviceConfig.Properties properties) { + if (!properties.getNamespace().equals(DeviceConfig.NAMESPACE_BLUETOOTH)) { + return; + } + boolean foundInit = false; + for (String name : properties.getKeyset()) { + if (name.startsWith("INIT_")) { + foundInit = true; + break; + } + } + if (!foundInit) { + return; + } + mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED); + mHandler.sendEmptyMessageDelayed( + MESSAGE_INIT_FLAGS_CHANGED, + DELAY_BEFORE_RESTART_DUE_TO_INIT_FLAGS_CHANGED_MS); + } + }; + public boolean onFactoryReset() { // Wait for stable state if bluetooth is temporary state. int state = getState(); @@ -507,6 +534,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub { Slog.w(TAG, "Unable to resolve SystemUI's UID."); } mSystemUiUid = systemUiUid; + DeviceConfig.addOnPropertiesChangedListener( + DeviceConfig.NAMESPACE_BLUETOOTH, + (Runnable r) -> r.run(), + mDeviceConfigChangedListener); } /** @@ -2148,80 +2179,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { /* disable and enable BT when detect a user switch */ if (mBluetooth != null && isEnabled()) { - try { - mBluetoothLock.readLock().lock(); - if (mBluetooth != null) { - mBluetooth.unregisterCallback(mBluetoothCallback); - } - } catch (RemoteException re) { - Slog.e(TAG, "Unable to unregister", re); - } finally { - mBluetoothLock.readLock().unlock(); - } - - if (mState == BluetoothAdapter.STATE_TURNING_OFF) { - // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE - bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF); - mState = BluetoothAdapter.STATE_OFF; - } - if (mState == BluetoothAdapter.STATE_OFF) { - bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON); - mState = BluetoothAdapter.STATE_TURNING_ON; - } - - waitForState(Set.of(BluetoothAdapter.STATE_ON)); - - if (mState == BluetoothAdapter.STATE_TURNING_ON) { - bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON); - } - - unbindAllBluetoothProfileServices(); - // disable - addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH, - mContext.getPackageName(), false); - handleDisable(); - // Pbap service need receive STATE_TURNING_OFF intent to close - bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, - BluetoothAdapter.STATE_TURNING_OFF); - - boolean didDisableTimeout = - !waitForState(Set.of(BluetoothAdapter.STATE_OFF)); - - bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, - BluetoothAdapter.STATE_OFF); - sendBluetoothServiceDownCallback(); - - try { - mBluetoothLock.writeLock().lock(); - if (mBluetooth != null) { - mBluetooth = null; - // Unbind - mContext.unbindService(mConnection); - } - mBluetoothGatt = null; - } finally { - mBluetoothLock.writeLock().unlock(); - } - - // - // If disabling Bluetooth times out, wait for an - // additional amount of time to ensure the process is - // shut down completely before attempting to restart. - // - if (didDisableTimeout) { - SystemClock.sleep(3000); - } else { - SystemClock.sleep(100); - } - - mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); - mState = BluetoothAdapter.STATE_OFF; - // enable - addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH, - mContext.getPackageName(), true); - // mEnable flag could have been reset on disableBLE. Reenable it. - mEnable = true; - handleEnable(mQuietEnable); + restartForReason(BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH); } else if (mBinding || mBluetooth != null) { Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED); userMsg.arg2 = 1 + msg.arg2; @@ -2248,8 +2206,95 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } handleEnable(mQuietEnable); } + break; + } + case MESSAGE_INIT_FLAGS_CHANGED: { + if (DBG) { + Slog.d(TAG, "MESSAGE_INIT_FLAGS_CHANGED"); + } + mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED); + if (mBluetooth != null && isEnabled()) { + restartForReason( + BluetoothProtoEnums.ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED); + } + break; + } + } + } + + private void restartForReason(int reason) { + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth != null) { + mBluetooth.unregisterCallback(mBluetoothCallback); + } + } catch (RemoteException re) { + Slog.e(TAG, "Unable to unregister", re); + } finally { + mBluetoothLock.readLock().unlock(); + } + + if (mState == BluetoothAdapter.STATE_TURNING_OFF) { + // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE + bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF); + mState = BluetoothAdapter.STATE_OFF; + } + if (mState == BluetoothAdapter.STATE_OFF) { + bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON); + mState = BluetoothAdapter.STATE_TURNING_ON; + } + + waitForState(Set.of(BluetoothAdapter.STATE_ON)); + + if (mState == BluetoothAdapter.STATE_TURNING_ON) { + bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON); + } + + unbindAllBluetoothProfileServices(); + // disable + addActiveLog(reason, mContext.getPackageName(), false); + handleDisable(); + // Pbap service need receive STATE_TURNING_OFF intent to close + bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, + BluetoothAdapter.STATE_TURNING_OFF); + + boolean didDisableTimeout = + !waitForState(Set.of(BluetoothAdapter.STATE_OFF)); + + bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, + BluetoothAdapter.STATE_OFF); + sendBluetoothServiceDownCallback(); + + try { + mBluetoothLock.writeLock().lock(); + if (mBluetooth != null) { + mBluetooth = null; + // Unbind + mContext.unbindService(mConnection); } + mBluetoothGatt = null; + } finally { + mBluetoothLock.writeLock().unlock(); } + + // + // If disabling Bluetooth times out, wait for an + // additional amount of time to ensure the process is + // shut down completely before attempting to restart. + // + if (didDisableTimeout) { + SystemClock.sleep(3000); + } else { + SystemClock.sleep(100); + } + + mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); + mState = BluetoothAdapter.STATE_OFF; + // enable + addActiveLog(reason, mContext.getPackageName(), true); + // mEnable flag could have been reset on disableBLE. Reenable it. + mEnable = true; + handleEnable(mQuietEnable); } } @@ -2711,6 +2756,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return "RESTORE_USER_SETTING"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET: return "FACTORY_RESET"; + case BluetoothProtoEnums.ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED: + return "INIT_FLAGS_CHANGED"; case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED: default: return "UNKNOWN[" + reason + "]"; } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 77cd5d2ffdab..02c08cc4cd39 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1835,11 +1835,12 @@ public class ConnectivityService extends IConnectivityManager.Stub * @return {@code true} on success, {@code false} on failure */ @Override - public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) { + public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress, + String callingPackageName, String callingAttributionTag) { if (disallowedBecauseSystemCaller()) { return false; } - enforceChangePermission(); + enforceChangePermission(callingPackageName, callingAttributionTag); if (mProtectedNetworks.contains(networkType)) { enforceConnectivityRestrictedNetworksPermission(); } @@ -2093,8 +2094,8 @@ public class ConnectivityService extends IConnectivityManager.Stub "ConnectivityService"); } - private void enforceChangePermission() { - ConnectivityManager.enforceChangePermission(mContext); + private void enforceChangePermission(String callingPkg, String callingAttributionTag) { + ConnectivityManager.enforceChangePermission(mContext, callingPkg, callingAttributionTag); } private void enforceSettingsPermission() { @@ -5149,14 +5150,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void onPackageAdded(String packageName, int uid) { - if (TextUtils.isEmpty(packageName) || uid < 0) { - Slog.wtf(TAG, "Invalid package in onPackageAdded: " + packageName + " | " + uid); - return; - } - mPermissionMonitor.onPackageAdded(packageName, uid); - } - private void onPackageReplaced(String packageName, int uid) { if (TextUtils.isEmpty(packageName) || uid < 0) { Slog.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid); @@ -5182,7 +5175,6 @@ public class ConnectivityService extends IConnectivityManager.Stub Slog.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid); return; } - mPermissionMonitor.onPackageRemoved(uid); final int userId = UserHandle.getUserId(uid); synchronized (mVpns) { @@ -5232,8 +5224,6 @@ public class ConnectivityService extends IConnectivityManager.Stub onUserRemoved(userId); } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) { onUserUnlocked(userId); - } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { - onPackageAdded(packageName, uid); } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) { onPackageReplaced(packageName, uid); } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { @@ -5509,7 +5499,7 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, int timeoutMs, IBinder binder, int legacyType, - @NonNull String callingPackageName) { + @NonNull String callingPackageName, @Nullable String callingAttributionTag) { if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) { if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) { throw new SecurityException("Insufficient permissions to specify legacy type"); @@ -5527,7 +5517,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceAccessPermission(); } else { networkCapabilities = new NetworkCapabilities(networkCapabilities); - enforceNetworkRequestPermissions(networkCapabilities); + enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, + callingAttributionTag); // TODO: this is incorrect. We mark the request as metered or not depending on the state // of the app when the request is filed, but we never change the request if the app // changes network state. http://b/29964605 @@ -5562,11 +5553,12 @@ public class ConnectivityService extends IConnectivityManager.Stub return networkRequest; } - private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) { + private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities, + String callingPackageName, String callingAttributionTag) { if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) { enforceConnectivityRestrictedNetworksPermission(); } else { - enforceChangePermission(); + enforceChangePermission(callingPackageName, callingAttributionTag); } } @@ -5617,11 +5609,13 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, - PendingIntent operation, @NonNull String callingPackageName) { + PendingIntent operation, @NonNull String callingPackageName, + @Nullable String callingAttributionTag) { Objects.requireNonNull(operation, "PendingIntent cannot be null."); final int callingUid = Binder.getCallingUid(); networkCapabilities = new NetworkCapabilities(networkCapabilities); - enforceNetworkRequestPermissions(networkCapabilities); + enforceNetworkRequestPermissions(networkCapabilities, callingPackageName, + callingAttributionTag); enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, diff --git a/services/core/java/com/android/server/RuntimeService.java b/services/core/java/com/android/server/RuntimeService.java index bb39ccc52af2..f4249f844873 100644 --- a/services/core/java/com/android/server/RuntimeService.java +++ b/services/core/java/com/android/server/RuntimeService.java @@ -23,10 +23,9 @@ import android.service.runtime.RuntimeServiceInfoProto; import android.util.Slog; import android.util.proto.ProtoOutputStream; -import libcore.timezone.TimeZoneDataFiles; -import libcore.util.CoreLibraryDebug; -import libcore.util.DebugInfo; - +import com.android.i18n.timezone.DebugInfo; +import com.android.i18n.timezone.I18nModuleDebug; +import com.android.i18n.timezone.TimeZoneDataFiles; import com.android.internal.util.DumpUtils; import com.android.timezone.distro.DistroException; import com.android.timezone.distro.DistroVersion; @@ -61,14 +60,14 @@ public class RuntimeService extends Binder { boolean protoFormat = hasOption(args, "--proto"); ProtoOutputStream proto = null; - DebugInfo coreLibraryDebugInfo = CoreLibraryDebug.getDebugInfo(); - addTimeZoneApkDebugInfo(coreLibraryDebugInfo); + DebugInfo i18nLibraryDebugInfo = I18nModuleDebug.getDebugInfo(); + addTimeZoneApkDebugInfo(i18nLibraryDebugInfo); if (protoFormat) { proto = new ProtoOutputStream(fd); - reportTimeZoneInfoProto(coreLibraryDebugInfo, proto); + reportTimeZoneInfoProto(i18nLibraryDebugInfo, proto); } else { - reportTimeZoneInfo(coreLibraryDebugInfo, pw); + reportTimeZoneInfo(i18nLibraryDebugInfo, pw); } if (protoFormat) { diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index 425a0452b6b8..17c0970c5ca7 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -23,7 +23,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.hidl.manager.V1_0.IServiceManager; import android.os.Binder; -import android.os.Build; import android.os.Debug; import android.os.Handler; import android.os.IPowerManager; @@ -32,10 +31,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; -import android.system.StructRlimit; import android.util.EventLog; import android.util.Log; import android.util.Slog; @@ -51,13 +46,8 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -139,7 +129,6 @@ public class Watchdog extends Thread { private IActivityController mController; private boolean mAllowRestart = true; - private final OpenFdMonitor mOpenFdMonitor; private final List<Integer> mInterestingJavaPids = new ArrayList<>(); /** @@ -345,8 +334,6 @@ public class Watchdog extends Thread { // Initialize monitor for Binder threads. addMonitor(new BinderThreadMonitor()); - mOpenFdMonitor = OpenFdMonitor.create(); - mInterestingJavaPids.add(Process.myPid()); // See the notes on DEFAULT_TIMEOUT. @@ -592,40 +579,30 @@ public class Watchdog extends Thread { timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start); } - boolean fdLimitTriggered = false; - if (mOpenFdMonitor != null) { - fdLimitTriggered = mOpenFdMonitor.monitor(); - } - - if (!fdLimitTriggered) { - final int waitState = evaluateCheckerCompletionLocked(); - if (waitState == COMPLETED) { - // The monitors have returned; reset - waitedHalf = false; - continue; - } else if (waitState == WAITING) { - // still waiting but within their configured intervals; back off and recheck - continue; - } else if (waitState == WAITED_HALF) { - if (!waitedHalf) { - Slog.i(TAG, "WAITED_HALF"); - // We've waited half the deadlock-detection interval. Pull a stack - // trace and wait another half. - ArrayList<Integer> pids = new ArrayList<>(mInterestingJavaPids); - ActivityManagerService.dumpStackTraces(pids, null, null, - getInterestingNativePids(), null); - waitedHalf = true; - } - continue; + final int waitState = evaluateCheckerCompletionLocked(); + if (waitState == COMPLETED) { + // The monitors have returned; reset + waitedHalf = false; + continue; + } else if (waitState == WAITING) { + // still waiting but within their configured intervals; back off and recheck + continue; + } else if (waitState == WAITED_HALF) { + if (!waitedHalf) { + Slog.i(TAG, "WAITED_HALF"); + // We've waited half the deadlock-detection interval. Pull a stack + // trace and wait another half. + ArrayList<Integer> pids = new ArrayList<>(mInterestingJavaPids); + ActivityManagerService.dumpStackTraces(pids, null, null, + getInterestingNativePids(), null); + waitedHalf = true; } - - // something is overdue! - blockedCheckers = getBlockedCheckersLocked(); - subject = describeCheckersLocked(blockedCheckers); - } else { - blockedCheckers = Collections.emptyList(); - subject = "Open FD high water mark reached"; + continue; } + + // something is overdue! + blockedCheckers = getBlockedCheckersLocked(); + subject = describeCheckersLocked(blockedCheckers); allowRestart = mAllowRestart; } @@ -728,94 +705,4 @@ public class Watchdog extends Thread { Slog.w(TAG, "Failed to write to /proc/sysrq-trigger", e); } } - - public static final class OpenFdMonitor { - /** - * Number of FDs below the soft limit that we trigger a runtime restart at. This was - * chosen arbitrarily, but will need to be at least 6 in order to have a sufficient number - * of FDs in reserve to complete a dump. - */ - private static final int FD_HIGH_WATER_MARK = 12; - - private final File mDumpDir; - private final File mFdHighWaterMark; - - public static OpenFdMonitor create() { - // Only run the FD monitor on debuggable builds (such as userdebug and eng builds). - if (!Build.IS_DEBUGGABLE) { - return null; - } - - final StructRlimit rlimit; - try { - rlimit = android.system.Os.getrlimit(OsConstants.RLIMIT_NOFILE); - } catch (ErrnoException errno) { - Slog.w(TAG, "Error thrown from getrlimit(RLIMIT_NOFILE)", errno); - return null; - } - - // The assumption we're making here is that FD numbers are allocated (more or less) - // sequentially, which is currently (and historically) true since open is currently - // specified to always return the lowest-numbered non-open file descriptor for the - // current process. - // - // We do this to avoid having to enumerate the contents of /proc/self/fd in order to - // count the number of descriptors open in the process. - final File fdThreshold = new File("/proc/self/fd/" + (rlimit.rlim_cur - FD_HIGH_WATER_MARK)); - return new OpenFdMonitor(new File("/data/anr"), fdThreshold); - } - - OpenFdMonitor(File dumpDir, File fdThreshold) { - mDumpDir = dumpDir; - mFdHighWaterMark = fdThreshold; - } - - /** - * Dumps open file descriptors and their full paths to a temporary file in {@code mDumpDir}. - */ - private void dumpOpenDescriptors() { - // We cannot exec lsof to get more info about open file descriptors because a newly - // forked process will not have the permissions to readlink. Instead list all open - // descriptors from /proc/pid/fd and resolve them. - List<String> dumpInfo = new ArrayList<>(); - String fdDirPath = String.format("/proc/%d/fd/", Process.myPid()); - File[] fds = new File(fdDirPath).listFiles(); - if (fds == null) { - dumpInfo.add("Unable to list " + fdDirPath); - } else { - for (File f : fds) { - String fdSymLink = f.getAbsolutePath(); - String resolvedPath = ""; - try { - resolvedPath = Os.readlink(fdSymLink); - } catch (ErrnoException ex) { - resolvedPath = ex.getMessage(); - } - dumpInfo.add(fdSymLink + "\t" + resolvedPath); - } - } - - // Dump the fds & paths to a temp file. - try { - File dumpFile = File.createTempFile("anr_fd_", "", mDumpDir); - Path out = Paths.get(dumpFile.getAbsolutePath()); - Files.write(out, dumpInfo, StandardCharsets.UTF_8); - } catch (IOException ex) { - Slog.w(TAG, "Unable to write open descriptors to file: " + ex); - } - } - - /** - * @return {@code true} if the high water mark was breached and a dump was written, - * {@code false} otherwise. - */ - public boolean monitor() { - if (mFdHighWaterMark.exists()) { - dumpOpenDescriptors(); - return true; - } - - return false; - } - } } diff --git a/services/core/java/com/android/server/accounts/TokenCache.java b/services/core/java/com/android/server/accounts/TokenCache.java index e38cf5f3ece5..66e550fe3c4c 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 2e628642dac5..5a0ea7586301 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -110,6 +110,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ProcessMap; import com.android.internal.app.procstats.ProcessStats; +import com.android.internal.os.RuntimeInit; import com.android.internal.os.Zygote; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; @@ -124,7 +125,6 @@ import com.android.server.pm.parsing.pkg.AndroidPackage; 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; @@ -345,10 +345,18 @@ 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. /** + * Enable memory tag checks in non-system apps. This flag will only have an effect on + * hardware supporting the ARM Memory Tagging Extension (MTE). + */ + @ChangeId + @Disabled + private static final long NATIVE_MEMORY_TAGGING = 135772972; // This is a bug id. + + /** * Enable sampled memory bug detection in the app. * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>. */ @@ -361,7 +369,7 @@ public final class ProcessList { * app has made them world-readable. */ @ChangeId - @EnabledAfter(targetSdkVersion = VersionCodes.Q) + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) private static final long APP_DATA_DIRECTORY_ISOLATION = 143937733; // See b/143937733 ActivityManagerService mService = null; @@ -1669,6 +1677,25 @@ public final class ProcessList { return gidArray; } + private boolean shouldEnableMemoryTagging(ProcessRecord app) { + // Ensure the hardware + kernel actually supports MTE. + if (!Zygote.nativeSupportsMemoryTagging()) { + return false; + } + + // Enable MTE for system apps if supported. + if ((app.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + return true; + } + + // Enable MTE if the compat feature is enabled. + if (mPlatformCompat.isChangeEnabled(NATIVE_MEMORY_TAGGING, app.info)) { + return true; + } + + return false; + } + private boolean shouldEnableTaggedPointers(ProcessRecord app) { // Ensure we have platform + kernel support for TBI. if (!Zygote.nativeSupportsTaggedPointers()) { @@ -1689,6 +1716,11 @@ public final class ProcessList { } private int decideTaggingLevel(ProcessRecord app) { + // Check MTE support first, as it should take precedence over TBI. + if (shouldEnableMemoryTagging(app)) { + return Zygote.MEMORY_TAG_LEVEL_ASYNC; + } + if (shouldEnableTaggedPointers(app)) { return Zygote.MEMORY_TAG_LEVEL_TBI; } @@ -1917,13 +1949,13 @@ public final class ProcessList { // If instructionSet is non-null, this indicates that the system_server is spawning a // process with an ISA that may be different from its own. System (kernel and hardware) // compatililty for these features is checked in the decideTaggingLevel in the - // system_server process (not the child process). As TBI is only supported in aarch64, - // we can simply ensure that the new process is also aarch64. This prevents the mismatch - // where a 64-bit system server spawns a 32-bit child that thinks it should enable some - // tagging variant. Theoretically, a 32-bit system server could exist that spawns 64-bit - // processes, in which case the new process won't get any tagging. This is fine as we - // haven't seen this configuration in practice, and we can reasonable assume that if - // tagging is desired, the system server will be 64-bit. + // system_server process (not the child process). As both MTE and TBI are only supported + // in aarch64, we can simply ensure that the new process is also aarch64. This prevents + // the mismatch where a 64-bit system server spawns a 32-bit child that thinks it should + // enable some tagging variant. Theoretically, a 32-bit system server could exist that + // spawns 64-bit processes, in which case the new process won't get any tagging. This is + // fine as we haven't seen this configuration in practice, and we can reasonable assume + // that if tagging is desired, the system server will be 64-bit. if (instructionSet == null || instructionSet.equals("arm64")) { runtimeFlags |= decideTaggingLevel(app); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index c4eca605206d..7e4038e92563 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3815,7 +3815,7 @@ public class AudioService extends IAudioService.Stub } try { hdlr.getBinder().unlinkToDeath(hdlr, 0); - if (cb != hdlr.getBinder()) { + if (cb != hdlr.getBinder()){ hdlr = null; } } catch (NoSuchElementException e) { diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java index 26281b739436..bbc29b0bf89b 100755 --- a/services/core/java/com/android/server/audio/MediaFocusControl.java +++ b/services/core/java/com/android/server/audio/MediaFocusControl.java @@ -682,7 +682,12 @@ public class MediaFocusControl implements PlayerFocusEnforcer { return; } } - final FocusRequester fr = mFocusOwnersForFocusPolicy.get(afi.getClientId()); + final FocusRequester fr; + if (requestResult == AudioManager.AUDIOFOCUS_REQUEST_FAILED) { + fr = mFocusOwnersForFocusPolicy.remove(afi.getClientId()); + } else { + fr = mFocusOwnersForFocusPolicy.get(afi.getClientId()); + } if (fr != null) { fr.dispatchFocusResultFromExtPolicy(requestResult); } diff --git a/services/core/java/com/android/server/compat/OWNERS b/services/core/java/com/android/server/compat/OWNERS index 2b7cdb0cbce9..cfd0a4b079ad 100644 --- a/services/core/java/com/android/server/compat/OWNERS +++ b/services/core/java/com/android/server/compat/OWNERS @@ -2,6 +2,5 @@ platform-compat-eng+reviews@google.com andreionea@google.com -atrost@google.com mathewi@google.com satayev@google.com diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index d7e9499cf8db..92fce8a22937 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.LOG_COMPAT_CHANGE; import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG; import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.os.Process.SYSTEM_UID; import android.annotation.UserIdInt; import android.app.ActivityManager; @@ -333,6 +334,10 @@ public class PlatformCompat extends IPlatformCompat.Stub { } private void checkCompatChangeLogPermission() throws SecurityException { + // Don't check for permissions within the system process + if (Binder.getCallingUid() == SYSTEM_UID) { + return; + } if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE) != PERMISSION_GRANTED) { throw new SecurityException("Cannot log compat change usage"); @@ -340,6 +345,10 @@ public class PlatformCompat extends IPlatformCompat.Stub { } private void checkCompatChangeReadPermission() throws SecurityException { + // Don't check for permissions within the system process + if (Binder.getCallingUid() == SYSTEM_UID) { + return; + } if (mContext.checkCallingOrSelfPermission(READ_COMPAT_CHANGE_CONFIG) != PERMISSION_GRANTED) { throw new SecurityException("Cannot read compat change"); @@ -347,6 +356,10 @@ public class PlatformCompat extends IPlatformCompat.Stub { } private void checkCompatChangeOverridePermission() throws SecurityException { + // Don't check for permissions within the system process + if (Binder.getCallingUid() == SYSTEM_UID) { + return; + } if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG) != PERMISSION_GRANTED) { throw new SecurityException("Cannot override compat change"); diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 37b2de1070a5..a9f62d91592d 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -658,19 +658,22 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // 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 + "} " - + "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/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java index f6ce2dc68b99..de302fc01f2d 100644 --- a/services/core/java/com/android/server/connectivity/PacManager.java +++ b/services/core/java/com/android/server/connectivity/PacManager.java @@ -196,13 +196,7 @@ public class PacManager { mPacUrl = Uri.EMPTY; mCurrentPac = null; if (mProxyService != null) { - try { - mProxyService.stopPacSystem(); - } catch (RemoteException e) { - Log.w(TAG, "Failed to stop PAC service", e); - } finally { - unbind(); - } + unbind(); } } return DO_SEND_BROADCAST; @@ -327,11 +321,6 @@ public class PacManager { if (mProxyService == null) { Log.e(TAG, "No proxy service"); } else { - try { - mProxyService.startPacSystem(); - } catch (RemoteException e) { - Log.e(TAG, "Unable to reach ProxyService - PAC will not be started", e); - } mNetThreadHandler.post(mPacDownloader); } } diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java index f0b7150dd84f..a75a80a606eb 100644 --- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java +++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java @@ -72,7 +72,7 @@ import java.util.Set; * * @hide */ -public class PermissionMonitor { +public class PermissionMonitor implements PackageManagerInternal.PackageListObserver { private static final String TAG = "PermissionMonitor"; private static final boolean DBG = true; protected static final Boolean SYSTEM = Boolean.TRUE; @@ -82,6 +82,7 @@ public class PermissionMonitor { private final PackageManager mPackageManager; private final UserManager mUserManager; private final INetd mNetd; + private final Dependencies mDeps; // Values are User IDs. @GuardedBy("this") @@ -102,48 +103,30 @@ public class PermissionMonitor { @GuardedBy("this") private final Set<Integer> mAllApps = new HashSet<>(); - private class PackageListObserver implements PackageManagerInternal.PackageListObserver { - - private int getPermissionForUid(int uid) { - int permission = 0; - // Check all the packages for this UID. The UID has the permission if any of the - // packages in it has the permission. - String[] packages = mPackageManager.getPackagesForUid(uid); - if (packages != null && packages.length > 0) { - for (String name : packages) { - final PackageInfo app = getPackageInfo(name); - if (app != null && app.requestedPermissions != null) { - permission |= getNetdPermissionMask(app.requestedPermissions, - app.requestedPermissionsFlags); - } - } - } else { - // The last package of this uid is removed from device. Clean the package up. - permission = INetd.PERMISSION_UNINSTALLED; - } - return permission; - } - - @Override - public void onPackageAdded(String packageName, int uid) { - sendPackagePermissionsForUid(uid, getPermissionForUid(uid)); - } - - @Override - public void onPackageChanged(@NonNull String packageName, int uid) { - sendPackagePermissionsForUid(uid, getPermissionForUid(uid)); + /** + * Dependencies of PermissionMonitor, for injection in tests. + */ + @VisibleForTesting + public static class Dependencies { + /** + * Get device first sdk version. + */ + public int getDeviceFirstSdkInt() { + return Build.VERSION.FIRST_SDK_INT; } + } - @Override - public void onPackageRemoved(String packageName, int uid) { - sendPackagePermissionsForUid(uid, getPermissionForUid(uid)); - } + public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) { + this(context, netd, new Dependencies()); } - public PermissionMonitor(Context context, INetd netd) { + @VisibleForTesting + PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd, + @NonNull final Dependencies deps) { mPackageManager = context.getPackageManager(); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mNetd = netd; + mDeps = deps; } // Intended to be called only once at startup, after the system is ready. Installs a broadcast @@ -153,7 +136,7 @@ public class PermissionMonitor { PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); if (pmi != null) { - pmi.getPackageList(new PackageListObserver()); + pmi.getPackageList(this); } else { loge("failed to get the PackageManagerInternal service"); } @@ -224,11 +207,6 @@ public class PermissionMonitor { } @VisibleForTesting - protected int getDeviceFirstSdkInt() { - return Build.VERSION.FIRST_SDK_INT; - } - - @VisibleForTesting boolean hasPermission(@NonNull final PackageInfo app, @NonNull final String permission) { if (app.requestedPermissions == null || app.requestedPermissionsFlags == null) { return false; @@ -250,7 +228,7 @@ public class PermissionMonitor { if (app.applicationInfo != null) { // Backward compatibility for b/114245686, on devices that launched before Q daemons // and apps running as the system UID are exempted from this check. - if (app.applicationInfo.uid == SYSTEM_UID && getDeviceFirstSdkInt() < VERSION_Q) { + if (app.applicationInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q) { return true; } @@ -363,15 +341,38 @@ public class PermissionMonitor { return currentPermission; } + private int getPermissionForUid(final int uid) { + int permission = INetd.PERMISSION_NONE; + // Check all the packages for this UID. The UID has the permission if any of the + // packages in it has the permission. + final String[] packages = mPackageManager.getPackagesForUid(uid); + if (packages != null && packages.length > 0) { + for (String name : packages) { + final PackageInfo app = getPackageInfo(name); + if (app != null && app.requestedPermissions != null) { + permission |= getNetdPermissionMask(app.requestedPermissions, + app.requestedPermissionsFlags); + } + } + } else { + // The last package of this uid is removed from device. Clean the package up. + permission = INetd.PERMISSION_UNINSTALLED; + } + return permission; + } + /** - * Called when a package is added. See {link #ACTION_PACKAGE_ADDED}. + * Called when a package is added. * * @param packageName The name of the new package. * @param uid The uid of the new package. * * @hide */ - public synchronized void onPackageAdded(String packageName, int uid) { + @Override + public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) { + sendPackagePermissionsForUid(uid, getPermissionForUid(uid)); + // If multiple packages share a UID (cf: android:sharedUserId) and ask for different // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is). final Boolean permission = highestPermissionForUid(mApps.get(uid), packageName); @@ -398,13 +399,17 @@ public class PermissionMonitor { } /** - * Called when a package is removed. See {link #ACTION_PACKAGE_REMOVED}. + * Called when a package is removed. * + * @param packageName The name of the removed package or null. * @param uid containing the integer uid previously assigned to the package. * * @hide */ - public synchronized void onPackageRemoved(int uid) { + @Override + public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) { + sendPackagePermissionsForUid(uid, getPermissionForUid(uid)); + // If the newly-removed package falls within some VPN's uid range, update Netd with it. // This needs to happen before the mApps update below, since removeBypassingUids() depends // on mApps to check if the package can bypass VPN. @@ -449,6 +454,19 @@ public class PermissionMonitor { } } + /** + * Called when a package is changed. + * + * @param packageName The name of the changed package. + * @param uid The uid of the changed package. + * + * @hide + */ + @Override + public synchronized void onPackageChanged(@NonNull final String packageName, final int uid) { + sendPackagePermissionsForUid(uid, getPermissionForUid(uid)); + } + private static int getNetdPermissionMask(String[] requestedPermissions, int[] requestedPermissionsFlags) { int permissions = 0; diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java index e715890fb211..26cc3ee165f1 100644 --- a/services/core/java/com/android/server/connectivity/ProxyTracker.java +++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java @@ -73,6 +73,8 @@ public class ProxyTracker { @GuardedBy("mProxyLock") private boolean mDefaultProxyEnabled = true; + private final Handler mConnectivityServiceHandler; + // The object responsible for Proxy Auto Configuration (PAC). @NonNull private final PacManager mPacManager; @@ -80,6 +82,7 @@ public class ProxyTracker { public ProxyTracker(@NonNull final Context context, @NonNull final Handler connectivityServiceInternalHandler, final int pacChangedEvent) { mContext = context; + mConnectivityServiceHandler = connectivityServiceInternalHandler; mPacManager = new PacManager(context, connectivityServiceInternalHandler, pacChangedEvent); } @@ -149,6 +152,9 @@ public class ProxyTracker { * Read the global proxy settings and cache them in memory. */ public void loadGlobalProxy() { + if (loadDeprecatedGlobalHttpProxy()) { + return; + } ContentResolver res = mContext.getContentResolver(); String host = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_HOST); int port = Settings.Global.getInt(res, GLOBAL_HTTP_PROXY_PORT, 0); @@ -157,7 +163,7 @@ public class ProxyTracker { if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) { ProxyInfo proxyProperties; if (!TextUtils.isEmpty(pacFileUrl)) { - proxyProperties = new ProxyInfo(pacFileUrl); + proxyProperties = new ProxyInfo(Uri.parse(pacFileUrl)); } else { proxyProperties = new ProxyInfo(host, port, exclList); } @@ -169,20 +175,24 @@ public class ProxyTracker { synchronized (mProxyLock) { mGlobalProxy = proxyProperties; } + + if (!TextUtils.isEmpty(pacFileUrl)) { + mConnectivityServiceHandler.post( + () -> mPacManager.setCurrentProxyScriptUrl(proxyProperties)); + } } - loadDeprecatedGlobalHttpProxy(); - // TODO : shouldn't this function call mPacManager.setCurrentProxyScriptUrl ? } /** * Read the global proxy from the deprecated Settings.Global.HTTP_PROXY setting and apply it. + * Returns {@code true} when global proxy was set successfully from deprecated setting. */ - public void loadDeprecatedGlobalHttpProxy() { + public boolean loadDeprecatedGlobalHttpProxy() { final String proxy = Settings.Global.getString(mContext.getContentResolver(), HTTP_PROXY); if (!TextUtils.isEmpty(proxy)) { String data[] = proxy.split(":"); if (data.length == 0) { - return; + return false; } final String proxyHost = data[0]; @@ -191,12 +201,14 @@ public class ProxyTracker { try { proxyPort = Integer.parseInt(data[1]); } catch (NumberFormatException e) { - return; + return false; } } final ProxyInfo p = new ProxyInfo(proxyHost, proxyPort, ""); setGlobalProxy(p); + return true; } + return false; } /** diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index 75ab33dbbfc7..66652ca26e54 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -27,9 +27,7 @@ import android.hardware.tv.cec.V1_0.SendMessageResult; import android.os.Handler; import android.os.IHwBinder; import android.os.Looper; -import android.os.MessageQueue; import android.os.RemoteException; -import android.os.SystemProperties; import android.util.Slog; import android.util.SparseArray; @@ -125,18 +123,10 @@ final class HdmiCecController { private final NativeWrapper mNativeWrapperImpl; - /** List of logical addresses that should not be assigned to the current device. - * - * <p>Parsed from {@link Constants#PROPERTY_HDMI_CEC_NEVER_ASSIGN_LOGICAL_ADDRESSES} - */ - private final List<Integer> mNeverAssignLogicalAddresses; - // Private constructor. Use HdmiCecController.create(). private HdmiCecController(HdmiControlService service, NativeWrapper nativeWrapper) { mService = service; mNativeWrapperImpl = nativeWrapper; - mNeverAssignLogicalAddresses = mService.getIntList(SystemProperties.get( - Constants.PROPERTY_HDMI_CEC_NEVER_ASSIGN_LOGICAL_ADDRESSES)); } /** @@ -227,8 +217,7 @@ final class HdmiCecController { for (int i = 0; i < NUM_LOGICAL_ADDRESS; ++i) { int curAddress = (startAddress + i) % NUM_LOGICAL_ADDRESS; if (curAddress != Constants.ADDR_UNREGISTERED - && deviceType == HdmiUtils.getTypeFromAddress(curAddress) - && !mNeverAssignLogicalAddresses.contains(curAddress)) { + && deviceType == HdmiUtils.getTypeFromAddress(curAddress)) { boolean acked = false; for (int j = 0; j < HdmiConfig.ADDRESS_ALLOCATION_RETRY; ++j) { if (sendPollMessage(curAddress, curAddress, 1)) { @@ -731,21 +720,6 @@ final class HdmiCecController { boolean nativeIsConnected(int port); } - private static native long nativeInit(HdmiCecController handler, MessageQueue messageQueue); - private static native int nativeSendCecCommand(long controllerPtr, int srcAddress, - int dstAddress, byte[] body); - private static native int nativeAddLogicalAddress(long controllerPtr, int logicalAddress); - private static native void nativeClearLogicalAddress(long controllerPtr); - private static native int nativeGetPhysicalAddress(long controllerPtr); - private static native int nativeGetVersion(long controllerPtr); - private static native int nativeGetVendorId(long controllerPtr); - private static native HdmiPortInfo[] nativeGetPortInfos(long controllerPtr); - private static native void nativeSetOption(long controllerPtr, int flag, boolean enabled); - private static native void nativeSetLanguage(long controllerPtr, String language); - private static native void nativeEnableAudioReturnChannel(long controllerPtr, - int port, boolean flag); - private static native boolean nativeIsConnected(long controllerPtr, int port); - private static final class NativeWrapperImpl implements NativeWrapper, IHwBinder.DeathRecipient, getPhysicalAddressCallback { private IHdmiCec mHdmiCec; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index f4a86675541d..2c0ddaf35182 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -214,9 +214,11 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { resetSelectRequestBuffer(); launchDeviceDiscovery(); startQueuedActions(); + if (!mDelayedMessageBuffer.isBuffered(Constants.MESSAGE_ACTIVE_SOURCE)) { + mService.sendCecCommand(HdmiCecMessageBuilder.buildRequestActiveSource(mAddress)); + } } - @ServiceThreadOnly private List<Integer> initLocalDeviceAddresses() { assertRunOnServiceThread(); @@ -1096,10 +1098,11 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { HdmiDeviceInfo avr = getAvrDeviceInfo(); if (avr != null && (avrAddress == avr.getLogicalAddress()) - && isConnectedToArcPort(avr.getPhysicalAddress()) - && isDirectConnectAddress(avr.getPhysicalAddress())) { + && isConnectedToArcPort(avr.getPhysicalAddress())) { if (enabled) { - return isConnected(avr.getPortId()) && isArcFeatureEnabled(avr.getPortId()); + return isConnected(avr.getPortId()) + && isArcFeatureEnabled(avr.getPortId()) + && isDirectConnectAddress(avr.getPhysicalAddress()); } else { return true; } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 87a908c10721..4e04b72baab2 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -187,10 +187,6 @@ public class HdmiControlService extends SystemService { @GuardedBy("mLock") private boolean mSystemAudioActivated = false; - private static final boolean isHdmiCecNeverClaimPlaybackLogicAddr = - SystemProperties.getBoolean( - Constants.PROPERTY_HDMI_CEC_NEVER_CLAIM_PLAYBACK_LOGICAL_ADDRESS, false); - /** * Interface to report send result. */ @@ -789,10 +785,6 @@ public class HdmiControlService extends SystemService { // A container for [Device type, Local device info]. ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>(); for (int type : mLocalDevices) { - if (type == HdmiDeviceInfo.DEVICE_PLAYBACK - && isHdmiCecNeverClaimPlaybackLogicAddr) { - continue; - } HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(type); if (localDevice == null) { localDevice = HdmiCecLocalDevice.create(this, type); @@ -1207,10 +1199,6 @@ public class HdmiControlService extends SystemService { } ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>(); for (int type : mLocalDevices) { - if (type == HdmiDeviceInfo.DEVICE_PLAYBACK - && isHdmiCecNeverClaimPlaybackLogicAddr) { - continue; - } HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(type); if (localDevice == null) { localDevice = HdmiCecLocalDevice.create(this, type); diff --git a/services/core/java/com/android/server/hdmi/HdmiLogger.java b/services/core/java/com/android/server/hdmi/HdmiLogger.java index 8da3c93de360..01040642add8 100644 --- a/services/core/java/com/android/server/hdmi/HdmiLogger.java +++ b/services/core/java/com/android/server/hdmi/HdmiLogger.java @@ -18,9 +18,9 @@ package com.android.server.hdmi; import android.annotation.Nullable; import android.os.SystemClock; -import android.util.Log; import android.util.Pair; import android.util.Slog; +import android.util.Log; import java.util.HashMap; @@ -71,7 +71,7 @@ final class HdmiLogger { getLogger().errorInternal(toLogString(logMessage, objs)); } - static void error(String logMessage, Exception e, Object... objs) { + static final void error(String logMessage, Exception e, Object... objs) { getLogger().errorInternal(toLogString(logMessage + e, objs)); } diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java index e3e02e32ad50..f0bf5c0975f2 100644 --- a/services/core/java/com/android/server/net/IpConfigStore.java +++ b/services/core/java/com/android/server/net/IpConfigStore.java @@ -24,6 +24,7 @@ import android.net.NetworkUtils; import android.net.ProxyInfo; import android.net.RouteInfo; import android.net.StaticIpConfiguration; +import android.net.Uri; import android.util.ArrayMap; import android.util.Log; import android.util.SparseArray; @@ -372,7 +373,7 @@ public class IpConfigStore { config.httpProxy = proxyInfo; break; case PAC: - ProxyInfo proxyPacProperties = new ProxyInfo(pacFileUrl); + ProxyInfo proxyPacProperties = new ProxyInfo(Uri.parse(pacFileUrl)); config.proxySettings = proxySettings; config.httpProxy = proxyPacProperties; break; diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index ba9f486092f7..71e7c8adc5db 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -87,6 +87,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.database.ContentObserver; import android.net.DataUsageRequest; import android.net.INetworkManagementEventObserver; import android.net.INetworkStatsService; @@ -103,6 +104,7 @@ import android.net.NetworkStats.NonMonotonicObserver; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.TrafficStats; +import android.net.Uri; import android.net.netstats.provider.INetworkStatsProvider; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.netstats.provider.NetworkStatsProvider; @@ -213,6 +215,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final boolean mUseBpfTrafficStats; + private final ContentObserver mContentObserver; + private final ContentResolver mContentResolver; + @VisibleForTesting public static final String ACTION_NETWORK_STATS_POLL = "com.android.server.action.NETWORK_STATS_POLL"; @@ -437,7 +442,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { handlerThread.start(); mHandler = new NetworkStatsHandler(handlerThread.getLooper()); mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext, - new HandlerExecutor(mHandler), this); + mHandler.getLooper(), new HandlerExecutor(mHandler), this); + mContentResolver = mContext.getContentResolver(); + mContentObserver = mDeps.makeContentObserver(mHandler, mSettings, + mNetworkStatsSubscriptionsMonitor); } /** @@ -460,11 +468,31 @@ public class NetworkStatsService extends INetworkStatsService.Stub { */ @NonNull public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context, - @NonNull Executor executor, @NonNull NetworkStatsService service) { + @NonNull Looper looper, @NonNull Executor executor, + @NonNull NetworkStatsService service) { // TODO: Update RatType passively in NSS, instead of querying into the monitor // when forceUpdateIface. - return new NetworkStatsSubscriptionsMonitor(context, executor, (subscriberId, type) -> - service.handleOnCollapsedRatTypeChanged()); + return new NetworkStatsSubscriptionsMonitor(context, looper, executor, + (subscriberId, type) -> service.handleOnCollapsedRatTypeChanged()); + } + + /** + * Create a ContentObserver instance which is used to observe settings changes, + * and dispatch onChange events on handler thread. + */ + public @NonNull ContentObserver makeContentObserver(@NonNull Handler handler, + @NonNull NetworkStatsSettings settings, + @NonNull NetworkStatsSubscriptionsMonitor monitor) { + return new ContentObserver(handler) { + @Override + public void onChange(boolean selfChange, @NonNull Uri uri) { + if (!settings.getCombineSubtypeEnabled()) { + monitor.start(); + } else { + monitor.stop(); + } + } + }; } } @@ -530,11 +558,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, mSettings.getPollInterval(), pollIntent); - // TODO: listen to settings changed to support dynamically enable/disable. - // watch for networkType changes - if (!mSettings.getCombineSubtypeEnabled()) { - mNetworkStatsSubscriptionsMonitor.start(); - } + mContentResolver.registerContentObserver(Settings.Global + .getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED), + false /* notifyForDescendants */, mContentObserver); + + // Post a runnable on handler thread to call onChange(). It's for getting current value of + // NETSTATS_COMBINE_SUBTYPE_ENABLED to decide start or stop monitoring RAT type changes. + mHandler.post(() -> mContentObserver.onChange(false, Settings.Global + .getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED))); registerGlobalAlert(); } @@ -560,6 +591,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mNetworkStatsSubscriptionsMonitor.stop(); } + mContentResolver.unregisterContentObserver(mContentObserver); + final long currentTime = mClock.millis(); // persist any pending stats diff --git a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java index cb1c7e4fd0de..0575ac6315a1 100644 --- a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java +++ b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java @@ -21,6 +21,7 @@ import static android.net.NetworkTemplate.getCollapsedRatType; import android.annotation.NonNull; import android.content.Context; +import android.os.Looper; import android.telephony.Annotation; import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; @@ -77,9 +78,9 @@ public class NetworkStatsSubscriptionsMonitor extends @NonNull private final Executor mExecutor; - NetworkStatsSubscriptionsMonitor(@NonNull Context context, @NonNull Executor executor, - @NonNull Delegate delegate) { - super(); + NetworkStatsSubscriptionsMonitor(@NonNull Context context, @NonNull Looper looper, + @NonNull Executor executor, @NonNull Delegate delegate) { + super(looper); mSubscriptionManager = (SubscriptionManager) context.getSystemService( Context.TELEPHONY_SUBSCRIPTION_SERVICE); mTeleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 2fe783387e23..d4a57884879b 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -6968,6 +6968,10 @@ public class NotificationManagerService extends SystemService { if (isInCall() || mScreenOn) { return false; } + // check current user + if (!isNotificationForCurrentUser(record)) { + return false; + } return true; } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 4931d3f3e95c..5417275bc8f1 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -869,13 +869,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/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index d9d949154ce1..e12cb8f533a7 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -77,6 +77,8 @@ public abstract class ApexManager { public static final int MATCH_ACTIVE_PACKAGE = 1 << 0; static final int MATCH_FACTORY_PACKAGE = 1 << 1; + private static final String VNDK_APEX_MODULE_NAME_PREFIX = "com.android.vndk."; + private static final Singleton<ApexManager> sApexManagerSingleton = new Singleton<ApexManager>() { @Override @@ -521,7 +523,9 @@ public abstract class ApexManager { activePackagesSet.add(packageInfo.packageName); } if (ai.isFactory) { - if (factoryPackagesSet.contains(packageInfo.packageName)) { + // Don't throw when the duplicating APEX is VNDK APEX + if (factoryPackagesSet.contains(packageInfo.packageName) + && !ai.moduleName.startsWith(VNDK_APEX_MODULE_NAME_PREFIX)) { throw new IllegalStateException( "Two factory packages have the same name: " + packageInfo.packageName); diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS index f8c173f6a9c1..fe6aad70c31e 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -10,8 +10,8 @@ toddke@android.com toddke@google.com # apex support -per-file ApexManager.java = dariofreni@google.com -per-file StagingManager.java = dariofreni@google.com +per-file ApexManager.java = dariofreni@google.com, ioffe@google.com, olilan@google.com +per-file StagingManager.java = dariofreni@google.com, ioffe@google.com, olilan@google.com # dex per-file AbstractStatsBase.java = agampe@google.com, calin@google.com, ngeoffray@google.com @@ -30,8 +30,9 @@ per-file CrossProfileAppsServiceImpl.java = omakoto@google.com, yamasani@google. per-file CrossProfileAppsService.java = omakoto@google.com, yamasani@google.com per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com -per-file UserManagerService.java = omakoto@google.com, yamasani@google.com +per-file UserManagerService.java = bookatz@google.com, omakoto@google.com, yamasani@google.com per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com +per-file RestrictionsSet.java = bookatz@google.com, omakoto@google.com, yamasani@google.com, rubinxu@google.com, sandness@google.com per-file UserSystemPackageInstaller.java = bookatz@google.com, omakoto@google.com, yamasani@google.com per-file UserTypeDetails.java = bookatz@google.com, omakoto@google.com, yamasani@google.com per-file UserTypeFactory.java = bookatz@google.com, omakoto@google.com, yamasani@google.com 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/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java index 734b71824490..de06c92e8dae 100644 --- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java +++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java @@ -49,11 +49,8 @@ import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.EventLogTags; import com.android.server.SystemService; -import com.android.server.pm.InstructionSets; import com.android.server.pm.PackageManagerService; -import dalvik.system.VMRuntime; - import java.io.File; import java.io.FileDescriptor; import java.io.IOException; @@ -214,7 +211,7 @@ public class DeviceStorageMonitorService extends SystemService { newLevel = State.LEVEL_FULL; } else if (usableBytes <= lowBytes) { newLevel = State.LEVEL_LOW; - } else if (StorageManager.UUID_DEFAULT.equals(uuid) && !isBootImageOnDisk() + } else if (StorageManager.UUID_DEFAULT.equals(uuid) && usableBytes < BOOT_IMAGE_STORAGE_REQUIREMENT) { newLevel = State.LEVEL_LOW; } else { @@ -261,15 +258,6 @@ public class DeviceStorageMonitorService extends SystemService { }; } - private static boolean isBootImageOnDisk() { - for (String instructionSet : InstructionSets.getAllDexCodeInstructionSets()) { - if (!VMRuntime.isBootClassPathOnDisk(instructionSet)) { - return false; - } - } - return true; - } - @Override public void onStart() { final Context context = getContext(); @@ -481,15 +469,8 @@ public class DeviceStorageMonitorService extends SystemService { final CharSequence title = context.getText( com.android.internal.R.string.low_internal_storage_view_title); - final CharSequence details; - if (StorageManager.UUID_DEFAULT.equals(uuid)) { - details = context.getText(isBootImageOnDisk() - ? com.android.internal.R.string.low_internal_storage_view_text - : com.android.internal.R.string.low_internal_storage_view_text_no_boot); - } else { - details = context.getText( - com.android.internal.R.string.low_internal_storage_view_text); - } + final CharSequence details = context.getText( + com.android.internal.R.string.low_internal_storage_view_text); PendingIntent intent = PendingIntent.getActivityAsUser(context, 0, lowMemIntent, 0, null, UserHandle.CURRENT); diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java index bbd1ae60cb62..fd5c6e91a885 100644 --- a/services/core/java/com/android/server/timezone/RulesManagerService.java +++ b/services/core/java/com/android/server/timezone/RulesManagerService.java @@ -37,6 +37,10 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.Slog; +import com.android.i18n.timezone.TimeZoneDataFiles; +import com.android.i18n.timezone.TimeZoneFinder; +import com.android.i18n.timezone.TzDataSetVersion; +import com.android.i18n.timezone.ZoneInfoDb; import com.android.internal.annotations.VisibleForTesting; import com.android.server.EventLogTags; import com.android.server.SystemService; @@ -46,10 +50,6 @@ import com.android.timezone.distro.StagedDistroOperation; import com.android.timezone.distro.TimeZoneDistro; import com.android.timezone.distro.installer.TimeZoneDistroInstaller; -import libcore.timezone.TimeZoneDataFiles; -import libcore.timezone.TimeZoneFinder; -import libcore.timezone.TzDataSetVersion; -import libcore.timezone.ZoneInfoDb; import java.io.File; import java.io.FileDescriptor; diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 925ad0f57f19..e8972742f8e2 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -31,7 +31,6 @@ cc_library_static { "com_android_server_devicepolicy_CryptoTestHelper.cpp", "com_android_server_gpu_GpuService.cpp", "com_android_server_HardwarePropertiesManagerService.cpp", - "com_android_server_hdmi_HdmiCecController.cpp", "com_android_server_input_InputManagerService.cpp", "com_android_server_lights_LightsService.cpp", "com_android_server_location_GnssLocationProvider.cpp", @@ -152,7 +151,6 @@ cc_defaults { "android.hardware.power-cpp", "android.hardware.power.stats@1.0", "android.hardware.thermal@1.0", - "android.hardware.tv.cec@1.0", "android.hardware.tv.input@1.0", "android.hardware.vibrator-cpp", "android.hardware.vibrator@1.0", diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp index e79612fbf3d3..335040a4b92f 100644 --- a/services/core/jni/com_android_server_AlarmManagerService.cpp +++ b/services/core/jni/com_android_server_AlarmManagerService.cpp @@ -1,5 +1,4 @@ -/* //device/libs/android_runtime/android_server_AlarmManagerService.cpp -** +/* ** Copyright 2006, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,6 +18,8 @@ #include <nativehelper/JNIHelp.h> #include "jni.h" +#include <android-base/file.h> +#include <android-base/unique_fd.h> #include <utils/Log.h> #include <utils/misc.h> #include <utils/String8.h> @@ -40,6 +41,7 @@ #include <linux/rtc.h> #include <array> +#include <limits> #include <memory> namespace android { @@ -74,8 +76,8 @@ typedef std::array<int, N_ANDROID_TIMERFDS> TimerFds; class AlarmImpl { public: - AlarmImpl(const TimerFds &fds, int epollfd, int rtc_id) : - fds{fds}, epollfd{epollfd}, rtc_id{rtc_id} { } + AlarmImpl(const TimerFds &fds, int epollfd, const std::string& rtc_dev) : + fds{fds}, epollfd{epollfd}, rtc_dev{rtc_dev} { } ~AlarmImpl(); int set(int type, struct timespec *ts); @@ -86,7 +88,7 @@ public: private: const TimerFds fds; const int epollfd; - const int rtc_id; + std::string rtc_dev; }; AlarmImpl::~AlarmImpl() @@ -131,38 +133,24 @@ int AlarmImpl::getTime(int type, struct itimerspec *spec) int AlarmImpl::setTime(struct timeval *tv) { - struct rtc_time rtc; - struct tm tm, *gmtime_res; - int fd; - int res; - - res = settimeofday(tv, NULL); - if (res < 0) { - ALOGV("settimeofday() failed: %s\n", strerror(errno)); + if (settimeofday(tv, NULL) == -1) { + ALOGV("settimeofday() failed: %s", strerror(errno)); return -1; } - if (rtc_id < 0) { - ALOGV("Not setting RTC because wall clock RTC was not found"); - errno = ENODEV; + android::base::unique_fd fd{open(rtc_dev.c_str(), O_RDWR)}; + if (!fd.ok()) { + ALOGE("Unable to open %s: %s", rtc_dev.c_str(), strerror(errno)); return -1; } - android::String8 rtc_dev = String8::format("/dev/rtc%d", rtc_id); - fd = open(rtc_dev.string(), O_RDWR); - if (fd < 0) { - ALOGV("Unable to open %s: %s\n", rtc_dev.string(), strerror(errno)); - return res; - } - - gmtime_res = gmtime_r(&tv->tv_sec, &tm); - if (!gmtime_res) { - ALOGV("gmtime_r() failed: %s\n", strerror(errno)); - res = -1; - goto done; + struct tm tm; + if (!gmtime_r(&tv->tv_sec, &tm)) { + ALOGV("gmtime_r() failed: %s", strerror(errno)); + return -1; } - memset(&rtc, 0, sizeof(rtc)); + struct rtc_time rtc = {}; rtc.tm_sec = tm.tm_sec; rtc.tm_min = tm.tm_min; rtc.tm_hour = tm.tm_hour; @@ -172,12 +160,12 @@ int AlarmImpl::setTime(struct timeval *tv) rtc.tm_wday = tm.tm_wday; rtc.tm_yday = tm.tm_yday; rtc.tm_isdst = tm.tm_isdst; - res = ioctl(fd, RTC_SET_TIME, &rtc); - if (res < 0) - ALOGV("RTC_SET_TIME ioctl failed: %s\n", strerror(errno)); -done: - close(fd); - return res; + if (ioctl(fd, RTC_SET_TIME, &rtc) == -1) { + ALOGV("RTC_SET_TIME ioctl failed: %s", strerror(errno)); + return -1; + } + + return 0; } int AlarmImpl::waitForAlarm() @@ -213,22 +201,20 @@ int AlarmImpl::waitForAlarm() static jint android_server_AlarmManagerService_setKernelTime(JNIEnv*, jobject, jlong nativeData, jlong millis) { AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); - struct timeval tv; - int ret; - if (millis <= 0 || millis / 1000LL >= INT_MAX) { + if (millis <= 0 || millis / 1000LL >= std::numeric_limits<time_t>::max()) { return -1; } - tv.tv_sec = (time_t) (millis / 1000LL); - tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL); - - ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec); + struct timeval tv; + tv.tv_sec = (millis / 1000LL); + tv.tv_usec = ((millis % 1000LL) * 1000LL); - ret = impl->setTime(&tv); + ALOGD("Setting time of day to sec=%ld", tv.tv_sec); - if(ret < 0) { - ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno)); + int ret = impl->setTime(&tv); + if (ret < 0) { + ALOGW("Unable to set rtc to %ld: %s", tv.tv_sec, strerror(errno)); ret = -1; } return ret; @@ -252,65 +238,6 @@ static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobjec return 0; } -static const char rtc_sysfs[] = "/sys/class/rtc"; - -static bool rtc_is_hctosys(unsigned int rtc_id) -{ - android::String8 hctosys_path = String8::format("%s/rtc%u/hctosys", - rtc_sysfs, rtc_id); - FILE *file = fopen(hctosys_path.string(), "re"); - if (!file) { - ALOGE("failed to open %s: %s", hctosys_path.string(), strerror(errno)); - return false; - } - - unsigned int hctosys; - bool ret = false; - int err = fscanf(file, "%u", &hctosys); - if (err == EOF) - ALOGE("failed to read from %s: %s", hctosys_path.string(), - strerror(errno)); - else if (err == 0) - ALOGE("%s did not have expected contents", hctosys_path.string()); - else - ret = hctosys; - - fclose(file); - return ret; -} - -static int wall_clock_rtc() -{ - std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(rtc_sysfs), closedir); - if (!dir.get()) { - ALOGE("failed to open %s: %s", rtc_sysfs, strerror(errno)); - return -1; - } - - struct dirent *dirent; - while (errno = 0, dirent = readdir(dir.get())) { - unsigned int rtc_id; - int matched = sscanf(dirent->d_name, "rtc%u", &rtc_id); - - if (matched < 0) - break; - else if (matched != 1) - continue; - - if (rtc_is_hctosys(rtc_id)) { - ALOGV("found wall clock RTC %u", rtc_id); - return rtc_id; - } - } - - if (errno == 0) - ALOGW("no wall clock RTC found"); - else - ALOGE("failed to enumerate RTCs: %s", strerror(errno)); - - return -1; -} - static void log_timerfd_create_error(clockid_t id) { if (errno == EINVAL) { @@ -344,8 +271,7 @@ static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) epollfd = epoll_create(fds.size()); if (epollfd < 0) { - ALOGE("epoll_create(%zu) failed: %s", fds.size(), - strerror(errno)); + ALOGE("epoll_create(%zu) failed: %s", fds.size(), strerror(errno)); return 0; } @@ -361,7 +287,19 @@ static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) } } - AlarmImpl *ret = new AlarmImpl(fds, epollfd, wall_clock_rtc()); + // Find the wall clock RTC. We expect this always to be /dev/rtc0, but + // check the /dev/rtc symlink first so that legacy devices that don't use + // rtc0 can add a symlink rather than need to carry a local patch to this + // code. + // + // TODO: if you're reading this in a world where all devices are using the + // GKI, you can remove the readlink and just assume /dev/rtc0. + std::string dev_rtc; + if (!android::base::Readlink("/dev/rtc", &dev_rtc)) { + dev_rtc = "/dev/rtc0"; + } + + std::unique_ptr<AlarmImpl> alarm{new AlarmImpl(fds, epollfd, dev_rtc)}; for (size_t i = 0; i < fds.size(); i++) { epoll_event event; @@ -371,13 +309,11 @@ static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) int err = epoll_ctl(epollfd, EPOLL_CTL_ADD, fds[i], &event); if (err < 0) { ALOGE("epoll_ctl(EPOLL_CTL_ADD) failed: %s", strerror(errno)); - delete ret; return 0; } } - struct itimerspec spec; - memset(&spec, 0, sizeof(spec)); + struct itimerspec spec = {}; /* 0 = disarmed; the timerfd doesn't need to be armed to get RTC change notifications, just set up as cancelable */ @@ -385,11 +321,10 @@ static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, NULL); if (err < 0) { ALOGE("timerfd_settime() failed: %s", strerror(errno)); - delete ret; return 0; } - return reinterpret_cast<jlong>(ret); + return reinterpret_cast<jlong>(alarm.release()); } static jlong android_server_AlarmManagerService_getNextAlarm(JNIEnv*, jobject, jlong nativeData, jint type) diff --git a/services/core/jni/com_android_server_SerialService.cpp b/services/core/jni/com_android_server_SerialService.cpp index aef0b25503c8..6600c981b68d 100644 --- a/services/core/jni/com_android_server_SerialService.cpp +++ b/services/core/jni/com_android_server_SerialService.cpp @@ -18,7 +18,7 @@ #include "utils/Log.h" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "android_runtime/AndroidRuntime.h" #include <sys/types.h> @@ -48,6 +48,7 @@ static jobject android_server_SerialService_open(JNIEnv *env, jobject /* thiz */ jobject fileDescriptor = jniCreateFileDescriptor(env, fd); if (fileDescriptor == NULL) { + close(fd); return NULL; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, diff --git a/services/core/jni/com_android_server_UsbDeviceManager.cpp b/services/core/jni/com_android_server_UsbDeviceManager.cpp index ff1ec04cb23e..3ab5920d8b59 100644 --- a/services/core/jni/com_android_server_UsbDeviceManager.cpp +++ b/services/core/jni/com_android_server_UsbDeviceManager.cpp @@ -18,7 +18,8 @@ #include "utils/Log.h" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> +#include <nativehelper/ScopedUtfChars.h> #include "android_runtime/AndroidRuntime.h" #include "android_runtime/Log.h" #include "MtpDescriptors.h" @@ -88,6 +89,7 @@ static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobjec } jobject fileDescriptor = jniCreateFileDescriptor(env, fd); if (fileDescriptor == NULL) { + close(fd); return NULL; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, @@ -120,35 +122,30 @@ static jint android_server_UsbDeviceManager_getAudioMode(JNIEnv* /* env */, jobj } static jobject android_server_UsbDeviceManager_openControl(JNIEnv *env, jobject /* thiz */, jstring jFunction) { - const char *function = env->GetStringUTFChars(jFunction, NULL); + ScopedUtfChars function(env, jFunction); bool ptp = false; int fd = -1; - if (!strcmp(function, "ptp")) { + if (!strcmp(function.c_str(), "ptp")) { ptp = true; } - if (!strcmp(function, "mtp") || ptp) { + if (!strcmp(function.c_str(), "mtp") || ptp) { fd = TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP0 : FFS_MTP_EP0, O_RDWR)); if (fd < 0) { - ALOGE("could not open control for %s %s", function, strerror(errno)); - goto error; + ALOGE("could not open control for %s %s", function.c_str(), strerror(errno)); + return NULL; } if (!writeDescriptors(fd, ptp)) { - goto error; + close(fd); + return NULL; } } - if (function != NULL) { - env->ReleaseStringUTFChars(jFunction, function); - } - return jniCreateFileDescriptor(env, fd); -error: - if (fd != -1) { + jobject jifd = jniCreateFileDescriptor(env, fd); + if (jifd == NULL) { + // OutOfMemoryError will be pending. close(fd); } - if (function != NULL) { - env->ReleaseStringUTFChars(jFunction, function); - } - return NULL; + return jifd; } static const JNINativeMethod method_table[] = { diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp index 24f2014afa30..a629b69c1c27 100644 --- a/services/core/jni/com_android_server_UsbHostManager.cpp +++ b/services/core/jni/com_android_server_UsbHostManager.cpp @@ -18,7 +18,7 @@ #include "utils/Log.h" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include "android_runtime/AndroidRuntime.h" #include "android_runtime/Log.h" @@ -134,6 +134,7 @@ static jobject android_server_UsbHostManager_openDevice(JNIEnv *env, jobject /* jobject fileDescriptor = jniCreateFileDescriptor(env, newFD); if (fileDescriptor == NULL) { + close(newFD); return NULL; } return env->NewObject(gParcelFileDescriptorOffsets.mClass, diff --git a/services/core/jni/com_android_server_UsbMidiDevice.cpp b/services/core/jni/com_android_server_UsbMidiDevice.cpp index 79d935fe610c..d6b5bed173eb 100644 --- a/services/core/jni/com_android_server_UsbMidiDevice.cpp +++ b/services/core/jni/com_android_server_UsbMidiDevice.cpp @@ -19,7 +19,8 @@ #include "utils/Log.h" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> +#include <nativehelper/ScopedLocalRef.h> #include "android_runtime/AndroidRuntime.h" #include "android_runtime/Log.h" @@ -99,24 +100,45 @@ android_server_UsbMidiDevice_open(JNIEnv *env, jobject thiz, jint card, jint dev int fd = open(path, O_RDWR); if (fd < 0) { ALOGE("open failed on %s for index %d", path, i); - return NULL; + goto release_fds; } - - jobject fileDescriptor = jniCreateFileDescriptor(env, fd); - env->SetObjectArrayElement(fds, i, fileDescriptor); - env->DeleteLocalRef(fileDescriptor); + ScopedLocalRef<jobject> jifd(env, jniCreateFileDescriptor(env, fd)); + if (jifd.get() == NULL) { + goto release_fds; + } + env->SetObjectArrayElement(fds, i, jifd.get()); } // create a pipe to use for unblocking our input thread - int pipeFD[2]; - pipe(pipeFD); - jobject fileDescriptor = jniCreateFileDescriptor(env, pipeFD[0]); - env->SetObjectArrayElement(fds, subdevice_count, fileDescriptor); - env->DeleteLocalRef(fileDescriptor); - // store our end of the pipe in mPipeFD - env->SetIntField(thiz, sPipeFDField, pipeFD[1]); + { + int pipeFD[2]; + if (pipe(pipeFD) == -1) { + ALOGE("pipe() failed, errno = %d", errno); + goto release_fds; + } + ScopedLocalRef<jobject> jifd(env, jniCreateFileDescriptor(env, pipeFD[0])); + if (jifd.get() == NULL) { + close(pipeFD[0]); + close(pipeFD[1]); + goto release_fds; + } + env->SetObjectArrayElement(fds, subdevice_count, jifd.get()); + // store our end of the pipe in mPipeFD + env->SetIntField(thiz, sPipeFDField, pipeFD[1]); + } return fds; + +release_fds: + for (int i = 0; i < subdevice_count + 1; ++i) { + ScopedLocalRef<jobject> jifd(env, env->GetObjectArrayElement(fds, i)); + if (jifd.get() == NULL) { + break; + } + int fd = jniGetFDFromFileDescriptor(env, jifd.get()); + close(fd); + } + return NULL; } static void diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp deleted file mode 100644 index b08d13f234ce..000000000000 --- a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (C) 2014 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. - */ - -#define LOG_TAG "HdmiCecControllerJni" - -#define LOG_NDEBUG 1 - -#include <nativehelper/JNIHelp.h> -#include <nativehelper/ScopedPrimitiveArray.h> - -#include <android/hardware/tv/cec/1.0/IHdmiCec.h> -#include <android/hardware/tv/cec/1.0/IHdmiCecCallback.h> -#include <android/hardware/tv/cec/1.0/types.h> -#include <android_os_MessageQueue.h> -#include <android_runtime/AndroidRuntime.h> -#include <android_runtime/Log.h> -#include <sys/param.h> -#include <utils/Errors.h> -#include <utils/Looper.h> -#include <utils/RefBase.h> - -using ::android::hardware::tv::cec::V1_0::CecLogicalAddress; -using ::android::hardware::tv::cec::V1_0::CecMessage; -using ::android::hardware::tv::cec::V1_0::HdmiPortInfo; -using ::android::hardware::tv::cec::V1_0::HotplugEvent; -using ::android::hardware::tv::cec::V1_0::IHdmiCec; -using ::android::hardware::tv::cec::V1_0::IHdmiCecCallback; -using ::android::hardware::tv::cec::V1_0::MaxLength; -using ::android::hardware::tv::cec::V1_0::OptionKey; -using ::android::hardware::tv::cec::V1_0::Result; -using ::android::hardware::tv::cec::V1_0::SendMessageResult; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::hidl_vec; -using ::android::hardware::hidl_string; - -namespace android { - -static struct { - jmethodID handleIncomingCecCommand; - jmethodID handleHotplug; -} gHdmiCecControllerClassInfo; - -class HdmiCecController { -public: - HdmiCecController(sp<IHdmiCec> hdmiCec, jobject callbacksObj, const sp<Looper>& looper); - ~HdmiCecController(); - - // Send message to other device. Note that it runs in IO thread. - int sendMessage(const CecMessage& message); - // Add a logical address to device. - int addLogicalAddress(CecLogicalAddress address); - // Clear all logical address registered to the device. - void clearLogicaladdress(); - // Get physical address of device. - int getPhysicalAddress(); - // Get CEC version from driver. - int getVersion(); - // Get vendor id used for vendor command. - uint32_t getVendorId(); - // Get Port information on all the HDMI ports. - jobjectArray getPortInfos(); - // Set an option to CEC HAL. - void setOption(OptionKey key, bool enabled); - // Informs CEC HAL about the current system language. - void setLanguage(hidl_string language); - // Enable audio return channel. - void enableAudioReturnChannel(int port, bool flag); - // Whether to hdmi device is connected to the given port. - bool isConnected(int port); - - jobject getCallbacksObj() const { - return mCallbacksObj; - } - -private: - class HdmiCecCallback : public IHdmiCecCallback { - public: - explicit HdmiCecCallback(HdmiCecController* controller) : mController(controller) {}; - Return<void> onCecMessage(const CecMessage& event) override; - Return<void> onHotplugEvent(const HotplugEvent& event) override; - private: - HdmiCecController* mController; - }; - - static const int INVALID_PHYSICAL_ADDRESS = 0xFFFF; - - sp<IHdmiCec> mHdmiCec; - jobject mCallbacksObj; - sp<IHdmiCecCallback> mHdmiCecCallback; - sp<Looper> mLooper; -}; - -// Handler class to delegate incoming message to service thread. -class HdmiCecEventHandler : public MessageHandler { -public: - enum EventType { - CEC_MESSAGE, - HOT_PLUG - }; - - HdmiCecEventHandler(HdmiCecController* controller, const CecMessage& cecMessage) - : mController(controller), - mCecMessage(cecMessage) {} - - HdmiCecEventHandler(HdmiCecController* controller, const HotplugEvent& hotplugEvent) - : mController(controller), - mHotplugEvent(hotplugEvent) {} - - virtual ~HdmiCecEventHandler() {} - - void handleMessage(const Message& message) { - switch (message.what) { - case EventType::CEC_MESSAGE: - propagateCecCommand(mCecMessage); - break; - case EventType::HOT_PLUG: - propagateHotplugEvent(mHotplugEvent); - break; - default: - // TODO: add more type whenever new type is introduced. - break; - } - } - -private: - // Propagate the message up to Java layer. - void propagateCecCommand(const CecMessage& message) { - JNIEnv* env = AndroidRuntime::getJNIEnv(); - jint srcAddr = static_cast<jint>(message.initiator); - jint dstAddr = static_cast<jint>(message.destination); - jbyteArray body = env->NewByteArray(message.body.size()); - const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body.data()); - env->SetByteArrayRegion(body, 0, message.body.size(), bodyPtr); - env->CallVoidMethod(mController->getCallbacksObj(), - gHdmiCecControllerClassInfo.handleIncomingCecCommand, srcAddr, - dstAddr, body); - env->DeleteLocalRef(body); - - checkAndClearExceptionFromCallback(env, __FUNCTION__); - } - - void propagateHotplugEvent(const HotplugEvent& event) { - // Note that this method should be called in service thread. - JNIEnv* env = AndroidRuntime::getJNIEnv(); - jint port = static_cast<jint>(event.portId); - jboolean connected = (jboolean) event.connected; - env->CallVoidMethod(mController->getCallbacksObj(), - gHdmiCecControllerClassInfo.handleHotplug, port, connected); - - checkAndClearExceptionFromCallback(env, __FUNCTION__); - } - - // static - static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { - if (env->ExceptionCheck()) { - ALOGE("An exception was thrown by callback '%s'.", methodName); - LOGE_EX(env); - env->ExceptionClear(); - } - } - - HdmiCecController* mController; - CecMessage mCecMessage; - HotplugEvent mHotplugEvent; -}; - -HdmiCecController::HdmiCecController(sp<IHdmiCec> hdmiCec, - jobject callbacksObj, const sp<Looper>& looper) - : mHdmiCec(hdmiCec), - mCallbacksObj(callbacksObj), - mLooper(looper) { - mHdmiCecCallback = new HdmiCecCallback(this); - Return<void> ret = mHdmiCec->setCallback(mHdmiCecCallback); - if (!ret.isOk()) { - ALOGE("Failed to set a cec callback."); - } -} - -HdmiCecController::~HdmiCecController() { - Return<void> ret = mHdmiCec->setCallback(nullptr); - if (!ret.isOk()) { - ALOGE("Failed to set a cec callback."); - } -} - -int HdmiCecController::sendMessage(const CecMessage& message) { - // TODO: propagate send_message's return value. - Return<SendMessageResult> ret = mHdmiCec->sendMessage(message); - if (!ret.isOk()) { - ALOGE("Failed to send CEC message."); - return static_cast<int>(SendMessageResult::FAIL); - } - return static_cast<int>((SendMessageResult) ret); -} - -int HdmiCecController::addLogicalAddress(CecLogicalAddress address) { - Return<Result> ret = mHdmiCec->addLogicalAddress(address); - if (!ret.isOk()) { - ALOGE("Failed to add a logical address."); - return static_cast<int>(Result::FAILURE_UNKNOWN); - } - return static_cast<int>((Result) ret); -} - -void HdmiCecController::clearLogicaladdress() { - Return<void> ret = mHdmiCec->clearLogicalAddress(); - if (!ret.isOk()) { - ALOGE("Failed to clear logical address."); - } -} - -int HdmiCecController::getPhysicalAddress() { - Result result; - uint16_t addr; - Return<void> ret = mHdmiCec->getPhysicalAddress([&result, &addr](Result res, uint16_t paddr) { - result = res; - addr = paddr; - }); - if (!ret.isOk()) { - ALOGE("Failed to get physical address."); - return INVALID_PHYSICAL_ADDRESS; - } - return result == Result::SUCCESS ? addr : INVALID_PHYSICAL_ADDRESS; -} - -int HdmiCecController::getVersion() { - Return<int32_t> ret = mHdmiCec->getCecVersion(); - if (!ret.isOk()) { - ALOGE("Failed to get cec version."); - } - return ret; -} - -uint32_t HdmiCecController::getVendorId() { - Return<uint32_t> ret = mHdmiCec->getVendorId(); - if (!ret.isOk()) { - ALOGE("Failed to get vendor id."); - } - return ret; -} - -jobjectArray HdmiCecController::getPortInfos() { - JNIEnv* env = AndroidRuntime::getJNIEnv(); - jclass hdmiPortInfo = env->FindClass("android/hardware/hdmi/HdmiPortInfo"); - if (hdmiPortInfo == NULL) { - return NULL; - } - jmethodID ctor = env->GetMethodID(hdmiPortInfo, "<init>", "(IIIZZZ)V"); - if (ctor == NULL) { - return NULL; - } - hidl_vec<HdmiPortInfo> ports; - Return<void> ret = mHdmiCec->getPortInfo([&ports](hidl_vec<HdmiPortInfo> list) { - ports = list; - }); - if (!ret.isOk()) { - ALOGE("Failed to get port information."); - return NULL; - } - jobjectArray res = env->NewObjectArray(ports.size(), hdmiPortInfo, NULL); - - // MHL support field will be obtained from MHL HAL. Leave it to false. - jboolean mhlSupported = (jboolean) 0; - for (size_t i = 0; i < ports.size(); ++i) { - jboolean cecSupported = (jboolean) ports[i].cecSupported; - jboolean arcSupported = (jboolean) ports[i].arcSupported; - jobject infoObj = env->NewObject(hdmiPortInfo, ctor, ports[i].portId, ports[i].type, - ports[i].physicalAddress, cecSupported, mhlSupported, arcSupported); - env->SetObjectArrayElement(res, i, infoObj); - } - return res; -} - -void HdmiCecController::setOption(OptionKey key, bool enabled) { - Return<void> ret = mHdmiCec->setOption(key, enabled); - if (!ret.isOk()) { - ALOGE("Failed to set option."); - } -} - -void HdmiCecController::setLanguage(hidl_string language) { - Return<void> ret = mHdmiCec->setLanguage(language); - if (!ret.isOk()) { - ALOGE("Failed to set language."); - } -} - -// Enable audio return channel. -void HdmiCecController::enableAudioReturnChannel(int port, bool enabled) { - Return<void> ret = mHdmiCec->enableAudioReturnChannel(port, enabled); - if (!ret.isOk()) { - ALOGE("Failed to enable/disable ARC."); - } -} - -// Whether to hdmi device is connected to the given port. -bool HdmiCecController::isConnected(int port) { - Return<bool> ret = mHdmiCec->isConnected(port); - if (!ret.isOk()) { - ALOGE("Failed to get connection info."); - } - return ret; -} - -Return<void> HdmiCecController::HdmiCecCallback::onCecMessage(const CecMessage& message) { - sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(mController, message)); - mController->mLooper->sendMessage(handler, HdmiCecEventHandler::EventType::CEC_MESSAGE); - return Void(); -} - -Return<void> HdmiCecController::HdmiCecCallback::onHotplugEvent(const HotplugEvent& event) { - sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(mController, event)); - mController->mLooper->sendMessage(handler, HdmiCecEventHandler::EventType::HOT_PLUG); - return Void(); -} - -//------------------------------------------------------------------------------ -#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ - var = env->GetMethodID(clazz, methodName, methodDescriptor); \ - LOG_FATAL_IF(! (var), "Unable to find method " methodName); - -static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj, - jobject messageQueueObj) { - // TODO(b/31632518) - sp<IHdmiCec> hdmiCec = IHdmiCec::getService(); - if (hdmiCec == nullptr) { - ALOGE("Couldn't get tv.cec service."); - return 0; - } - sp<MessageQueue> messageQueue = - android_os_MessageQueue_getMessageQueue(env, messageQueueObj); - - HdmiCecController* controller = new HdmiCecController( - hdmiCec, - env->NewGlobalRef(callbacksObj), - messageQueue->getLooper()); - - GET_METHOD_ID(gHdmiCecControllerClassInfo.handleIncomingCecCommand, clazz, - "handleIncomingCecCommand", "(II[B)V"); - GET_METHOD_ID(gHdmiCecControllerClassInfo.handleHotplug, clazz, - "handleHotplug", "(IZ)V"); - - return reinterpret_cast<jlong>(controller); -} - -static jint nativeSendCecCommand(JNIEnv* env, jclass clazz, jlong controllerPtr, - jint srcAddr, jint dstAddr, jbyteArray body) { - CecMessage message; - message.initiator = static_cast<CecLogicalAddress>(srcAddr); - message.destination = static_cast<CecLogicalAddress>(dstAddr); - - jsize len = env->GetArrayLength(body); - ScopedByteArrayRO bodyPtr(env, body); - size_t bodyLength = MIN(static_cast<size_t>(len), - static_cast<size_t>(MaxLength::MESSAGE_BODY)); - message.body.resize(bodyLength); - for (size_t i = 0; i < bodyLength; ++i) { - message.body[i] = static_cast<uint8_t>(bodyPtr[i]); - } - - HdmiCecController* controller = - reinterpret_cast<HdmiCecController*>(controllerPtr); - return controller->sendMessage(message); -} - -static jint nativeAddLogicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr, - jint logicalAddress) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - return controller->addLogicalAddress(static_cast<CecLogicalAddress>(logicalAddress)); -} - -static void nativeClearLogicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - controller->clearLogicaladdress(); -} - -static jint nativeGetPhysicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - return controller->getPhysicalAddress(); -} - -static jint nativeGetVersion(JNIEnv* env, jclass clazz, jlong controllerPtr) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - return controller->getVersion(); -} - -static jint nativeGetVendorId(JNIEnv* env, jclass clazz, jlong controllerPtr) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - return controller->getVendorId(); -} - -static jobjectArray nativeGetPortInfos(JNIEnv* env, jclass clazz, jlong controllerPtr) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - return controller->getPortInfos(); -} - -static void nativeSetOption(JNIEnv* env, jclass clazz, jlong controllerPtr, jint flag, jint value) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - controller->setOption(static_cast<OptionKey>(flag), value > 0 ? true : false); -} - -static void nativeSetLanguage(JNIEnv* env, jclass clazz, jlong controllerPtr, jstring language) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - const char *languageStr = env->GetStringUTFChars(language, NULL); - controller->setLanguage(languageStr); - env->ReleaseStringUTFChars(language, languageStr); -} - -static void nativeEnableAudioReturnChannel(JNIEnv* env, jclass clazz, jlong controllerPtr, - jint port, jboolean enabled) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - controller->enableAudioReturnChannel(port, enabled == JNI_TRUE); -} - -static jboolean nativeIsConnected(JNIEnv* env, jclass clazz, jlong controllerPtr, jint port) { - HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - return controller->isConnected(port) ? JNI_TRUE : JNI_FALSE ; -} - -static const JNINativeMethod sMethods[] = { - /* name, signature, funcPtr */ - { "nativeInit", - "(Lcom/android/server/hdmi/HdmiCecController;Landroid/os/MessageQueue;)J", - (void *) nativeInit }, - { "nativeSendCecCommand", "(JII[B)I", (void *) nativeSendCecCommand }, - { "nativeAddLogicalAddress", "(JI)I", (void *) nativeAddLogicalAddress }, - { "nativeClearLogicalAddress", "(J)V", (void *) nativeClearLogicalAddress }, - { "nativeGetPhysicalAddress", "(J)I", (void *) nativeGetPhysicalAddress }, - { "nativeGetVersion", "(J)I", (void *) nativeGetVersion }, - { "nativeGetVendorId", "(J)I", (void *) nativeGetVendorId }, - { "nativeGetPortInfos", - "(J)[Landroid/hardware/hdmi/HdmiPortInfo;", - (void *) nativeGetPortInfos }, - { "nativeSetOption", "(JIZ)V", (void *) nativeSetOption }, - { "nativeSetLanguage", "(JLjava/lang/String;)V", (void *) nativeSetLanguage }, - { "nativeEnableAudioReturnChannel", "(JIZ)V", (void *) nativeEnableAudioReturnChannel }, - { "nativeIsConnected", "(JI)Z", (void *) nativeIsConnected }, -}; - -#define CLASS_PATH "com/android/server/hdmi/HdmiCecController" - -int register_android_server_hdmi_HdmiCecController(JNIEnv* env) { - int res = jniRegisterNativeMethods(env, CLASS_PATH, sMethods, NELEM(sMethods)); - LOG_FATAL_IF(res < 0, "Unable to register native methods."); - (void)res; // Don't scream about unused variable in the LOG_NDEBUG case - return 0; -} - -} /* namespace android */ diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 75ec22486021..bad6b805f042 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -225,7 +225,7 @@ public: /* --- InputReaderPolicyInterface implementation --- */ virtual void getReaderConfiguration(InputReaderConfiguration* outConfig); - virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId); + virtual std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId); virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices); virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier); virtual std::string getDeviceAlias(const InputDeviceIdentifier& identifier); @@ -299,7 +299,7 @@ private: sp<SpriteController> spriteController; // Pointer controller singleton, created and destroyed as needed. - wp<PointerController> pointerController; + std::weak_ptr<PointerController> pointerController; // Input devices to be disabled std::set<int32_t> disabledInputDevices; @@ -544,15 +544,16 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon } // release lock } -sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t /* deviceId */) { +std::shared_ptr<PointerControllerInterface> NativeInputManager::obtainPointerController( + int32_t /* deviceId */) { ATRACE_CALL(); AutoMutex _l(mLock); - sp<PointerController> controller = mLocked.pointerController.promote(); + std::shared_ptr<PointerController> controller = mLocked.pointerController.lock(); if (controller == nullptr) { ensureSpriteControllerLocked(); - controller = new PointerController(this, mLooper, mLocked.spriteController); + controller = PointerController::create(this, mLooper, mLocked.spriteController); mLocked.pointerController = controller; updateInactivityTimeoutLocked(); } @@ -803,15 +804,14 @@ void NativeInputManager::setSystemUiVisibility(int32_t visibility) { } void NativeInputManager::updateInactivityTimeoutLocked() REQUIRES(mLock) { - sp<PointerController> controller = mLocked.pointerController.promote(); + std::shared_ptr<PointerController> controller = mLocked.pointerController.lock(); if (controller == nullptr) { return; } bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN; - controller->setInactivityTimeout(lightsOut - ? PointerController::INACTIVITY_TIMEOUT_SHORT - : PointerController::INACTIVITY_TIMEOUT_NORMAL); + controller->setInactivityTimeout(lightsOut ? PointerController::InactivityTimeout::SHORT + : PointerController::InactivityTimeout::NORMAL); } void NativeInputManager::setPointerSpeed(int32_t speed) { @@ -891,7 +891,7 @@ void NativeInputManager::reloadCalibration() { void NativeInputManager::setPointerIconType(int32_t iconId) { AutoMutex _l(mLock); - sp<PointerController> controller = mLocked.pointerController.promote(); + std::shared_ptr<PointerController> controller = mLocked.pointerController.lock(); if (controller != nullptr) { controller->updatePointerIcon(iconId); } @@ -899,7 +899,7 @@ void NativeInputManager::setPointerIconType(int32_t iconId) { void NativeInputManager::reloadPointerIcons() { AutoMutex _l(mLock); - sp<PointerController> controller = mLocked.pointerController.promote(); + std::shared_ptr<PointerController> controller = mLocked.pointerController.lock(); if (controller != nullptr) { controller->reloadPointerResources(); } @@ -907,7 +907,7 @@ void NativeInputManager::reloadPointerIcons() { void NativeInputManager::setCustomPointerIcon(const SpriteIcon& icon) { AutoMutex _l(mLock); - sp<PointerController> controller = mLocked.pointerController.promote(); + std::shared_ptr<PointerController> controller = mLocked.pointerController.lock(); if (controller != nullptr) { controller->setCustomPointerIcon(icon); } diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index e5d2a83479e0..8cb3e6d1ae73 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -43,7 +43,6 @@ int register_android_server_location_GnssLocationProvider(JNIEnv* env); int register_android_server_connectivity_Vpn(JNIEnv* env); int register_android_server_TestNetworkService(JNIEnv* env); int register_android_server_devicepolicy_CryptoTestHelper(JNIEnv*); -int register_android_server_hdmi_HdmiCecController(JNIEnv* env); int register_android_server_tv_TvUinputBridge(JNIEnv* env); int register_android_server_tv_TvInputHal(JNIEnv* env); int register_android_server_PersistentDataBlockService(JNIEnv* env); @@ -99,7 +98,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_devicepolicy_CryptoTestHelper(env); register_android_server_ConsumerIrService(env); register_android_server_BatteryStatsService(env); - register_android_server_hdmi_HdmiCecController(env); register_android_server_tv_TvUinputBridge(env); register_android_server_tv_TvInputHal(env); register_android_server_PersistentDataBlockService(env); diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp index de639c5d0760..7534c7c40a3d 100644 --- a/services/incremental/Android.bp +++ b/services/incremental/Android.bp @@ -39,6 +39,7 @@ cc_defaults { cc_defaults { name: "service.incremental-defaults", defaults: ["service.incremental-proto-defaults"], + header_libs: ["jni_headers"], local_include_dirs: ["include/"], cflags: [ "-Wall", @@ -53,7 +54,6 @@ cc_defaults { "libdataloader_aidl-cpp", "libincremental_aidl-cpp", "libincremental_manager_aidl-cpp", - "libnativehelper", "libprotobuf-cpp-lite", "service.incremental.proto", "libutils", diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp index 7132706c4ef1..0ae10b6dc3b5 100644 --- a/services/incremental/BinderIncrementalService.cpp +++ b/services/incremental/BinderIncrementalService.cpp @@ -25,7 +25,6 @@ #include "ServiceWrappers.h" #include "jni.h" -#include "nativehelper/JNIHelp.h" #include "path.h" using namespace std::literals; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 2a200fb0ae2c..b3dcf4d4fa63 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -80,6 +80,7 @@ import android.util.Pair; import android.util.Slog; import android.view.contentcapture.ContentCaptureManager; +import com.android.i18n.timezone.ZoneInfoDb; import com.android.internal.R; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BinderInternal; @@ -199,12 +200,6 @@ public final class SystemServer { private static final String ENCRYPTING_STATE = "trigger_restart_min_framework"; private static final String ENCRYPTED_STATE = "1"; - private static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr - - // The earliest supported time. We pick one day into 1970, to - // give any timezone code room without going into negative time. - private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000; - private static final long SLOW_DISPATCH_THRESHOLD_MS = 100; private static final long SLOW_DELIVERY_THRESHOLD_MS = 200; @@ -444,8 +439,9 @@ public final class SystemServer { // Default the timezone property to GMT if not set. // String timezoneProperty = SystemProperties.get("persist.sys.timezone"); - if (timezoneProperty == null || timezoneProperty.isEmpty()) { - Slog.w(TAG, "Timezone not set; setting to GMT."); + if (!isValidTimeZoneId(timezoneProperty)) { + Slog.w(TAG, "persist.sys.timezone is not valid (" + timezoneProperty + + "); setting to GMT."); SystemProperties.set("persist.sys.timezone", "GMT"); } @@ -612,17 +608,17 @@ public final class SystemServer { } } - // Diagnostic to ensure that the system is in a base healthy state. Done here as a common - // non-zygote process. - if (!VMRuntime.hasBootImageSpaces()) { - Slog.wtf(TAG, "Runtime is not running with a boot image!"); - } - // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); } + private static boolean isValidTimeZoneId(String timezoneProperty) { + return timezoneProperty != null + && !timezoneProperty.isEmpty() + && ZoneInfoDb.getInstance().hasTimeZone(timezoneProperty); + } + private boolean isFirstBootOrUpgrade() { return mPackageManagerService.isFirstBoot() || mPackageManagerService.isDeviceUpgrading(); } diff --git a/services/robotests/Android.bp b/services/robotests/Android.bp index 25ab5d36169e..1ae2aec90ba3 100644 --- a/services/robotests/Android.bp +++ b/services/robotests/Android.bp @@ -43,6 +43,7 @@ android_robolectric_test { // Include the testing libraries libs: [ "platform-test-annotations", + "services.backup", "testng", ], static_libs: [ 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/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java index 28887fdab00d..dd98c4b09b78 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java @@ -75,7 +75,6 @@ public class HdmiCecLocalDeviceAudioSystemTest { private static final int HDMI_3_PHYSICAL_ADDRESS = 0x2300; private int mInvokeDeviceEventState; private HdmiDeviceInfo mDeviceInfo; - private boolean mMutingEnabled; private boolean mArcSupport; private HdmiPortInfo[] mHdmiPortInfo; private boolean mWokenUp; @@ -159,8 +158,6 @@ public class HdmiCecLocalDeviceAudioSystemTest { @Override boolean readBooleanSystemProperty(String key, boolean defVal) { switch (key) { - case Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE: - return mMutingEnabled; case Constants.PROPERTY_ARC_SUPPORT: return mArcSupport; default: @@ -216,7 +213,6 @@ public class HdmiCecLocalDeviceAudioSystemTest { mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); mTestLooper.dispatchAll(); mNativeWrapper.clearResultMessages(); - mMutingEnabled = true; mArcSupport = true; mInvokeDeviceEventState = 0; mDeviceInfo = null; diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageInfoFlagBehaviorTest.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageInfoFlagBehaviorTest.kt index 0a32e4a53284..946f27e09fdb 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageInfoFlagBehaviorTest.kt +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageInfoFlagBehaviorTest.kt @@ -26,6 +26,7 @@ import com.android.server.pm.parsing.AndroidPackageInfoFlagBehaviorTest.Companio import com.android.server.pm.parsing.pkg.AndroidPackage import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage +import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized @@ -102,6 +103,7 @@ class AndroidPackageInfoFlagBehaviorTest : AndroidPackageParsingTestBase() { lateinit var param: Param<Any> @Test + @Ignore("b/155935153") fun fieldPresence() { oldPackages.asSequence().zip(newPackages.asSequence()) .forEach { (old, new) -> @@ -124,6 +126,7 @@ class AndroidPackageInfoFlagBehaviorTest : AndroidPackageParsingTestBase() { } @Test + @Ignore("b/155935153") fun fieldAbsence() { newPackages.forEach { val newWithoutFlag = param.newPkgFunction(it, 0) diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingEquivalenceTest.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingEquivalenceTest.kt index 74b4d122cbc0..9f9ec31f0c91 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingEquivalenceTest.kt +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingEquivalenceTest.kt @@ -20,6 +20,7 @@ import android.content.pm.PackageManager import android.platform.test.annotations.Presubmit import androidx.test.filters.LargeTest import com.google.common.truth.Expect + import org.junit.Rule import org.junit.Test diff --git a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java index 5c6fe0fc4cad..2c4c4d0ee91f 100644 --- a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java @@ -43,13 +43,13 @@ import android.app.timezone.RulesManager; import android.app.timezone.RulesState; import android.os.ParcelFileDescriptor; +import com.android.i18n.timezone.TzDataSetVersion; import com.android.timezone.distro.DistroVersion; import com.android.timezone.distro.StagedDistroOperation; import com.android.timezone.distro.TimeZoneDistro; import com.android.timezone.distro.installer.TimeZoneDistroInstaller; import libcore.io.IoUtils; -import libcore.timezone.TzDataSetVersion; import org.junit.Before; import org.junit.Test; diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java index b100c8482bf8..1d75967756c3 100644 --- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java @@ -39,6 +39,7 @@ import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightState; import com.android.server.wm.WindowManagerInternal; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -165,6 +166,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { LocalServices.addService(clazz, service); } + @Ignore // b/152719290 - Fails on stage-aosp-master @Test public void setNightMoveActivated_overridesFunctionCorrectly() throws RemoteException { // set up @@ -205,6 +207,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { verify(mContext, atLeastOnce()).registerReceiver(any(BroadcastReceiver.class), any()); } + @Ignore // b/152719290 - Fails on stage-aosp-master @Test public void setAutoMode_screenOffUnRegistered() throws RemoteException { try { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java index afd10ddb8ec2..abcc14c6be93 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -1346,6 +1346,22 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { } @Test + public void testLightsCheckCurrentUser() { + final Notification n = new Builder(getContext(), "test") + .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); + int userId = mUser.getIdentifier() + 10; + StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, + mPid, n, UserHandle.of(userId), null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(getContext(), sbn, + new NotificationChannel("test", "test", IMPORTANCE_HIGH)); + + mService.buzzBeepBlinkLocked(r); + verifyNeverLights(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test public void testListenerHintCall() throws Exception { NotificationChannel ringtoneChannel = new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 2e49929ec032..4dc8ad9d0a98 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -56,6 +56,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -70,6 +71,7 @@ import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationManager; import android.content.ContentProvider; +import android.content.ContentResolver; import android.content.Context; import android.content.IContentProvider; import android.content.pm.ApplicationInfo; @@ -80,13 +82,16 @@ import android.content.res.Resources; import android.graphics.Color; import android.media.AudioAttributes; import android.net.Uri; +import android.os.AsyncTask; import android.os.Build; +import android.os.Bundle; +import android.os.RemoteCallback; +import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Global; import android.provider.Settings.Secure; import android.service.notification.ConversationChannelWrapper; -import android.test.mock.MockIContentProvider; import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableContentResolver; import android.util.ArrayMap; @@ -108,7 +113,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.mockito.Spy; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; @@ -146,7 +150,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Mock NotificationUsageStats mUsageStats; @Mock RankingHandler mHandler; @Mock PackageManager mPm; - @Spy IContentProvider mTestIContentProvider = new MockIContentProvider(); + IContentProvider mTestIContentProvider; @Mock Context mContext; @Mock ZenModeHelper mMockZenModeHelper; @Mock AppOpsManager mAppOpsManager; @@ -193,6 +197,39 @@ public class PreferencesHelperTest extends UiServiceTestCase { Global.putInt(contentResolver, Global.NOTIFICATION_BUBBLES, 1); ContentProvider testContentProvider = mock(ContentProvider.class); + mTestIContentProvider = mock(IContentProvider.class, invocation -> { + throw new UnsupportedOperationException("unimplemented mock method"); + }); + doAnswer(invocation -> { + String callingPkg = invocation.getArgument(0); + String featureId = invocation.getArgument(1); + Uri uri = invocation.getArgument(2); + RemoteCallback cb = invocation.getArgument(3); + IContentProvider mock = (IContentProvider) (invocation.getMock()); + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + final Bundle bundle = new Bundle(); + try { + bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, + mock.canonicalize(callingPkg, featureId, uri)); + } catch (RemoteException e) { /* consume */ } + cb.sendResult(bundle); + }); + return null; + }).when(mTestIContentProvider).canonicalizeAsync(any(), any(), any(), any()); + doAnswer(invocation -> { + Uri uri = invocation.getArgument(0); + RemoteCallback cb = invocation.getArgument(1); + IContentProvider mock = (IContentProvider) (invocation.getMock()); + AsyncTask.SERIAL_EXECUTOR.execute(() -> { + final Bundle bundle = new Bundle(); + try { + bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT, mock.getType(uri)); + } catch (RemoteException e) { /* consume */ } + cb.sendResult(bundle); + }); + return null; + }).when(mTestIContentProvider).getTypeAsync(any(), any()); + when(testContentProvider.getIContentProvider()).thenReturn(mTestIContentProvider); contentResolver.addProvider(TEST_AUTHORITY, testContentProvider); 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/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java index 8abab90f775f..4d9311c282f7 100644 --- a/telecomm/java/android/telecom/CallScreeningService.java +++ b/telecomm/java/android/telecom/CallScreeningService.java @@ -16,7 +16,9 @@ package android.telecom; +import android.Manifest; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.TestApi; @@ -302,6 +304,7 @@ public abstract class CallScreeningService extends Service { */ @SystemApi @TestApi + @RequiresPermission(Manifest.permission.CAPTURE_AUDIO_OUTPUT) public @NonNull Builder setShouldScreenCallViaAudioProcessing( boolean shouldScreenCallViaAudioProcessing) { mShouldScreenCallViaAudioProcessing = shouldScreenCallViaAudioProcessing; diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index f2f14125ef6b..8eebbeda9e83 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -1645,6 +1645,7 @@ public class TelecomManager { * @hide */ @SystemApi + @TestApi @RequiresPermission(anyOf = { READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt index 8ce4b0d158a3..73799dc5f006 100644 --- a/telephony/api/system-current.txt +++ b/telephony/api/system-current.txt @@ -179,85 +179,6 @@ package android.telephony { 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(); 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/java/android/service/euicc/EuiccProfileInfo.java b/telephony/java/android/service/euicc/EuiccProfileInfo.java index 8450a9018634..92e419707970 100644 --- a/telephony/java/android/service/euicc/EuiccProfileInfo.java +++ b/telephony/java/android/service/euicc/EuiccProfileInfo.java @@ -29,6 +29,7 @@ import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Objects; @@ -231,7 +232,9 @@ public final class EuiccProfileInfo implements Parcelable { mState = baseProfile.mState; mCarrierIdentifier = baseProfile.mCarrierIdentifier; mPolicyRules = baseProfile.mPolicyRules; - mAccessRules = Arrays.asList(baseProfile.mAccessRules); + mAccessRules = baseProfile.mAccessRules == null + ? Collections.emptyList() + : Arrays.asList(baseProfile.mAccessRules); } /** Builds the profile instance. */ diff --git a/telephony/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java index 93155865c166..fcbb008c79b3 100644 --- a/telephony/java/android/service/euicc/EuiccService.java +++ b/telephony/java/android/service/euicc/EuiccService.java @@ -328,8 +328,7 @@ public abstract class EuiccService extends Service { * or when an number is bigger than 15 */ public int encodeSmdxSubjectAndReasonCode(@Nullable String subjectCode, - @Nullable String reasonCode) - throws NumberFormatException, IllegalArgumentException, UnsupportedOperationException { + @Nullable String reasonCode) { final int maxSupportedSection = 3; final int maxSupportedDigit = 15; final int bitsPerSection = 4; diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 52f1e37e69f4..b6152e200e65 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -354,6 +354,34 @@ public class CarrierConfigManager { "only_auto_select_in_home_network"; /** + * Flag indicating whether to show single operator row in the choose network setting. + * + * The device configuration value {@code config_enableNewAutoSelectNetworkUI} ultimately + * controls whether this carrier configuration option is used. Where + * {@code config_enableNewAutoSelectNetworkUI} is false, the value of the + * {@link #KEY_SHOW_SINGLE_OPERATOR_ROW_IN_CHOOSE_NETWORK_SETTING_BOOL} carrier configuration + * option is ignored. + * + * If {@code true}, default value, merge the duplicate networks which with the same plmn, keep + * the one that with the higher signal strength level. + * If {@code false}, show all operators without merging. + * @hide + */ + public static final String KEY_SHOW_SINGLE_OPERATOR_ROW_IN_CHOOSE_NETWORK_SETTING_BOOL = + "show_single_operator_row_in_choose_network_setting_bool"; + + /** + * Flag indicating whether to display SPN as network name for home network in choose + * network setting. + * + * If {@code true}, display SPN as network name in choose network setting. + * If {@code false}, display PLMN in choose network setting. + * @hide + */ + public static final String KEY_SHOW_SPN_FOR_HOME_IN_CHOOSE_NETWORK_SETTING_BOOL = + "show_spn_for_home_in_choose_network_setting_bool"; + + /** * Control whether users receive a simplified network settings UI and improved network * selection. */ @@ -3779,6 +3807,15 @@ public class CarrierConfigManager { "carrier_certificate_string_array"; /** + * Flag specifying whether the incoming call number should be formatted to national number + * for Japan. @return {@code true} convert to the national format, {@code false} otherwise. + * e.g. "+819012345678" -> "09012345678" + * @hide + */ + public static final String KEY_FORMAT_INCOMING_NUMBER_TO_NATIONAL_FOR_JP_BOOL = + "format_incoming_number_to_national_for_jp_bool"; + + /** * DisconnectCause array to play busy tone. Value should be array of * {@link android.telephony.DisconnectCause}. */ @@ -3910,6 +3947,8 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL, false); sDefaults.putBoolean(KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, false); sDefaults.putBoolean(KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL, false); + sDefaults.putBoolean(KEY_SHOW_SINGLE_OPERATOR_ROW_IN_CHOOSE_NETWORK_SETTING_BOOL, true); + sDefaults.putBoolean(KEY_SHOW_SPN_FOR_HOME_IN_CHOOSE_NETWORK_SETTING_BOOL, false); sDefaults.putBoolean(KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL, false); sDefaults.putBoolean(KEY_HIDE_SIM_LOCK_SETTINGS_BOOL, false); @@ -4359,6 +4398,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SUPPORT_WPS_OVER_IMS_BOOL, true); sDefaults.putAll(Ims.getDefaults()); sDefaults.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, null); + sDefaults.putBoolean(KEY_FORMAT_INCOMING_NUMBER_TO_NATIONAL_FOR_JP_BOOL, false); sDefaults.putIntArray(KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY, new int[] {4 /* BUSY */}); sDefaults.putBoolean(KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL, false); @@ -4622,6 +4662,7 @@ public class CarrierConfigManager { } catch (RemoteException ex) { Rlog.e(TAG, "getDefaultCarrierServicePackageName ICarrierConfigLoader is null" + ex.toString()); + ex.rethrowAsRuntimeException(); } return ""; } diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java index 2d0bd52f84ee..aa1230165e13 100644 --- a/telephony/java/android/telephony/CellLocation.java +++ b/telephony/java/android/telephony/CellLocation.java @@ -16,7 +16,9 @@ package android.telephony; +import android.app.ActivityThread; import android.compat.annotation.UnsupportedAppUsage; +import android.content.Context; import android.os.Bundle; import android.os.RemoteException; import android.telephony.cdma.CdmaCellLocation; @@ -31,11 +33,32 @@ import com.android.internal.telephony.PhoneConstants; public abstract class CellLocation { /** - * Request an update of the current location. If the location has changed, - * a broadcast will be sent to everyone registered with {@link - * PhoneStateListener#LISTEN_CELL_LOCATION}. + * This method will not do anything. + * + * Whenever location changes, a callback will automatically be be sent to + * all registrants of {@link PhoneStateListener#LISTEN_CELL_LOCATION}. + * + * <p>This method is a no-op for callers targeting SDK level 31 or greater. + * <p>This method is a no-op for callers that target SDK level 29 or 30 and lack + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION}. + * <p>This method is a no-op for callers that target SDK level 28 or below and lack + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. + * + * Callers wishing to request a single location update should use + * {@link TelephonyManager#requestCellInfoUpdate}. + * + * @deprecated this method has undesirable side-effects, and it calls into the OS without + * access to a {@link android.content.Context Context}, meaning that certain safety checks and + * attribution are error-prone. Given that this method has numerous downsides, and given that + * there are long-available superior alternatives, callers are strongly discouraged from using + * this method. */ + @Deprecated public static void requestLocationUpdate() { + // Since this object doesn't have a context, this is the best we can do. + final Context appContext = ActivityThread.currentApplication(); + if (appContext == null) return; // should never happen + try { ITelephony phone = ITelephony.Stub.asInterface( TelephonyFrameworkInitializer @@ -43,7 +66,7 @@ public abstract class CellLocation { .getTelephonyServiceRegisterer() .get()); if (phone != null) { - phone.updateServiceLocation(); + phone.updateServiceLocationWithPackageName(appContext.getOpPackageName()); } } catch (RemoteException ex) { // ignore it diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java index c667165e7a0e..e91d6fc9d801 100644 --- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java +++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java @@ -72,28 +72,20 @@ public final class DataSpecificRegistrationInfo implements Parcelable { /** * Provides network support info for LTE VoPS and LTE Emergency bearer support */ + @Nullable private final LteVopsSupportInfo mLteVopsSupportInfo; /** - * Indicates if it's using carrier aggregation - * - * @hide - */ - public boolean mIsUsingCarrierAggregation; - - /** * @hide */ DataSpecificRegistrationInfo( int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable, - boolean isEnDcAvailable, LteVopsSupportInfo lteVops, - boolean isUsingCarrierAggregation) { + boolean isEnDcAvailable, @Nullable LteVopsSupportInfo lteVops) { this.maxDataCalls = maxDataCalls; this.isDcNrRestricted = isDcNrRestricted; this.isNrAvailable = isNrAvailable; this.isEnDcAvailable = isEnDcAvailable; this.mLteVopsSupportInfo = lteVops; - this.mIsUsingCarrierAggregation = isUsingCarrierAggregation; } /** @@ -102,32 +94,29 @@ public final class DataSpecificRegistrationInfo implements Parcelable { * @param dsri another data specific registration info * @hide */ - DataSpecificRegistrationInfo(DataSpecificRegistrationInfo dsri) { + DataSpecificRegistrationInfo(@NonNull DataSpecificRegistrationInfo dsri) { maxDataCalls = dsri.maxDataCalls; isDcNrRestricted = dsri.isDcNrRestricted; isNrAvailable = dsri.isNrAvailable; isEnDcAvailable = dsri.isEnDcAvailable; mLteVopsSupportInfo = dsri.mLteVopsSupportInfo; - mIsUsingCarrierAggregation = dsri.mIsUsingCarrierAggregation; } - private DataSpecificRegistrationInfo(Parcel source) { + private DataSpecificRegistrationInfo(/* @NonNull */ Parcel source) { maxDataCalls = source.readInt(); isDcNrRestricted = source.readBoolean(); isNrAvailable = source.readBoolean(); isEnDcAvailable = source.readBoolean(); mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source); - mIsUsingCarrierAggregation = source.readBoolean(); } @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(/* @NonNull */ Parcel dest, int flags) { dest.writeInt(maxDataCalls); dest.writeBoolean(isDcNrRestricted); dest.writeBoolean(isNrAvailable); dest.writeBoolean(isEnDcAvailable); mLteVopsSupportInfo.writeToParcel(dest, flags); - dest.writeBoolean(mIsUsingCarrierAggregation); } @Override @@ -144,8 +133,7 @@ public final class DataSpecificRegistrationInfo implements Parcelable { .append(" isDcNrRestricted = " + isDcNrRestricted) .append(" isNrAvailable = " + isNrAvailable) .append(" isEnDcAvailable = " + isEnDcAvailable) - .append(" " + mLteVopsSupportInfo.toString()) - .append(" mIsUsingCarrierAggregation = " + mIsUsingCarrierAggregation) + .append(" " + mLteVopsSupportInfo) .append(" }") .toString(); } @@ -153,7 +141,7 @@ public final class DataSpecificRegistrationInfo implements Parcelable { @Override public int hashCode() { return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable, - mLteVopsSupportInfo, mIsUsingCarrierAggregation); + mLteVopsSupportInfo); } @Override @@ -167,8 +155,7 @@ public final class DataSpecificRegistrationInfo implements Parcelable { && this.isDcNrRestricted == other.isDcNrRestricted && this.isNrAvailable == other.isNrAvailable && this.isEnDcAvailable == other.isEnDcAvailable - && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo) - && this.mIsUsingCarrierAggregation == other.mIsUsingCarrierAggregation; + && Objects.equals(mLteVopsSupportInfo, other.mLteVopsSupportInfo); } public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR = @@ -192,23 +179,4 @@ public final class DataSpecificRegistrationInfo implements Parcelable { return mLteVopsSupportInfo; } - /** - * Set the flag indicating if using carrier aggregation. - * - * @param isUsingCarrierAggregation {@code true} if using carrier aggregation. - * @hide - */ - public void setIsUsingCarrierAggregation(boolean isUsingCarrierAggregation) { - mIsUsingCarrierAggregation = isUsingCarrierAggregation; - } - - /** - * Get whether network has configured carrier aggregation or not. - * - * @return {@code true} if using carrier aggregation. - * @hide - */ - public boolean isUsingCarrierAggregation() { - return mIsUsingCarrierAggregation; - } } diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java index be85b30f272b..2704418935d9 100644 --- a/telephony/java/android/telephony/DisconnectCause.java +++ b/telephony/java/android/telephony/DisconnectCause.java @@ -17,16 +17,14 @@ package android.telephony; import android.annotation.NonNull; -import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; /** * Describes the cause of a disconnected call. Those disconnect causes can be converted into a more * generic {@link android.telecom.DisconnectCause} object. * - * @hide + * Used in {@link PhoneStateListener#onCallDisconnectCauseChanged}. */ -@SystemApi public final class DisconnectCause { /** The disconnect cause is not valid (Not received a disconnect cause) */ @@ -337,20 +335,17 @@ public final class DisconnectCause { /** * Indicates that the call is dropped due to RTCP inactivity, primarily due to media path * disruption. - * @hide */ public static final int MEDIA_TIMEOUT = 77; /** * Indicates that an emergency call cannot be placed over WFC because the service is not * available in the current location. - * @hide */ public static final int EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE = 78; /** * Indicates that WiFi calling service is not available in the current location. - * @hide */ public static final int WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 79; diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java index 45deea206cfc..3f671ca2d809 100644 --- a/telephony/java/android/telephony/MbmsDownloadSession.java +++ b/telephony/java/android/telephony/MbmsDownloadSession.java @@ -231,6 +231,8 @@ public class MbmsDownloadSession implements AutoCloseable { private static final String DESTINATION_SANITY_CHECK_FILE_NAME = "destinationSanityCheckFile"; + private static final int MAX_SERVICE_ANNOUNCEMENT_SIZE = 10 * 1024; // 10KB + private static AtomicBoolean sIsInitialized = new AtomicBoolean(false); private final Context mContext; @@ -318,6 +320,16 @@ public class MbmsDownloadSession implements AutoCloseable { return session; } + /** + * Returns the maximum size of the service announcement descriptor that can be provided via + * {@link #addServiceAnnouncement} + * @return The maximum length of the byte array passed as an argument to + * {@link #addServiceAnnouncement}. + */ + public static int getMaximumServiceAnnouncementSize() { + return MAX_SERVICE_ANNOUNCEMENT_SIZE; + } + private int bindAndInitialize() { mServiceConnection = new ServiceConnection() { @Override @@ -424,6 +436,61 @@ public class MbmsDownloadSession implements AutoCloseable { } /** + * Inform the middleware of a service announcement descriptor received from a group + * communication server. + * + * When participating in a group call via the {@link MbmsGroupCallSession} API, applications may + * receive a service announcement descriptor from the group call server that informs them of + * files that may be relevant to users communicating on the group call. + * + * After supplying the service announcement descriptor received from the server to the + * middleware via this API, applications will receive information on the available files via + * {@link MbmsDownloadSessionCallback#onFileServicesUpdated}, and the available files will be + * downloadable via {@link MbmsDownloadSession#download} like other files published via + * {@link MbmsDownloadSessionCallback#onFileServicesUpdated}. + * + * Asynchronous error codes via the {@link MbmsDownloadSessionCallback#onError(int, String)} + * callback may include any of the errors that are not specific to the streaming use-case. + * + * May throw an {@link IllegalStateException} when the middleware has not yet been bound, + * or an {@link IllegalArgumentException} if the byte array is too large, or an + * {@link UnsupportedOperationException} if the middleware has not implemented this method. + * + * @param contents The contents of the service announcement descriptor received from the + * group call server. If the size of this array is greater than the value of + * {@link #getMaximumServiceAnnouncementSize()}, an + * {@link IllegalArgumentException} will be thrown. + */ + public void addServiceAnnouncement(@NonNull byte[] contents) { + IMbmsDownloadService downloadService = mService.get(); + if (downloadService == null) { + throw new IllegalStateException("Middleware not yet bound"); + } + + if (contents.length > MAX_SERVICE_ANNOUNCEMENT_SIZE) { + throw new IllegalArgumentException("File too large"); + } + + try { + int returnCode = downloadService.addServiceAnnouncement( + mSubscriptionId, contents); + if (returnCode == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return an unknown error code"); + } + if (returnCode != MbmsErrors.SUCCESS) { + sendErrorToApp(returnCode, null); + } + } catch (RemoteException e) { + Log.w(LOG_TAG, "Remote process died"); + mService.set(null); + sIsInitialized.set(false); + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null); + } + } + + /** * Sets the temp file root for downloads. * All temp files created for the middleware to write to will be contained in the specified * directory. Applications that wish to specify a location only need to call this method once diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java index 2b72ab7635c3..debb119c94bc 100644 --- a/telephony/java/android/telephony/ModemActivityInfo.java +++ b/telephony/java/android/telephony/ModemActivityInfo.java @@ -234,7 +234,7 @@ public final class ModemActivityInfo implements Parcelable { } /** - * Indicate if the ModemActivityInfo is invalid due to modem's invalid reporting. + * Indicates if the modem has reported valid {@link ModemActivityInfo}. * * @return {@code true} if this {@link ModemActivityInfo} record is valid, * {@code false} otherwise. diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index 6a67ad2b72cc..aee1e84ca356 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -218,6 +218,9 @@ public final class NetworkRegistrationInfo implements Parcelable { @NonNull private String mRplmn; + // Updated based on the accessNetworkTechnology + private boolean mIsUsingCarrierAggregation; + /** * @param domain Network domain. Must be a {@link Domain}. For transport type * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}. @@ -251,7 +254,7 @@ public final class NetworkRegistrationInfo implements Parcelable { mRegistrationState = registrationState; mRoamingType = (registrationState == REGISTRATION_STATE_ROAMING) ? ServiceState.ROAMING_TYPE_UNKNOWN : ServiceState.ROAMING_TYPE_NOT_ROAMING; - mAccessNetworkTechnology = accessNetworkTechnology; + setAccessNetworkTechnology(accessNetworkTechnology); mRejectCause = rejectCause; mAvailableServices = (availableServices != null) ? new ArrayList<>(availableServices) : new ArrayList<>(); @@ -290,13 +293,11 @@ public final class NetworkRegistrationInfo implements Parcelable { @Nullable CellIdentity cellIdentity, @Nullable String rplmn, int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable, - LteVopsSupportInfo lteVopsSupportInfo, - boolean isUsingCarrierAggregation) { + LteVopsSupportInfo lteVopsSupportInfo) { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, emergencyOnly, availableServices, cellIdentity, rplmn); mDataSpecificInfo = new DataSpecificRegistrationInfo( - maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo, - isUsingCarrierAggregation); + maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo); updateNrState(); } @@ -317,6 +318,7 @@ public final class NetworkRegistrationInfo implements Parcelable { DataSpecificRegistrationInfo.class.getClassLoader()); mNrState = source.readInt(); mRplmn = source.readString(); + mIsUsingCarrierAggregation = source.readBoolean(); } /** @@ -331,6 +333,7 @@ public final class NetworkRegistrationInfo implements Parcelable { mRegistrationState = nri.mRegistrationState; mRoamingType = nri.mRoamingType; mAccessNetworkTechnology = nri.mAccessNetworkTechnology; + mIsUsingCarrierAggregation = nri.mIsUsingCarrierAggregation; mRejectCause = nri.mRejectCause; mEmergencyOnly = nri.mEmergencyOnly; mAvailableServices = new ArrayList<>(nri.mAvailableServices); @@ -389,7 +392,7 @@ public final class NetworkRegistrationInfo implements Parcelable { } /** - * @return {@code true} if registered on roaming network, {@code false} otherwise. + * @return {@code true} if registered on roaming or home network, {@code false} otherwise. */ public boolean isRegistered() { return mRegistrationState == REGISTRATION_STATE_HOME @@ -397,7 +400,7 @@ public final class NetworkRegistrationInfo implements Parcelable { } /** - * @return {@code true} if registered on roaming network, {@code false} otherwise. + * @return {@code true} if searching for service, {@code false} otherwise. */ public boolean isSearching() { return mRegistrationState == REGISTRATION_STATE_NOT_REGISTERED_SEARCHING; @@ -484,9 +487,7 @@ public final class NetworkRegistrationInfo implements Parcelable { if (tech == TelephonyManager.NETWORK_TYPE_LTE_CA) { // For old device backward compatibility support tech = TelephonyManager.NETWORK_TYPE_LTE; - if (mDataSpecificInfo != null) { - mDataSpecificInfo.setIsUsingCarrierAggregation(true); - } + mIsUsingCarrierAggregation = true; } mAccessNetworkTechnology = tech; } @@ -511,6 +512,27 @@ public final class NetworkRegistrationInfo implements Parcelable { } /** + * Set whether network has configured carrier aggregation or not. + * + * @param isUsingCarrierAggregation set whether or not carrier aggregation is used. + * + * @hide + */ + public void setIsUsingCarrierAggregation(boolean isUsingCarrierAggregation) { + mIsUsingCarrierAggregation = isUsingCarrierAggregation; + } + + /** + * Get whether network has configured carrier aggregation or not. + * + * @return {@code true} if using carrier aggregation. + * @hide + */ + public boolean isUsingCarrierAggregation() { + return mIsUsingCarrierAggregation; + } + + /** * @hide */ @Nullable @@ -617,6 +639,7 @@ public final class NetworkRegistrationInfo implements Parcelable { .append(" dataSpecificInfo=").append(mDataSpecificInfo) .append(" nrState=").append(nrStateToString(mNrState)) .append(" rRplmn=").append(mRplmn) + .append(" isUsingCarrierAggregation=").append(mIsUsingCarrierAggregation) .append("}").toString(); } @@ -624,7 +647,8 @@ public final class NetworkRegistrationInfo implements Parcelable { public int hashCode() { return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, - mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn); + mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn, + mIsUsingCarrierAggregation); } @Override @@ -644,6 +668,7 @@ public final class NetworkRegistrationInfo implements Parcelable { && mRejectCause == other.mRejectCause && mEmergencyOnly == other.mEmergencyOnly && mAvailableServices.equals(other.mAvailableServices) + && mIsUsingCarrierAggregation == other.mIsUsingCarrierAggregation && Objects.equals(mCellIdentity, other.mCellIdentity) && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo) && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo) @@ -670,6 +695,7 @@ public final class NetworkRegistrationInfo implements Parcelable { dest.writeParcelable(mDataSpecificInfo, 0); dest.writeInt(mNrState); dest.writeString(mRplmn); + dest.writeBoolean(mIsUsingCarrierAggregation); } /** diff --git a/telephony/java/android/telephony/PinResult.java b/telephony/java/android/telephony/PinResult.java index 98d6448e77ea..c2a4f33e95b9 100644 --- a/telephony/java/android/telephony/PinResult.java +++ b/telephony/java/android/telephony/PinResult.java @@ -37,6 +37,7 @@ public final class PinResult implements Parcelable { PIN_RESULT_TYPE_SUCCESS, PIN_RESULT_TYPE_INCORRECT, PIN_RESULT_TYPE_FAILURE, + PIN_RESULT_TYPE_ABORTED, }) public @interface PinResultType {} @@ -55,6 +56,11 @@ public final class PinResult implements Parcelable { */ public static final int PIN_RESULT_TYPE_FAILURE = PhoneConstants.PIN_GENERAL_FAILURE; + /** + * Indicates that the pin attempt was aborted. + */ + public static final int PIN_RESULT_TYPE_ABORTED = PhoneConstants.PIN_OPERATION_ABORTED; + private static final PinResult sFailedResult = new PinResult(PinResult.PIN_RESULT_TYPE_FAILURE, -1); diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 9e2ba6875577..3e7464739f9f 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -1412,29 +1412,14 @@ public class ServiceState implements Parcelable { /** @hide */ public boolean isUsingCarrierAggregation() { - boolean isUsingCa = false; - NetworkRegistrationInfo nri = getNetworkRegistrationInfo( - NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); - if (nri != null) { - DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); - if (dsri != null) { - isUsingCa = dsri.isUsingCarrierAggregation(); - } - } - return isUsingCa || getCellBandwidths().length > 1; - } + if (getCellBandwidths().length > 1) return true; - /** @hide */ - public void setIsUsingCarrierAggregation(boolean ca) { - NetworkRegistrationInfo nri = getNetworkRegistrationInfo( - NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); - if (nri != null) { - DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); - if (dsri != null) { - dsri.setIsUsingCarrierAggregation(ca); - addNetworkRegistrationInfo(nri); + synchronized (mNetworkRegistrationInfos) { + for (NetworkRegistrationInfo nri : mNetworkRegistrationInfos) { + if (nri.isUsingCarrierAggregation()) return true; } } + return false; } /** diff --git a/telephony/java/android/telephony/SmsCbEtwsInfo.java b/telephony/java/android/telephony/SmsCbEtwsInfo.java index 2a7f7ad81e3b..a98916d715e4 100644 --- a/telephony/java/android/telephony/SmsCbEtwsInfo.java +++ b/telephony/java/android/telephony/SmsCbEtwsInfo.java @@ -27,6 +27,7 @@ import com.android.internal.telephony.uicc.IccUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.time.DateTimeException; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.Arrays; @@ -173,7 +174,7 @@ public final class SmsCbEtwsInfo implements Parcelable { /** * Returns the Warning-Security-Information timestamp (GSM primary notifications only). * As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received. - * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present + * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present or invalid. */ public long getPrimaryNotificationTimestamp() { if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) { @@ -201,18 +202,23 @@ public final class SmsCbEtwsInfo implements Parcelable { // timezoneOffset is in quarter hours. int timeZoneOffsetSeconds = timezoneOffset * 15 * 60; - LocalDateTime localDateTime = LocalDateTime.of( - // We only need to support years above 2000. - year + 2000, - month /* 1-12 */, - day, - hour, - minute, - second); - - long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds; - // Convert to milliseconds, ignore overflow. - return epochSeconds * 1000; + try { + LocalDateTime localDateTime = LocalDateTime.of( + // We only need to support years above 2000. + year + 2000, + month /* 1-12 */, + day, + hour, + minute, + second); + + long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds; + // Convert to milliseconds, ignore overflow. + return epochSeconds * 1000; + } catch (DateTimeException ex) { + // No-op + } + return 0; } /** diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index b376660f839e..183fdcce1ca4 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -670,10 +670,12 @@ public final class SmsManager { } if (priority < 0x00 || priority > 0x03) { + Log.e(TAG, "Invalid Priority " + priority); priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED; } if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) { + Log.e(TAG, "Invalid Validity Period " + validityPeriod); validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED; } @@ -1231,10 +1233,12 @@ public final class SmsManager { } if (priority < 0x00 || priority > 0x03) { + Log.e(TAG, "Invalid Priority " + priority); priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED; } if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) { + Log.e(TAG, "Invalid Validity Period " + validityPeriod); validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED; } diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index e537f666d4c0..717a9b155cbf 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -255,28 +255,6 @@ public class SmsMessage { } /** - * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the - * +CMT unsolicited response (PDU mode, of course) - * +CMT: [<alpha>],<length><CR><LF><pdu> - * - * Only public for debugging and for RIL - * - * {@hide} - */ - public static SmsMessage newFromCMT(byte[] pdu) { - // received SMS in 3GPP format - SmsMessageBase wrappedMessage = - com.android.internal.telephony.gsm.SmsMessage.newFromCMT(pdu); - - if (wrappedMessage != null) { - return new SmsMessage(wrappedMessage); - } else { - Rlog.e(LOG_TAG, "newFromCMT(): wrappedMessage is null"); - return null; - } - } - - /** * Creates an SmsMessage from an SMS EF record. * * @param index Index of SMS EF record. @@ -321,12 +299,9 @@ public class SmsMessage { * @param data Message data. * @param isCdma Indicates weather the type of the SMS is CDMA. * @return An SmsMessage representing the message. - * - * @hide */ - @SystemApi @Nullable - public static SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[] data, boolean isCdma) { + public static SmsMessage createSmsSubmitPdu(@NonNull byte[] data, boolean isCdma) { SmsMessageBase wrappedMessage; if (isCdma) { @@ -342,6 +317,23 @@ public class SmsMessage { } /** + * Create an SmsMessage from a native SMS-Submit PDU, specified by Bluetooth Message Access + * Profile Specification v1.4.2 5.8. + * This is used by Bluetooth MAP profile to decode message when sending non UTF-8 SMS messages. + * + * @param data Message data. + * @param isCdma Indicates weather the type of the SMS is CDMA. + * @return An SmsMessage representing the message. + * + * @hide + */ + @SystemApi + @Nullable + public static SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[] data, boolean isCdma) { + return null; + } + + /** * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the * length in bytes (not hex chars) less the SMSC header * @@ -496,7 +488,10 @@ public class SmsMessage { String newMsgBody = null; Resources r = Resources.getSystem(); if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) { - newMsgBody = Sms7BitEncodingTranslator.translate(text, isCdma); + // 7-bit ASCII table based translation is required only for CDMA single-part SMS since + // ENCODING_7BIT_ASCII is used for CDMA single-part SMS and ENCODING_GSM_7BIT_ALPHABET + // is used for CDMA multi-part SMS. + newMsgBody = Sms7BitEncodingTranslator.translate(text, isCdma && ted.msgCount == 1); } if (TextUtils.isEmpty(newMsgBody)) { newMsgBody = text; diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index e9ee06c246ba..4ad52ae5e077 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -1111,11 +1111,15 @@ public class SubscriptionManager { * individual records themselves. When a change occurs the onSubscriptionsChanged method of * the listener will be invoked immediately if there has been a notification. The * onSubscriptionChanged method will also be triggered once initially when calling this - * function. + * function. The callback will be invoked on the looper specified in the listener's constructor. * * @param listener an instance of {@link OnSubscriptionsChangedListener} with * onSubscriptionsChanged overridden. + * + * @deprecated Will get exception if the parameter listener is not initialized with a Looper. + * Use {@link #addOnSubscriptionsChangedListener(Executor, OnSubscriptionsChangedListener)}. */ + @Deprecated public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { if (listener == null) return; addOnSubscriptionsChangedListener(listener.mExecutor, listener); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 8ae1ee99b060..4b5399e74abf 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -113,8 +113,6 @@ import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.SmsApplication; import com.android.telephony.Rlog; -import java.io.FileInputStream; -import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -127,8 +125,6 @@ import java.util.Objects; import java.util.UUID; import java.util.concurrent.Executor; import java.util.function.Consumer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * Provides access to information about the telephony services on @@ -2341,58 +2337,6 @@ public class TelephonyManager { } /** - * Enables location update notifications. {@link PhoneStateListener#onCellLocationChanged - * PhoneStateListener.onCellLocationChanged} will be called on location updates. - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.CONTROL_LOCATION_UPDATES) - public void enableLocationUpdates() { - enableLocationUpdates(getSubId()); - } - - /** - * Enables location update notifications for a subscription. - * {@link PhoneStateListener#onCellLocationChanged - * PhoneStateListener.onCellLocationChanged} will be called on location updates. - * - * @param subId for which the location updates are enabled - * @hide - */ - @RequiresPermission(android.Manifest.permission.CONTROL_LOCATION_UPDATES) - public void enableLocationUpdates(int subId) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - telephony.enableLocationUpdatesForSubscriber(subId); - } catch (RemoteException ex) { - } catch (NullPointerException ex) { - } - } - - /** - * Disables location update notifications. {@link PhoneStateListener#onCellLocationChanged - * PhoneStateListener.onCellLocationChanged} will be called on location updates. - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.CONTROL_LOCATION_UPDATES) - public void disableLocationUpdates() { - disableLocationUpdates(getSubId()); - } - - /** @hide */ - public void disableLocationUpdates(int subId) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - telephony.disableLocationUpdatesForSubscriber(subId); - } catch (RemoteException ex) { - } catch (NullPointerException ex) { - } - } - - /** * Returns the neighboring cell information of the device. * * @return List of NeighboringCellInfo or null if info unavailable. @@ -2592,7 +2536,8 @@ public class TelephonyManager { return PhoneConstants.PHONE_TYPE_CDMA; case RILConstants.NETWORK_MODE_LTE_ONLY: - if (getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) { + if (TelephonyProperties.lte_on_cdma_device().orElse( + PhoneConstants.LTE_ON_CDMA_FALSE) == PhoneConstants.LTE_ON_CDMA_TRUE) { return PhoneConstants.PHONE_TYPE_CDMA; } else { return PhoneConstants.PHONE_TYPE_GSM; @@ -2603,35 +2548,6 @@ public class TelephonyManager { } /** - * The contents of the /proc/cmdline file - */ - @UnsupportedAppUsage - private static String getProcCmdLine() - { - String cmdline = ""; - FileInputStream is = null; - try { - is = new FileInputStream("/proc/cmdline"); - byte [] buffer = new byte[2048]; - int count = is.read(buffer); - if (count > 0) { - cmdline = new String(buffer, 0, count); - } - } catch (IOException e) { - Rlog.d(TAG, "No /proc/cmdline exception=" + e); - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException e) { - } - } - } - Rlog.d(TAG, "/proc/cmdline=" + cmdline); - return cmdline; - } - - /** * @return The max value for the timeout passed in {@link #requestNumberVerification}. * @hide */ @@ -2640,56 +2556,6 @@ public class TelephonyManager { return MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS; } - /** Kernel command line */ - private static final String sKernelCmdLine = getProcCmdLine(); - - /** Pattern for selecting the product type from the kernel command line */ - private static final Pattern sProductTypePattern = - Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)"); - - /** The ProductType used for LTE on CDMA devices */ - private static final String sLteOnCdmaProductType = - TelephonyProperties.lte_on_cdma_product_type().orElse(""); - - /** - * Return if the current radio is LTE on CDMA. This - * is a tri-state return value as for a period of time - * the mode may be unknown. - * - * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE} - * or {@link PhoneConstants#LTE_ON_CDMA_TRUE} - * - * @hide - */ - @UnsupportedAppUsage - public static int getLteOnCdmaModeStatic() { - int retVal; - int curVal; - String productType = ""; - - curVal = TelephonyProperties.lte_on_cdma_device().orElse( - PhoneConstants.LTE_ON_CDMA_UNKNOWN); - retVal = curVal; - if (retVal == PhoneConstants.LTE_ON_CDMA_UNKNOWN) { - Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine); - if (matcher.find()) { - productType = matcher.group(1); - if (sLteOnCdmaProductType.equals(productType)) { - retVal = PhoneConstants.LTE_ON_CDMA_TRUE; - } else { - retVal = PhoneConstants.LTE_ON_CDMA_FALSE; - } - } else { - retVal = PhoneConstants.LTE_ON_CDMA_FALSE; - } - } - - Rlog.d(TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal + - " product_type='" + productType + - "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'"); - return retVal; - } - // // // Current Network @@ -9307,17 +9173,14 @@ public class TelephonyManager { return RADIO_POWER_UNAVAILABLE; } - /** @hide */ + /** + * This method should not be used due to privacy and stability concerns. + * + * @hide + */ @SystemApi - @SuppressLint("Doclava125") public void updateServiceLocation() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - telephony.updateServiceLocation(); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#updateServiceLocation", e); - } + Log.e(TAG, "Do not call TelephonyManager#updateServiceLocation()"); } /** @hide */ diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java index cdff651c9c3d..e890acb36b48 100644 --- a/telephony/java/android/telephony/TelephonyScanManager.java +++ b/telephony/java/android/telephony/TelephonyScanManager.java @@ -30,6 +30,7 @@ import android.os.Parcelable; import android.os.RemoteException; import android.util.SparseArray; +import com.android.internal.annotations.GuardedBy; import com.android.internal.telephony.ITelephony; import com.android.telephony.Rlog; @@ -55,6 +56,8 @@ public final class TelephonyScanManager { public static final int CALLBACK_SCAN_COMPLETE = 3; /** @hide */ public static final int CALLBACK_RESTRICTED_SCAN_RESULTS = 4; + /** @hide */ + public static final int CALLBACK_TELEPHONY_DIED = 5; /** @hide */ public static final int INVALID_SCAN_ID = -1; @@ -103,17 +106,44 @@ public final class TelephonyScanManager { } private final Looper mLooper; + private final Handler mHandler; private final Messenger mMessenger; private final SparseArray<NetworkScanInfo> mScanInfo = new SparseArray<NetworkScanInfo>(); + private final Binder.DeathRecipient mDeathRecipient; public TelephonyScanManager() { HandlerThread thread = new HandlerThread(TAG); thread.start(); mLooper = thread.getLooper(); - mMessenger = new Messenger(new Handler(mLooper) { + mHandler = new Handler(mLooper) { @Override public void handleMessage(Message message) { checkNotNull(message, "message cannot be null"); + if (message.what == CALLBACK_TELEPHONY_DIED) { + // If there are no objects in mScanInfo then binder death will simply return. + synchronized (mScanInfo) { + for (int i = 0; i < mScanInfo.size(); i++) { + NetworkScanInfo nsi = mScanInfo.valueAt(i); + // At this point we go into panic mode and ignore errors that would + // normally stop the show in order to try and clean up as gracefully + // as possible. + if (nsi == null) continue; // shouldn't be possible + Executor e = nsi.mExecutor; + NetworkScanCallback cb = nsi.mCallback; + if (e == null || cb == null) continue; + try { + e.execute( + () -> cb.onError(NetworkScan.ERROR_MODEM_UNAVAILABLE)); + } catch (java.util.concurrent.RejectedExecutionException ignore) { + // ignore so that we can continue + } + } + + mScanInfo.clear(); + } + return; + } + NetworkScanInfo nsi; synchronized (mScanInfo) { nsi = mScanInfo.get(message.arg2); @@ -158,6 +188,9 @@ public final class TelephonyScanManager { Rlog.d(TAG, "onError: " + errorCode); callback.onError(errorCode); }); + synchronized (mScanInfo) { + mScanInfo.remove(message.arg2); + } } catch (Exception e) { Rlog.e(TAG, "Exception in networkscan callback onError", e); } @@ -168,7 +201,9 @@ public final class TelephonyScanManager { Rlog.d(TAG, "onComplete"); callback.onComplete(); }); - mScanInfo.remove(message.arg2); + synchronized (mScanInfo) { + mScanInfo.remove(message.arg2); + } } catch (Exception e) { Rlog.e(TAG, "Exception in networkscan callback onComplete", e); } @@ -178,7 +213,14 @@ public final class TelephonyScanManager { break; } } - }); + }; + mMessenger = new Messenger(mHandler); + mDeathRecipient = new Binder.DeathRecipient() { + @Override + public void binderDied() { + mHandler.obtainMessage(CALLBACK_TELEPHONY_DIED).sendToTarget(); + } + }; } /** @@ -189,7 +231,7 @@ public final class TelephonyScanManager { * * <p> * Requires Permission: - * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} * Or the calling app has carrier privileges. @see #hasCarrierPrivileges * @@ -204,19 +246,26 @@ public final class TelephonyScanManager { NetworkScanRequest request, Executor executor, NetworkScanCallback callback, String callingPackage, @Nullable String callingFeatureId) { try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - synchronized (mScanInfo) { - int scanId = telephony.requestNetworkScan( - subId, request, mMessenger, new Binder(), callingPackage, - callingFeatureId); - if (scanId == INVALID_SCAN_ID) { - Rlog.e(TAG, "Failed to initiate network scan"); - return null; - } - saveScanInfo(scanId, request, executor, callback); - return new NetworkScan(scanId, subId); - } + final ITelephony telephony = getITelephony(); + if (telephony == null) return null; + + int scanId = telephony.requestNetworkScan( + subId, request, mMessenger, new Binder(), callingPackage, + callingFeatureId); + if (scanId == INVALID_SCAN_ID) { + Rlog.e(TAG, "Failed to initiate network scan"); + return null; + } + synchronized (mScanInfo) { + // We link to death whenever a scan is started to ensure that we are linked + // at the point that phone process death might matter. + // We never unlink because: + // - Duplicate links to death with the same callback do not result in + // extraneous callbacks (the tracking de-dupes). + // - Receiving binderDeath() when no scans are active is a no-op. + telephony.asBinder().linkToDeath(mDeathRecipient, 0); + saveScanInfo(scanId, request, executor, callback); + return new NetworkScan(scanId, subId); } } catch (RemoteException ex) { Rlog.e(TAG, "requestNetworkScan RemoteException", ex); @@ -226,6 +275,7 @@ public final class TelephonyScanManager { return null; } + @GuardedBy("mScanInfo") private void saveScanInfo( int id, NetworkScanRequest request, Executor executor, NetworkScanCallback callback) { mScanInfo.put(id, new NetworkScanInfo(request, executor, callback)); diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java index 81af99fb40b7..d21a05103241 100644 --- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java +++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java @@ -683,5 +683,32 @@ public class ImsCallSessionListener { e.rethrowFromSystemServer(); } } + + /** + * Notifies the result of transfer request. + * @hide + */ + public void callSessionTransferred() { + try { + mListener.callSessionTransferred(); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Notifies the result of transfer request. + * + * @param reasonInfo {@link ImsReasonInfo} containing a reason for the + * session transfer failure + * @hide + */ + public void callSessionTransferFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionTransferFailed(reasonInfo); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } } diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java index ec112790a144..a427d056f915 100644 --- a/telephony/java/android/telephony/ims/RcsUceAdapter.java +++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java @@ -31,7 +31,7 @@ import android.os.RemoteException; import android.telephony.TelephonyFrameworkInitializer; import android.telephony.ims.aidl.IImsRcsController; import android.telephony.ims.aidl.IRcsUceControllerCallback; -import android.telephony.ims.feature.RcsFeature; +import android.telephony.ims.aidl.IRcsUcePublishStateCallback; import android.util.Log; import java.lang.annotation.Retention; @@ -185,6 +185,58 @@ public class RcsUceAdapter { }) public @interface PublishState {} + /** + * An application can use {@link #registerPublishStateCallback} to register a + * {@link PublishStateCallback), which will notify the user when the publish state to the + * network changes. + * @hide + */ + public static class PublishStateCallback { + + private static class PublishStateBinder extends IRcsUcePublishStateCallback.Stub { + + private final PublishStateCallback mLocalCallback; + private Executor mExecutor; + + PublishStateBinder(PublishStateCallback c) { + mLocalCallback = c; + } + + @Override + public void onPublishStateChanged(int publishState) { + if (mLocalCallback == null) return; + + long callingIdentity = Binder.clearCallingIdentity(); + try { + mExecutor.execute(() -> mLocalCallback.onChanged(publishState)); + } finally { + restoreCallingIdentity(callingIdentity); + } + } + + private void setExecutor(Executor executor) { + mExecutor = executor; + } + } + + private final PublishStateBinder mBinder = new PublishStateBinder(this); + + /**@hide*/ + public final IRcsUcePublishStateCallback getBinder() { + return mBinder; + } + + private void setExecutor(Executor executor) { + mBinder.setExecutor(executor); + } + + /** + * Notifies the callback when the publish state has changed. + * @param publishState The latest update to the publish state. + */ + public void onChanged(@PublishState int publishState) { + } + } /** * Provides a one-time callback for the response to a UCE request. After this callback is called @@ -321,6 +373,8 @@ public class RcsUceAdapter { try { return imsRcsController.getUcePublishState(mSubId); + } catch (android.os.ServiceSpecificException e) { + throw new ImsException(e.getMessage(), e.errorCode); } catch (RemoteException e) { Log.e(TAG, "Error calling IImsRcsController#getUcePublishState", e); throw new ImsException("Remote IMS Service is not available", @@ -329,6 +383,91 @@ public class RcsUceAdapter { } /** + * Registers a {@link PublishStateCallback} with the system, which will provide publish state + * updates for the subscription specified in {@link ImsManager@getRcsManager(subid)}. + * <p> + * Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to subscription + * changed events and call {@link #unregisterPublishStateCallback} to clean up. + * <p> + * The registered {@link PublishStateCallback} will also receive a callback when it is + * registered with the current publish state. + * + * @param executor The executor the listener callback events should be run on. + * @param c The {@link PublishStateCallback} to be added. + * @throws ImsException if the subscription associated with this callback is valid, but + * the {@link ImsService} associated with the subscription is not available. This can happen if + * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed + * reason. + * @hide + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void registerPublishStateCallback(@NonNull @CallbackExecutor Executor executor, + @NonNull PublishStateCallback c) throws ImsException { + if (c == null) { + throw new IllegalArgumentException("Must include a non-null PublishStateCallback."); + } + if (executor == null) { + throw new IllegalArgumentException("Must include a non-null Executor."); + } + + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "registerPublishStateCallback : IImsRcsController is null"); + throw new ImsException("Cannot find remote IMS service", + ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + + c.setExecutor(executor); + try { + imsRcsController.registerUcePublishStateCallback(mSubId, c.getBinder()); + } catch (android.os.ServiceSpecificException e) { + throw new ImsException(e.getMessage(), e.errorCode); + } catch (RemoteException e) { + Log.e(TAG, "Error calling IImsRcsController#registerUcePublishStateCallback", e); + throw new ImsException("Remote IMS Service is not available", + ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + } + + /** + * Removes an existing {@link PublishStateCallback}. + * <p> + * When the subscription associated with this callback is removed + * (SIM removed, ESIM swap,etc...), this callback will automatically be removed. If this method + * is called for an inactive subscription, it will result in a no-op. + * + * @param c The callback to be unregistered. + * @throws ImsException if the subscription associated with this callback is valid, but + * the {@link ImsService} associated with the subscription is not available. This can happen if + * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed + * reason. + * @hide + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void unregisterPublishStateCallback(@NonNull PublishStateCallback c) + throws ImsException { + if (c == null) { + throw new IllegalArgumentException("Must include a non-null PublishStateCallback."); + } + IImsRcsController imsRcsController = getIImsRcsController(); + if (imsRcsController == null) { + Log.e(TAG, "unregisterPublishStateCallback: IImsRcsController is null"); + throw new ImsException("Cannot find remote IMS service", + ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + + try { + imsRcsController.unregisterUcePublishStateCallback(mSubId, c.getBinder()); + } catch (android.os.ServiceSpecificException e) { + throw new ImsException(e.getMessage(), e.errorCode); + } catch (RemoteException e) { + Log.e(TAG, "Error calling IImsRcsController#unregisterUcePublishStateCallback", e); + throw new ImsException("Remote IMS Service is not available", + ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + } + + /** * The user’s setting for whether or not User Capability Exchange (UCE) is enabled for the * associated subscription. * <p> diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl index 483c66eedc0c..9e461420e126 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl @@ -19,6 +19,7 @@ package android.telephony.ims.aidl; import android.net.Uri; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IRcsUceControllerCallback; +import android.telephony.ims.aidl.IRcsUcePublishStateCallback; import android.telephony.ims.aidl.IImsRegistrationCallback; import com.android.internal.telephony.IIntegerConsumer; @@ -47,4 +48,6 @@ interface IImsRcsController { int getUcePublishState(int subId); boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId); void setUceSettingEnabled(int subId, boolean isEnabled); + void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c); + void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c); } diff --git a/tools/aapt/tests/TestHelper.h b/telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl index 79174832a54d..b6e84154f80f 100644 --- a/tools/aapt/tests/TestHelper.h +++ b/telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * 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. @@ -14,20 +14,13 @@ * limitations under the License. */ -#ifndef __TEST_HELPER_H -#define __TEST_HELPER_H - -#include <utils/String8.h> - -namespace android { +package android.telephony.ims.aidl; /** - * Stream operator for nicely printing String8's in gtest output. + * Interface for RCS UCE publish state change callbacks. + * + * {@hide} */ -inline std::ostream& operator<<(std::ostream& stream, const String8& str) { - return stream << str.string(); +oneway interface IRcsUcePublishStateCallback { + void onPublishStateChanged(int publishState); } - -} - -#endif diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java index b3b7b200816a..01d468cb53f6 100644 --- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java @@ -343,7 +343,6 @@ public class MmTelFeature extends ImsFeature { * @hide */ @Override - @SystemApi @TestApi public void onIncomingCall(IImsCallSession c, Bundle extras) { } @@ -355,7 +354,6 @@ public class MmTelFeature extends ImsFeature { * @hide */ @Override - @SystemApi @TestApi public void onRejectedCall(ImsCallProfile callProfile, ImsReasonInfo reason) { } @@ -366,7 +364,6 @@ public class MmTelFeature extends ImsFeature { * @hide */ @Override - @SystemApi @TestApi public void onVoiceMessageCountUpdate(int count) { } diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java index 7069e0ab9b1e..2cdf70e6cf4c 100644 --- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java @@ -29,6 +29,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.util.RemoteCallbackListExt; +import com.android.internal.util.ArrayUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -105,6 +106,11 @@ public class ImsRegistrationImplBase { // Locked on mLock, create unspecified disconnect cause. private ImsReasonInfo mLastDisconnectCause = new ImsReasonInfo(); + // We hold onto the uris each time they change so that we can send it to a callback when its + // first added. + private Uri[] mUris = new Uri[0]; + private boolean mUrisSet = false; + /** * @hide */ @@ -208,19 +214,27 @@ public class ImsRegistrationImplBase { } /** - * The this device's subscriber associated {@link Uri}s have changed, which are used to filter - * out this device's {@link Uri}s during conference calling. - * @param uris + * Invoked when the {@link Uri}s associated to this device's subscriber have changed. + * These {@link Uri}s' are filtered out during conference calls. + * + * The {@link Uri}s are not guaranteed to be different between subsequent calls. + * @param uris changed uris */ public final void onSubscriberAssociatedUriChanged(Uri[] uris) { - mCallbacks.broadcastAction((c) -> { - try { - c.onSubscriberAssociatedUriChanged(uris); - } catch (RemoteException e) { - Log.w(LOG_TAG, e + " " + "onSubscriberAssociatedUriChanged() - Skipping " + - "callback."); - } - }); + synchronized (mLock) { + mUris = ArrayUtils.cloneOrNull(uris); + mUrisSet = true; + } + mCallbacks.broadcastAction((c) -> onSubscriberAssociatedUriChanged(c, uris)); + } + + private void onSubscriberAssociatedUriChanged(IImsRegistrationCallback callback, Uri[] uris) { + try { + callback.onSubscriberAssociatedUriChanged(uris); + } catch (RemoteException e) { + Log.w(LOG_TAG, e + " " + "onSubscriberAssociatedUriChanged() - Skipping " + + "callback."); + } } private void updateToState(@ImsRegistrationTech int connType, int newState) { @@ -233,6 +247,10 @@ public class ImsRegistrationImplBase { private void updateToDisconnectedState(ImsReasonInfo info) { synchronized (mLock) { + //We don't want to send this info over if we are disconnected + mUrisSet = false; + mUris = null; + updateToState(REGISTRATION_TECH_NONE, RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); if (info != null) { @@ -260,12 +278,17 @@ public class ImsRegistrationImplBase { * @param c the newly registered callback that will be updated with the current registration * state. */ - private void updateNewCallbackWithState(IImsRegistrationCallback c) throws RemoteException { + private void updateNewCallbackWithState(IImsRegistrationCallback c) + throws RemoteException { int state; ImsReasonInfo disconnectInfo; + boolean urisSet; + Uri[] uris; synchronized (mLock) { state = mRegistrationState; disconnectInfo = mLastDisconnectCause; + urisSet = mUrisSet; + uris = mUris; } switch (state) { case RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED: { @@ -285,5 +308,8 @@ public class ImsRegistrationImplBase { break; } } + if (urisSet) { + onSubscriberAssociatedUriChanged(c, uris); + } } } diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java index ce9a73a21657..a9a33c0e1507 100644 --- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java @@ -403,8 +403,7 @@ public class ImsSmsImplBase { message.mWrappedSmsMessage.mMessageRef, STATUS_REPORT_STATUS_ERROR); } else { - Log.w(LOG_TAG, - "onSmsStatusReportReceivedWithoutMessageRef: Invalid pdu entered."); + Log.w(LOG_TAG, "onSmsStatusReportReceived: Invalid pdu entered."); acknowledgeSmsReport(token, 0, STATUS_REPORT_STATUS_ERROR); } } diff --git a/telephony/java/android/telephony/mbms/MbmsErrors.java b/telephony/java/android/telephony/mbms/MbmsErrors.java index 52e4d333b29d..40f3ae82d778 100644 --- a/telephony/java/android/telephony/mbms/MbmsErrors.java +++ b/telephony/java/android/telephony/mbms/MbmsErrors.java @@ -16,8 +16,12 @@ package android.telephony.mbms; +import android.annotation.IntDef; import android.telephony.MbmsStreamingSession; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + public class MbmsErrors { /** * Indicates that the middleware has sent an error code that is not defined in the version of @@ -138,6 +142,13 @@ public class MbmsErrors { /** Indicates the the middleware has no record of the supplied {@link FileInfo} */ public static final int ERROR_UNKNOWN_FILE_INFO = 403; + + /** + * Indicates that the service announcement descriptor passed via + * {@link android.telephony.MbmsDownloadSession#addServiceAnnouncement(byte[])} + * is malformed. + */ + public static final int ERROR_MALFORMED_SERVICE_ANNOUNCEMENT = 404; } /** @@ -156,5 +167,35 @@ public class MbmsErrors { public static final int ERROR_DUPLICATE_START_GROUP_CALL = 502; } + /** @hide */ + @IntDef(value = { + SUCCESS, + ERROR_NO_UNIQUE_MIDDLEWARE, + ERROR_MIDDLEWARE_NOT_BOUND, + ERROR_MIDDLEWARE_LOST, + InitializationErrors.ERROR_DUPLICATE_INITIALIZE, + InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED, + InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY, + GeneralErrors.ERROR_OUT_OF_MEMORY, + GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE, + GeneralErrors.ERROR_IN_E911, + GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE, + GeneralErrors.ERROR_UNABLE_TO_READ_SIM, + GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED, + StreamingErrors.ERROR_CONCURRENT_SERVICE_LIMIT_REACHED, + StreamingErrors.ERROR_UNABLE_TO_START_SERVICE, + StreamingErrors.ERROR_DUPLICATE_START_STREAM, + DownloadErrors.ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT, + DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST, + DownloadErrors.ERROR_UNKNOWN_FILE_INFO, + DownloadErrors.ERROR_MALFORMED_SERVICE_ANNOUNCEMENT, + GroupCallErrors.ERROR_UNABLE_TO_START_SERVICE, + GroupCallErrors.ERROR_DUPLICATE_START_GROUP_CALL, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface MbmsError { + } + private MbmsErrors() {} } diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl index 445087fb78d5..04efd53eb743 100755 --- a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl +++ b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl @@ -35,6 +35,8 @@ interface IMbmsDownloadService int setTempFileRootDirectory(int subId, String rootDirectoryPath); + int addServiceAnnouncement(int subId, in byte[] contents); + int download(in DownloadRequest downloadRequest); int addStatusListener(in DownloadRequest downloadRequest, diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java index 9f22d0a49806..3053ea03bebe 100644 --- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java +++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java @@ -216,6 +216,29 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub { } /** + * Called when the client application wishes to receive file information according to a + * service announcement descriptor received from a group call server. + * + * The service announcement descriptor is in the format of a multipart MIME file with XML parts, + * though no validation is performed on the contents of the {@code contents} argument -- + * implementing middleware applications should perform their own validation and return + * {@link MbmsErrors.DownloadErrors#ERROR_MALFORMED_SERVICE_ANNOUNCEMENT} if the descriptor is + * malformed. + * + * @param subscriptionId The subscription id the service announcement applies to. + * @param contents The contents of the service announcement descriptor. + * @return {@link MbmsErrors#SUCCESS}, or + * {@link MbmsErrors.DownloadErrors#ERROR_MALFORMED_SERVICE_ANNOUNCEMENT} + */ + // TODO: are there any public specifications of what the file format is that I can link to? + @Override + public @MbmsErrors.MbmsError int addServiceAnnouncement( + int subscriptionId, @NonNull byte[] contents) { + throw new UnsupportedOperationException("addServiceAnnouncement not supported by" + + " this middleware."); + } + + /** * Issues a request to download a set of files. * * The middleware should expect that {@link #setTempFileRootDirectory(int, String)} has been diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index b70937cee8a1..ae1b5c1b50bd 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -222,42 +222,29 @@ interface ITelephony { boolean setRadioPower(boolean turnOn); /** - * Request to update location information in service state + * This method has been removed due to security and stability issues. */ @UnsupportedAppUsage void updateServiceLocation(); /** - * Request to update location information for a subscrition in service state - * @param subId user preferred subId. + * Version of updateServiceLocation that records the caller and validates permissions. */ - void updateServiceLocationForSubscriber(int subId); + void updateServiceLocationWithPackageName(String callingPkg); /** - * Enable location update notifications. + * This method has been removed due to security and stability issues. */ @UnsupportedAppUsage void enableLocationUpdates(); /** - * Enable location update notifications. - * @param subId user preferred subId. - */ - void enableLocationUpdatesForSubscriber(int subId); - - /** - * Disable location update notifications. + * This method has been removed due to security and stability issues. */ @UnsupportedAppUsage void disableLocationUpdates(); /** - * Disable location update notifications. - * @param subId user preferred subId. - */ - void disableLocationUpdatesForSubscriber(int subId); - - /** * Allow mobile data connections. */ @UnsupportedAppUsage diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index 4d677545bc39..151187c5071f 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -108,6 +108,7 @@ public class PhoneConstants { public static final int PIN_RESULT_SUCCESS = 0; public static final int PIN_PASSWORD_INCORRECT = 1; public static final int PIN_GENERAL_FAILURE = 2; + public static final int PIN_OPERATION_ABORTED = 3; /** * Return codes for <code>enableApnType()</code> diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 6ed0be24a0f1..542e08d743ab 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -17,7 +17,7 @@ package com.android.internal.telephony.cdma; import android.compat.annotation.UnsupportedAppUsage; -import android.content.res.Resources; +import android.os.Build; import android.sysprop.TelephonyProperties; import android.telephony.PhoneNumberUtils; import android.telephony.SmsCbLocation; @@ -27,7 +27,6 @@ import android.text.TextUtils; import android.util.Log; import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; -import com.android.internal.telephony.Sms7BitEncodingTranslator; import com.android.internal.telephony.SmsAddress; import com.android.internal.telephony.SmsConstants; import com.android.internal.telephony.SmsHeader; @@ -156,7 +155,8 @@ public class SmsMessage extends SmsMessageBase { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link " + + "android.telephony.SmsMessage} API instead") public static SmsMessage createFromEfRecord(int index, byte[] data) { try { SmsMessage msg = new SmsMessage(); @@ -414,15 +414,7 @@ public class SmsMessage extends SmsMessageBase { @UnsupportedAppUsage public static TextEncodingDetails calculateLength(CharSequence messageBody, boolean use7bitOnly, boolean isEntireMsg) { - CharSequence newMsgBody = null; - Resources r = Resources.getSystem(); - if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) { - newMsgBody = Sms7BitEncodingTranslator.translate(messageBody, true /* isCdmaFormat */); - } - if (TextUtils.isEmpty(newMsgBody)) { - newMsgBody = messageBody; - } - return BearerData.calcTextEncodingDetails(newMsgBody, use7bitOnly, isEntireMsg); + return BearerData.calcTextEncodingDetails(messageBody, use7bitOnly, isEntireMsg); } /** diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java index c074e6e9a438..d186fcf63cfe 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java @@ -21,9 +21,11 @@ import android.content.res.Resources; import android.telephony.SmsCbCmasInfo; import android.telephony.cdma.CdmaSmsCbProgramData; import android.telephony.cdma.CdmaSmsCbProgramResults; +import android.text.TextUtils; import com.android.internal.telephony.GsmAlphabet; import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; +import com.android.internal.telephony.Sms7BitEncodingTranslator; import com.android.internal.telephony.SmsConstants; import com.android.internal.telephony.SmsHeader; import com.android.internal.telephony.SmsMessageBase; @@ -33,6 +35,7 @@ import com.android.internal.util.BitwiseOutputStream; import com.android.telephony.Rlog; import java.io.ByteArrayOutputStream; +import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -313,10 +316,16 @@ public final class BearerData { } public long toMillis() { - LocalDateTime localDateTime = - LocalDateTime.of(year, monthOrdinal, monthDay, hour, minute, second); - Instant instant = localDateTime.toInstant(mZoneId.getRules().getOffset(localDateTime)); - return instant.toEpochMilli(); + try { + LocalDateTime localDateTime = + LocalDateTime.of(year, monthOrdinal, monthDay, hour, minute, second); + Instant instant = + localDateTime.toInstant(mZoneId.getRules().getOffset(localDateTime)); + return instant.toEpochMilli(); + } catch (DateTimeException ex) { + Rlog.e(LOG_TAG, "Invalid timestamp", ex); + } + return 0; } @@ -540,8 +549,17 @@ public final class BearerData { */ public static TextEncodingDetails calcTextEncodingDetails(CharSequence msg, boolean force7BitEncoding, boolean isEntireMsg) { + CharSequence newMsg = null; + Resources r = Resources.getSystem(); + if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) { + newMsg = Sms7BitEncodingTranslator.translate(msg, true /* isCdmaFormat */); + } + if (TextUtils.isEmpty(newMsg)) { + newMsg = msg; + } + TextEncodingDetails ted; - int septets = countAsciiSeptets(msg, force7BitEncoding); + int septets = countAsciiSeptets(newMsg, force7BitEncoding); if (septets != -1 && septets <= SmsConstants.MAX_USER_DATA_SEPTETS) { ted = new TextEncodingDetails(); ted.msgCount = 1; @@ -1082,7 +1100,7 @@ public final class BearerData { bData.hasUserDataHeader = (inStream.read(1) == 1); inStream.skip(3); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "MESSAGE_IDENTIFIER decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1451,7 +1469,7 @@ public final class BearerData { bData.reportReq = (inStream.read(1) == 1); inStream.skip(4); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "REPLY_OPTION decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1470,7 +1488,7 @@ public final class BearerData { decodeSuccess = true; bData.numberOfMessages = IccUtils.cdmaBcdByteToInt((byte)inStream.read(8)); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "NUMBER_OF_MESSAGES decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1489,7 +1507,7 @@ public final class BearerData { decodeSuccess = true; bData.depositIndex = (inStream.read(8) << 8) | inStream.read(8); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "MESSAGE_DEPOSIT_INDEX decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1576,7 +1594,7 @@ public final class BearerData { bData.errorClass = inStream.read(2); bData.messageStatus = inStream.read(6); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "MESSAGE_STATUS decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1596,7 +1614,7 @@ public final class BearerData { decodeSuccess = true; bData.msgCenterTimeStamp = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8)); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "MESSAGE_CENTER_TIME_STAMP decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1615,7 +1633,7 @@ public final class BearerData { decodeSuccess = true; bData.validityPeriodAbsolute = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8)); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "VALIDITY_PERIOD_ABSOLUTE decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1635,7 +1653,7 @@ public final class BearerData { bData.deferredDeliveryTimeAbsolute = TimeStamp.fromByteArray( inStream.readByteArray(6 * 8)); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_ABSOLUTE decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1654,7 +1672,7 @@ public final class BearerData { decodeSuccess = true; bData.deferredDeliveryTimeRelative = inStream.read(8); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "VALIDITY_PERIOD_RELATIVE decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1674,7 +1692,7 @@ public final class BearerData { decodeSuccess = true; bData.validityPeriodRelative = inStream.read(8); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_RELATIVE decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1695,7 +1713,7 @@ public final class BearerData { bData.privacy = inStream.read(2); inStream.skip(6); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "PRIVACY_INDICATOR decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1715,7 +1733,7 @@ public final class BearerData { decodeSuccess = true; bData.language = inStream.read(8); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "LANGUAGE_INDICATOR decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1736,7 +1754,7 @@ public final class BearerData { bData.displayMode = inStream.read(2); inStream.skip(6); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "DISPLAY_MODE decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1757,7 +1775,7 @@ public final class BearerData { bData.priority = inStream.read(2); inStream.skip(6); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "PRIORITY_INDICATOR decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1778,7 +1796,7 @@ public final class BearerData { bData.alert = inStream.read(2); inStream.skip(6); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "ALERT_ON_MESSAGE_DELIVERY decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1798,7 +1816,7 @@ public final class BearerData { decodeSuccess = true; bData.userResponseCode = inStream.read(8); } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "USER_RESPONSE_CODE decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ")"); @@ -1860,7 +1878,7 @@ public final class BearerData { decodeSuccess = true; } - if ((! decodeSuccess) || (paramBits > 0)) { + if ((!decodeSuccess) || (paramBits > 0)) { Rlog.d(LOG_TAG, "SERVICE_CATEGORY_PROGRAM_DATA decode " + (decodeSuccess ? "succeeded" : "failed") + " (extra bits = " + paramBits + ')'); diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index 08580012ad17..7e31c4633050 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -27,6 +27,7 @@ import static com.android.internal.telephony.SmsConstants.MessageClass; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.Resources; +import android.os.Build; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; @@ -42,6 +43,7 @@ import com.android.telephony.Rlog; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.text.ParseException; +import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -90,14 +92,15 @@ public class SmsMessage extends SmsMessageBase { private int mVoiceMailCount = 0; + /** TP-Validity-Period-Format (TP-VPF). See TS 23.040, 9.2.3.3 */ private static final int VALIDITY_PERIOD_FORMAT_NONE = 0x00; private static final int VALIDITY_PERIOD_FORMAT_ENHANCED = 0x01; private static final int VALIDITY_PERIOD_FORMAT_RELATIVE = 0x02; private static final int VALIDITY_PERIOD_FORMAT_ABSOLUTE = 0x03; - //Validity Period min - 5 mins + // Validity Period min - 5 mins private static final int VALIDITY_PERIOD_MIN = 5; - //Validity Period max - 63 weeks + // Validity Period max - 63 weeks private static final int VALIDITY_PERIOD_MAX = 635040; private static final int INVALID_VALIDITY_PERIOD = -1; @@ -138,38 +141,6 @@ public class SmsMessage extends SmsMessageBase { } /** - * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the - * +CMT unsolicited response (PDU mode, of course) - * +CMT: [<alpha>],<length><CR><LF><pdu> - * - * Only public for debugging - * - * {@hide} - */ - public static SmsMessage newFromCMT(byte[] pdu) { - try { - SmsMessage msg = new SmsMessage(); - msg.parsePdu(pdu); - return msg; - } catch (RuntimeException ex) { - Rlog.e(LOG_TAG, "SMS PDU parsing failed: ", ex); - return null; - } - } - - /** @hide */ - public static SmsMessage newFromCDS(byte[] pdu) { - try { - SmsMessage msg = new SmsMessage(); - msg.parsePdu(pdu); - return msg; - } catch (RuntimeException ex) { - Rlog.e(LOG_TAG, "CDS SMS PDU parsing failed: ", ex); - return null; - } - } - - /** * Creates an SmsMessage from an SMS EF record. * * @param index Index of SMS EF record. @@ -178,7 +149,8 @@ public class SmsMessage extends SmsMessageBase { * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link " + + "android.telephony.SmsMessage} API instead") public static SmsMessage createFromEfRecord(int index, byte[] data) { try { SmsMessage msg = new SmsMessage(); @@ -222,20 +194,20 @@ public class SmsMessage extends SmsMessageBase { } /** - * Get Encoded Relative Validty Period Value from Validity period in mins. + * Gets Encoded Relative Validity Period Value from Validity period in mins. * * @param validityPeriod Validity period in mins. * * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. - * ||relValidityPeriod (TP-VP) || || validityPeriod || - * - * 0 to 143 ---> (TP-VP + 1) x 5 minutes - * - * 144 to 167 ---> 12 hours + ((TP-VP -143) x 30 minutes) - * - * 168 to 196 ---> (TP-VP - 166) x 1 day - * - * 197 to 255 ---> (TP-VP - 192) x 1 week + * ------------------------------------------------------------ + * TP-VP | Validity period + * (Relative format) | value + * ------------------------------------------------------------ + * 0 to 143 | (TP-VP + 1) x 5 minutes + * 144 to 167 | 12 hours + ((TP-VP -143) x 30 minutes) + * 168 to 196 | (TP-VP - 166) x 1 day + * 197 to 255 | (TP-VP - 192) x 1 week + * ------------------------------------------------------------ * * @return relValidityPeriod Encoded Relative Validity Period Value. * @hide @@ -243,19 +215,16 @@ public class SmsMessage extends SmsMessageBase { public static int getRelativeValidityPeriod(int validityPeriod) { int relValidityPeriod = INVALID_VALIDITY_PERIOD; - if (validityPeriod < VALIDITY_PERIOD_MIN || validityPeriod > VALIDITY_PERIOD_MAX) { - Rlog.e(LOG_TAG,"Invalid Validity Period" + validityPeriod); - return relValidityPeriod; - } - - if (validityPeriod <= 720) { - relValidityPeriod = (validityPeriod / 5) - 1; - } else if (validityPeriod <= 1440) { - relValidityPeriod = ((validityPeriod - 720) / 30) + 143; - } else if (validityPeriod <= 43200) { - relValidityPeriod = (validityPeriod / 1440) + 166; - } else if (validityPeriod <= 635040) { - relValidityPeriod = (validityPeriod / 10080) + 192; + if (validityPeriod >= VALIDITY_PERIOD_MIN) { + if (validityPeriod <= 720) { + relValidityPeriod = (validityPeriod / 5) - 1; + } else if (validityPeriod <= 1440) { + relValidityPeriod = ((validityPeriod - 720) / 30) + 143; + } else if (validityPeriod <= 43200) { + relValidityPeriod = (validityPeriod / 1440) + 166; + } else if (validityPeriod <= VALIDITY_PERIOD_MAX) { + relValidityPeriod = (validityPeriod / 10080) + 192; + } } return relValidityPeriod; } @@ -365,17 +334,19 @@ public class SmsMessage extends SmsMessageBase { SubmitPdu ret = new SubmitPdu(); - int validityPeriodFormat = VALIDITY_PERIOD_FORMAT_NONE; - int relativeValidityPeriod = INVALID_VALIDITY_PERIOD; + int relativeValidityPeriod = getRelativeValidityPeriod(validityPeriod); + + byte mtiByte = 0x01; // SMS-SUBMIT - // TP-Validity-Period-Format (TP-VPF) in 3GPP TS 23.040 V6.8.1 section 9.2.3.3 - //bit 4:3 = 10 - TP-VP field present - relative format - if((relativeValidityPeriod = getRelativeValidityPeriod(validityPeriod)) >= 0) { - validityPeriodFormat = VALIDITY_PERIOD_FORMAT_RELATIVE; + if (header != null) { + // Set TP-UDHI + mtiByte |= 0x40; } - byte mtiByte = (byte)(0x01 | (validityPeriodFormat << 0x03) | - (header != null ? 0x40 : 0x00)); + if (relativeValidityPeriod != INVALID_VALIDITY_PERIOD) { + // Set TP-Validity-Period-Format (TP-VPF) + mtiByte |= VALIDITY_PERIOD_FORMAT_RELATIVE << 3; + } ByteArrayOutputStream bo = getSubmitPduHead( scAddress, destinationAddress, mtiByte, @@ -447,8 +418,8 @@ public class SmsMessage extends SmsMessageBase { bo.write(0x08); } - if (validityPeriodFormat == VALIDITY_PERIOD_FORMAT_RELATIVE) { - // ( TP-Validity-Period - relative format) + // TP-Validity-Period (TP-VP) + if (relativeValidityPeriod != INVALID_VALIDITY_PERIOD) { bo.write(relativeValidityPeriod); } @@ -885,10 +856,9 @@ public class SmsMessage extends SmsMessageBase { } /** - * Parses an SC timestamp and returns a currentTimeMillis()-style - * timestamp + * Parses an SC timestamp and returns a currentTimeMillis()-style timestamp, or 0 if + * invalid. */ - long getSCTimestampMillis() { // TP-Service-Centre-Time-Stamp int year = IccUtils.gsmBcdByteToInt(mPdu[mCur++]); @@ -914,16 +884,22 @@ public class SmsMessage extends SmsMessageBase { // It's 2006. Should I really support years < 2000? int fullYear = year >= 90 ? year + 1900 : year + 2000; - LocalDateTime localDateTime = LocalDateTime.of( - fullYear, - month /* 1-12 */, - day, - hour, - minute, - second); - long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds; - // Convert to milliseconds. - return epochSeconds * 1000; + try { + LocalDateTime localDateTime = LocalDateTime.of( + fullYear, + month /* 1-12 */, + day, + hour, + minute, + second); + long epochSeconds = + localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds; + // Convert to milliseconds. + return epochSeconds * 1000; + } catch (DateTimeException ex) { + Rlog.e(LOG_TAG, "Invalid timestamp", ex); + } + return 0; } /** @@ -1274,6 +1250,7 @@ public class SmsMessage extends SmsMessageBase { mRecipientAddress = p.getAddress(); // TP-Service-Centre-Time-Stamp mScTimeMillis = p.getSCTimestampMillis(); + // TP-Discharge-Time p.getSCTimestampMillis(); // TP-Status mStatus = p.getByte(); @@ -1332,6 +1309,7 @@ public class SmsMessage extends SmsMessageBase { + " data coding scheme: " + mDataCodingScheme); } + // TP-Service-Centre-Time-Stamp mScTimeMillis = p.getSCTimestampMillis(); if (VDBG) Rlog.d(LOG_TAG, "SMS SC timestamp: " + mScTimeMillis); @@ -1374,23 +1352,17 @@ public class SmsMessage extends SmsMessageBase { // TP-Validity-Period-Format int validityPeriodLength = 0; - int validityPeriodFormat = ((firstByte>>3) & 0x3); - if (0x0 == validityPeriodFormat) /* 00, TP-VP field not present*/ - { + int validityPeriodFormat = ((firstByte >> 3) & 0x3); + if (validityPeriodFormat == VALIDITY_PERIOD_FORMAT_NONE) { validityPeriodLength = 0; - } - else if (0x2 == validityPeriodFormat) /* 10, TP-VP: relative format*/ - { + } else if (validityPeriodFormat == VALIDITY_PERIOD_FORMAT_RELATIVE) { validityPeriodLength = 1; - } - else /* other case, 11 or 01, TP-VP: absolute or enhanced format*/ - { + } else { // VALIDITY_PERIOD_FORMAT_ENHANCED or VALIDITY_PERIOD_FORMAT_ABSOLUTE validityPeriodLength = 7; } // TP-Validity-Period is not used on phone, so just ignore it for now. - while (validityPeriodLength-- > 0) - { + while (validityPeriodLength-- > 0) { p.getByte(); } diff --git a/test-base/Android.bp b/test-base/Android.bp index 69c296e7ee9c..c7c9fc739189 100644 --- a/test-base/Android.bp +++ b/test-base/Android.bp @@ -38,6 +38,7 @@ java_sdk_library { ], compile_dex: true, + default_to_stubs: true, } // Build the android.test.base_static library diff --git a/test-base/api/current.txt b/test-base/api/current.txt index 750fb5988327..823e24db1782 100644 --- a/test-base/api/current.txt +++ b/test-base/api/current.txt @@ -7,8 +7,10 @@ package android.test { method @Deprecated public void assertReadingContentUriRequiresPermission(android.net.Uri, String); method @Deprecated public void assertWritingContentUriRequiresPermission(android.net.Uri, String); method @Deprecated public android.content.Context getContext(); + method @Deprecated public android.content.Context getTestContext(); method @Deprecated protected void scrubClass(Class<?>) throws java.lang.IllegalAccessException; method @Deprecated public void setContext(android.content.Context); + method @Deprecated public void setTestContext(android.content.Context); method @Deprecated @android.test.suitebuilder.annotation.Suppress public void testAndroidTestCaseSetupProperly(); field @Deprecated protected android.content.Context mContext; } diff --git a/test-base/hiddenapi/src/android/test/AndroidTestCase.java b/test-base/hiddenapi/src/android/test/AndroidTestCase.java deleted file mode 100644 index fcb8d432a631..000000000000 --- a/test-base/hiddenapi/src/android/test/AndroidTestCase.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.test; - -import android.compat.annotation.UnsupportedAppUsage; -import android.content.Context; - -import junit.framework.TestCase; - -/** - * @deprecated Stub only - */ -@SuppressWarnings({ "unchecked", "deprecation", "all" }) -@Deprecated -public class AndroidTestCase extends TestCase { - - /** - * Stub only - */ - @UnsupportedAppUsage - public void setTestContext(Context context) { - throw new RuntimeException("Stub!"); - } - - /** - * Stub only - */ - @UnsupportedAppUsage - public Context getTestContext() { - throw new RuntimeException("Stub!"); - } -} diff --git a/test-base/src/android/test/AndroidTestCase.java b/test-base/src/android/test/AndroidTestCase.java index 1e6bd9c14fd9..d3e896be0832 100644 --- a/test-base/src/android/test/AndroidTestCase.java +++ b/test-base/src/android/test/AndroidTestCase.java @@ -71,14 +71,13 @@ public class AndroidTestCase extends TestCase { * latter is provided by the context set with the {@link #setContext} * method. * - * @hide */ public void setTestContext(Context context) { mTestContext = context; } /** - * @hide + * Returns the test context that was set via {@link #setTestContext(Context)}. */ public Context getTestContext() { return mTestContext; diff --git a/test-base/src/android/test/InstrumentationTestCase.java b/test-base/src/android/test/InstrumentationTestCase.java index 6b79314a4385..9f7a2fa44dc2 100644 --- a/test-base/src/android/test/InstrumentationTestCase.java +++ b/test-base/src/android/test/InstrumentationTestCase.java @@ -34,9 +34,9 @@ import junit.framework.TestCase; * A test case that has access to {@link Instrumentation}. * * @deprecated Use - * <a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html"> + * <a href="{@docRoot}reference/androidx/test/platform/app/InstrumentationRegistry.html"> * InstrumentationRegistry</a> instead. New tests should be written using the - * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>. + * <a href="{@docRoot}training/testing/index.html">AndroidX Test Library</a>. */ @Deprecated public class InstrumentationTestCase extends TestCase { diff --git a/test-mock/Android.bp b/test-mock/Android.bp index 248c117d2e03..7d0f92fac4c7 100644 --- a/test-mock/Android.bp +++ b/test-mock/Android.bp @@ -37,6 +37,7 @@ java_sdk_library { "android.test.mock", ], compile_dex: true, + default_to_stubs: true, } // Make the current.txt available for use by the cts/tests/signature tests. diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java index d1d64d39b688..a5c254f1aca2 100644 --- a/test-mock/src/android/test/mock/MockContentProvider.java +++ b/test-mock/src/android/test/mock/MockContentProvider.java @@ -33,6 +33,7 @@ import android.content.res.AssetFileDescriptor; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; +import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.ICancellationSignal; @@ -336,7 +337,7 @@ public class MockContentProvider extends ContentProvider { * @hide */ public IBinder getIContentProviderBinder() { - throw new UnsupportedOperationException("unimplemented mock method"); + return new Binder(); } /** diff --git a/test-runner/Android.bp b/test-runner/Android.bp index 75f5b5a96eb1..1f6db8403eee 100644 --- a/test-runner/Android.bp +++ b/test-runner/Android.bp @@ -41,6 +41,7 @@ java_sdk_library { ], compile_dex: true, + default_to_stubs: true, } // Build the android.test.runner-minus-junit library diff --git a/test-runner/api/current.txt b/test-runner/api/current.txt index c093ac7c8d4d..5407b685bb34 100644 --- a/test-runner/api/current.txt +++ b/test-runner/api/current.txt @@ -78,6 +78,7 @@ package android.test { @Deprecated public class InstrumentationTestRunner extends android.app.Instrumentation implements android.test.TestSuiteProvider { ctor @Deprecated public InstrumentationTestRunner(); + method @Deprecated protected void addTestListener(junit.framework.TestListener); method @Deprecated public junit.framework.TestSuite getAllTests(); method @Deprecated protected android.test.AndroidTestRunner getAndroidTestRunner(); method @Deprecated public android.os.Bundle getArguments(); @@ -100,6 +101,13 @@ package android.test { method @Deprecated public java.util.List<android.content.Intent> getAndClearBroadcastIntents(); } + @Deprecated public class LaunchPerformanceBase extends android.app.Instrumentation { + ctor @Deprecated public LaunchPerformanceBase(); + method @Deprecated protected void LaunchApp(); + field @Deprecated protected android.content.Intent mIntent; + field @Deprecated protected android.os.Bundle mResults; + } + public class LoaderTestCase extends android.test.AndroidTestCase { ctor public LoaderTestCase(); method public <T> T getLoaderResultSynchronously(android.content.Loader<T>); @@ -285,6 +293,11 @@ package android.test.suitebuilder { method @Deprecated public void testSuiteConstructionFailed(); } + @Deprecated public class UnitTestSuiteBuilder extends android.test.suitebuilder.TestSuiteBuilder { + ctor @Deprecated public UnitTestSuiteBuilder(Class); + ctor @Deprecated public UnitTestSuiteBuilder(String, ClassLoader); + } + } package junit.runner { diff --git a/test-runner/src/android/test/InstrumentationTestRunner.java b/test-runner/src/android/test/InstrumentationTestRunner.java index b2582c19b548..07e3f8736cc8 100644 --- a/test-runner/src/android/test/InstrumentationTestRunner.java +++ b/test-runner/src/android/test/InstrumentationTestRunner.java @@ -410,7 +410,6 @@ public class InstrumentationTestRunner extends Instrumentation implements TestSu /** * Add a {@link TestListener} - * @hide */ protected void addTestListener(TestListener listener){ if(mTestRunner!=null && listener!=null){ diff --git a/test-runner/src/android/test/LaunchPerformanceBase.java b/test-runner/src/android/test/LaunchPerformanceBase.java index 62c90d6a4373..d87a8119ae16 100644 --- a/test-runner/src/android/test/LaunchPerformanceBase.java +++ b/test-runner/src/android/test/LaunchPerformanceBase.java @@ -23,12 +23,11 @@ import android.os.Bundle; /** * Base class for all launch performance Instrumentation classes. - * - * @hide */ @Deprecated public class LaunchPerformanceBase extends Instrumentation { + /** @hide */ public static final String LOG_TAG = "Launch Performance"; protected Bundle mResults; @@ -43,8 +42,6 @@ public class LaunchPerformanceBase extends Instrumentation { /** * Launches intent, and waits for idle before returning. - * - * @hide */ protected void LaunchApp() { startActivitySync(mIntent); diff --git a/test-runner/src/android/test/suitebuilder/UnitTestSuiteBuilder.java b/test-runner/src/android/test/suitebuilder/UnitTestSuiteBuilder.java index a746b35e19b7..ea7405b332c0 100644 --- a/test-runner/src/android/test/suitebuilder/UnitTestSuiteBuilder.java +++ b/test-runner/src/android/test/suitebuilder/UnitTestSuiteBuilder.java @@ -19,8 +19,9 @@ package android.test.suitebuilder; /** * A suite builder that finds unit tests. * - * {@hide} Not needed for 1.0 SDK. + * @deprecated android.test.runner is obsolete */ +@Deprecated public class UnitTestSuiteBuilder extends TestSuiteBuilder { public UnitTestSuiteBuilder(Class clazz) { diff --git a/test-runner/tests/Android.bp b/test-runner/tests/Android.bp index 03c73986118d..d74cee4937c9 100644 --- a/test-runner/tests/Android.bp +++ b/test-runner/tests/Android.bp @@ -25,7 +25,7 @@ android_test { // libs: [ - "android.test.runner", + "android.test.runner.impl", "android.test.base", "android.test.mock", ], diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/jni/Android.bp b/tests/Camera2Tests/SmartCamera/SimpleCamera/jni/Android.bp index a23ac38785f6..125deb521ddc 100644 --- a/tests/Camera2Tests/SmartCamera/SimpleCamera/jni/Android.bp +++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/jni/Android.bp @@ -33,5 +33,6 @@ cc_test_library { "-Werror", "-Wno-unused-parameter", ], + header_libs: ["jni_headers"], stl: "c++_static", } diff --git a/tests/DynamicCodeLoggerIntegrationTests/Android.mk b/tests/DynamicCodeLoggerIntegrationTests/Android.mk index 62c1ba89653c..2d58ce8baddc 100644 --- a/tests/DynamicCodeLoggerIntegrationTests/Android.mk +++ b/tests/DynamicCodeLoggerIntegrationTests/Android.mk @@ -36,8 +36,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_MODULE := DynamicCodeLoggerNativeTestLibrary LOCAL_SRC_FILES := src/cpp/com_android_dcl_Jni.cpp -LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) +LOCAL_HEADER_LIBRARIES := jni_headers LOCAL_SDK_VERSION := 28 LOCAL_NDK_STL_VARIANT := c++_static diff --git a/tests/FlickerTests/AndroidTest.xml b/tests/FlickerTests/AndroidTest.xml index d1da47f0f9d8..a331ec5b52bd 100644 --- a/tests/FlickerTests/AndroidTest.xml +++ b/tests/FlickerTests/AndroidTest.xml @@ -9,6 +9,14 @@ <option name="screen-always-on" value="on" /> <!-- prevents the phone from restarting --> <option name="force-skip-system-props" value="true" /> + <!-- set WM tracing verbose level to all --> + <option name="run-command" value="adb shell cmd window tracing level all" /> + <!-- inform WM to log all transactions --> + <option name="run-command" value="adb shell cmd window tracing transaction" /> + </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.DeviceCleaner"> + <!-- keeps the screen on during tests --> + <option name="cleanup-action" value="REBOOT" /> </target_preparer> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true"/> diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java index 5a66e805c575..ad64840aaee2 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java @@ -144,6 +144,19 @@ public class ChangeAppRotationTest extends FlickerTestBase { ); } + @Test + public void checkVisibility_screenshotLayerBecomesInvisible() { + checkResults(result -> LayersTraceSubject.assertThat(result) + .showsLayer(mTestApp.getPackage()) + .then() + .replaceVisibleLayer(mTestApp.getPackage(), "Screenshot") + .then() + .showsLayer(mTestApp.getPackage()).and().showsLayer("Screenshot") + .then() + .replaceVisibleLayer("Screenshot", mTestApp.getPackage()) + .forAllEntries()); + } + @FlakyTest(bugId = 140855415) @Ignore("Waiting bug feedback") @Test diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java index e033d0ab9578..0201a95b18bb 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java @@ -20,7 +20,6 @@ import static android.os.SystemClock.sleep; import static android.view.Surface.rotationToString; import static com.android.server.wm.flicker.helpers.AutomationUtils.clearRecents; -import static com.android.server.wm.flicker.helpers.AutomationUtils.closePipWindow; import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen; import static com.android.server.wm.flicker.helpers.AutomationUtils.expandPipWindow; import static com.android.server.wm.flicker.helpers.AutomationUtils.launchSplitScreen; @@ -176,11 +175,15 @@ class CommonTransitions { .repeat(ITERATIONS); } - static TransitionBuilder appToSplitScreen(IAppHelper testApp, UiDevice device) { + static TransitionBuilder appToSplitScreen(IAppHelper testApp, UiDevice device, + int beginRotation) { + final String testTag = "appToSplitScreen_" + testApp.getLauncherName() + "_" + + rotationToString(beginRotation); return TransitionRunner.newBuilder() - .withTag("appToSplitScreen_" + testApp.getLauncherName()) + .withTag(testTag) .recordAllRuns() .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) + .runBeforeAll(() -> setRotation(device, beginRotation)) .runBefore(testApp::open) .runBefore(device::waitForIdle) .runBefore(() -> sleep(500)) @@ -285,41 +288,52 @@ class CommonTransitions { .repeat(ITERATIONS); } - static TransitionBuilder enterPipMode(PipAppHelper testApp, UiDevice device) { + static TransitionBuilder enterPipMode(PipAppHelper testApp, UiDevice device, + int beginRotation) { return TransitionRunner.newBuilder() - .withTag("enterPipMode_" + testApp.getLauncherName()) + .withTag("enterPipMode_" + testApp.getLauncherName() + + rotationToString(beginRotation)) .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) .runBefore(device::pressHome) + .runBefore(() -> setRotation(device, beginRotation)) .runBefore(testApp::open) .run(() -> testApp.clickEnterPipButton(device)) - .runAfter(() -> closePipWindow(device)) + .runAfter(() -> testApp.closePipWindow(device)) .runAfterAll(testApp::exit) .repeat(ITERATIONS); } - static TransitionBuilder exitPipModeToHome(PipAppHelper testApp, UiDevice device) { + static TransitionBuilder exitPipModeToHome(PipAppHelper testApp, UiDevice device, + int beginRotation) { return TransitionRunner.newBuilder() - .withTag("exitPipModeToHome_" + testApp.getLauncherName()) + .withTag("exitPipModeToHome_" + testApp.getLauncherName() + + rotationToString(beginRotation)) + .recordAllRuns() .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) .runBefore(device::pressHome) + .runBefore(() -> setRotation(device, beginRotation)) .runBefore(testApp::open) - .runBefore(() -> testApp.clickEnterPipButton(device)) - .run(() -> closePipWindow(device)) + .run(() -> testApp.clickEnterPipButton(device)) + .run(() -> testApp.closePipWindow(device)) .run(device::waitForIdle) - .runAfterAll(testApp::exit) + .run(testApp::exit) .repeat(ITERATIONS); } - static TransitionBuilder exitPipModeToApp(PipAppHelper testApp, UiDevice device) { + static TransitionBuilder exitPipModeToApp(PipAppHelper testApp, UiDevice device, + int beginRotation) { return TransitionRunner.newBuilder() - .withTag("exitPipModeToApp_" + testApp.getLauncherName()) + .withTag("exitPipModeToApp_" + testApp.getLauncherName() + + rotationToString(beginRotation)) + .recordAllRuns() .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen) - .runBefore(device::pressHome) - .runBefore(testApp::open) - .runBefore(() -> testApp.clickEnterPipButton(device)) + .run(device::pressHome) + .run(() -> setRotation(device, beginRotation)) + .run(testApp::open) + .run(() -> testApp.clickEnterPipButton(device)) .run(() -> expandPipWindow(device)) .run(device::waitForIdle) - .runAfterAll(testApp::exit) + .run(testApp::exit) .repeat(ITERATIONS); } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java index 8f0177c7afc5..666a0b9be779 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java @@ -94,7 +94,8 @@ public class DebugTest { */ @Test public void openAppToSplitScreen() { - CommonTransitions.appToSplitScreen(testApp, uiDevice).includeJankyRuns().recordAllRuns() + CommonTransitions.appToSplitScreen(testApp, uiDevice, + Surface.ROTATION_0).includeJankyRuns().recordAllRuns() .build().run(); } @@ -116,7 +117,7 @@ public class DebugTest { ImeAppHelper bottomApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); CommonTransitions.resizeSplitScreen(testApp, bottomApp, uiDevice, Surface.ROTATION_0, new Rational(1, 3), new Rational(2, 3)) - .includeJankyRuns().recordEachRun().build().run(); + .includeJankyRuns().build().run(); } // IME tests @@ -128,7 +129,7 @@ public class DebugTest { public void editTextSetFocus() { ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); CommonTransitions.editTextSetFocus(testApp, uiDevice, Surface.ROTATION_0) - .includeJankyRuns().recordEachRun() + .includeJankyRuns() .build().run(); } @@ -139,7 +140,7 @@ public class DebugTest { public void editTextLoseFocusToHome() { ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0) - .includeJankyRuns().recordEachRun() + .includeJankyRuns() .build().run(); } @@ -150,7 +151,7 @@ public class DebugTest { public void editTextLoseFocusToApp() { ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation()); CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0) - .includeJankyRuns().recordEachRun() + .includeJankyRuns() .build().run(); } @@ -162,7 +163,7 @@ public class DebugTest { @Test public void enterPipMode() { PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation()); - CommonTransitions.enterPipMode(testApp, uiDevice).includeJankyRuns().recordEachRun() + CommonTransitions.enterPipMode(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns() .build().run(); } @@ -172,7 +173,8 @@ public class DebugTest { @Test public void exitPipModeToHome() { PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation()); - CommonTransitions.exitPipModeToHome(testApp, uiDevice).includeJankyRuns().recordEachRun() + CommonTransitions.exitPipModeToHome(testApp, uiDevice, Surface.ROTATION_0) + .includeJankyRuns() .build().run(); } @@ -182,7 +184,7 @@ public class DebugTest { @Test public void exitPipModeToApp() { PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation()); - CommonTransitions.exitPipModeToApp(testApp, uiDevice).includeJankyRuns().recordEachRun() + CommonTransitions.exitPipModeToApp(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns() .build().run(); } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java index 883d59ea8a92..4578fa3f0b9a 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java @@ -89,7 +89,7 @@ public class FlickerTestBase { } if (result.screenCaptureVideoExists()) { Log.e(TAG, "Screen capture video saved to " + result - .screenCaptureVideo.toString()); + .screenCaptureVideoPath().toString()); } } }); diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java index efdfaee60e64..2981ff9aefe6 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java @@ -19,6 +19,8 @@ package com.android.server.wm.flicker; import static com.android.server.wm.flicker.CommonTransitions.openAppCold; import static com.android.server.wm.flicker.WmTraceSubject.assertThat; +import android.view.Surface; + import androidx.test.InstrumentationRegistry; import androidx.test.filters.FlakyTest; import androidx.test.filters.LargeTest; @@ -76,10 +78,20 @@ public class OpenAppColdTest extends NonRotationTestBase { @Test public void checkVisibility_wallpaperLayerBecomesInvisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer("Wallpaper") - .then() - .hidesLayer("Wallpaper") - .forAllEntries()); + if (mBeginRotation == Surface.ROTATION_0) { + checkResults(result -> LayersTraceSubject.assertThat(result) + .showsLayer("Wallpaper") + .then() + .replaceVisibleLayer("Wallpaper", mTestApp.getPackage()) + .forAllEntries()); + } else { + checkResults(result -> LayersTraceSubject.assertThat(result) + .showsLayer("Wallpaper") + .then() + .replaceVisibleLayer("Wallpaper", "Screenshot") + .then() + .showsLayer(mTestApp.getPackage()) + .forAllEntries()); + } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java index f8b7938901a8..ddead6d321a0 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java @@ -17,35 +17,38 @@ package com.android.server.wm.flicker; import static com.android.server.wm.flicker.CommonTransitions.appToSplitScreen; -import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds; import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; -import androidx.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; +import org.junit.runners.Parameterized; /** * Test open app to split screen. * To run this test: {@code atest FlickerTests:OpenAppToSplitScreenTest} */ @LargeTest -@RunWith(AndroidJUnit4.class) +@RunWith(Parameterized.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OpenAppToSplitScreenTest extends FlickerTestBase { +public class OpenAppToSplitScreenTest extends NonRotationTestBase { + + public OpenAppToSplitScreenTest(String beginRotationName, int beginRotation) { + super(beginRotationName, beginRotation); - public OpenAppToSplitScreenTest() { this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(), "com.android.server.wm.flicker.testapp", "SimpleApp"); } @Before public void runTransition() { - super.runTransition(appToSplitScreen(mTestApp, mUiDevice).includeJankyRuns().build()); + super.runTransition(appToSplitScreen(mTestApp, mUiDevice, mBeginRotation) + .includeJankyRuns() + .build()); } @Test @@ -70,25 +73,6 @@ public class OpenAppToSplitScreenTest extends FlickerTestBase { } @Test - public void checkCoveredRegion_noUncoveredRegions() { - checkResults(result -> - LayersTraceSubject.assertThat(result) - .coversRegion(getDisplayBounds()).forAllEntries()); - } - - @Test - public void checkVisibility_navBarLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()); - } - - @Test - public void checkVisibility_statusBarLayerIsAlwaysVisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()); - } - - @Test public void checkVisibility_dividerLayerBecomesVisible() { checkResults(result -> LayersTraceSubject.assertThat(result) .hidesLayer(DOCKED_STACK_DIVIDER) diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java index 7ce6315f529a..bb684d19d645 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java @@ -19,6 +19,8 @@ package com.android.server.wm.flicker; import static com.android.server.wm.flicker.CommonTransitions.openAppWarm; import static com.android.server.wm.flicker.WmTraceSubject.assertThat; +import android.view.Surface; + import androidx.test.InstrumentationRegistry; import androidx.test.filters.FlakyTest; import androidx.test.filters.LargeTest; @@ -76,10 +78,20 @@ public class OpenAppWarmTest extends NonRotationTestBase { @Test public void checkVisibility_wallpaperLayerBecomesInvisible() { - checkResults(result -> LayersTraceSubject.assertThat(result) - .showsLayer("Wallpaper") - .then() - .hidesLayer("Wallpaper") - .forAllEntries()); + if (mBeginRotation == Surface.ROTATION_0) { + checkResults(result -> LayersTraceSubject.assertThat(result) + .showsLayer("Wallpaper") + .then() + .replaceVisibleLayer("Wallpaper", mTestApp.getPackage()) + .forAllEntries()); + } else { + checkResults(result -> LayersTraceSubject.assertThat(result) + .showsLayer("Wallpaper") + .then() + .replaceVisibleLayer("Wallpaper", "Screenshot") + .then() + .showsLayer(mTestApp.getPackage()) + .forAllEntries()); + } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java new file mode 100644 index 000000000000..85706bd14c5e --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java @@ -0,0 +1,89 @@ +/* + * 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 com.android.server.wm.flicker; + +import static com.android.server.wm.flicker.CommonTransitions.exitPipModeToApp; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.LargeTest; + +import com.android.server.wm.flicker.helpers.PipAppHelper; + +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.junit.runners.Parameterized; + +/** + * Test Pip launch. + * To run this test: {@code atest FlickerTests:PipToAppTest} + */ +@LargeTest +@RunWith(Parameterized.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class PipToAppTest extends NonRotationTestBase { + + static final String sPipWindowTitle = "PipMenuActivity"; + + public PipToAppTest(String beginRotationName, int beginRotation) { + super(beginRotationName, beginRotation); + + this.mTestApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation()); + } + + @Before + public void runTransition() { + run(exitPipModeToApp((PipAppHelper) mTestApp, mUiDevice, mBeginRotation) + .includeJankyRuns().build()); + } + + @Test + public void checkVisibility_pipWindowBecomesVisible() { + checkResults(result -> WmTraceSubject.assertThat(result) + .skipUntilFirstAssertion() + .showsAppWindowOnTop(sPipWindowTitle) + .then() + .hidesAppWindow(sPipWindowTitle) + .forAllEntries()); + } + + @Test + public void checkVisibility_pipLayerBecomesVisible() { + checkResults(result -> LayersTraceSubject.assertThat(result) + .skipUntilFirstAssertion() + .showsLayer(sPipWindowTitle) + .then() + .hidesLayer(sPipWindowTitle) + .forAllEntries()); + } + + @Test + public void checkVisibility_backgroundWindowVisibleBehindPipLayer() { + checkResults(result -> WmTraceSubject.assertThat(result) + .skipUntilFirstAssertion() + .showsAppWindowOnTop(sPipWindowTitle) + .then() + .showsBelowAppWindow("Wallpaper") + .then() + .showsAppWindowOnTop(mTestApp.getPackage()) + .then() + .hidesAppWindowOnTop(mTestApp.getPackage()) + .forAllEntries()); + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java new file mode 100644 index 000000000000..ef856dc52167 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java @@ -0,0 +1,93 @@ +/* + * 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 com.android.server.wm.flicker; + +import static com.android.server.wm.flicker.CommonTransitions.exitPipModeToHome; + +import android.view.Surface; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.LargeTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.server.wm.flicker.helpers.PipAppHelper; + +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; + +/** + * Test Pip launch. + * To run this test: {@code atest FlickerTests:PipToHomeTest} + */ +@LargeTest +@RunWith(AndroidJUnit4.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class PipToHomeTest extends FlickerTestBase { + + static final String sPipWindowTitle = "PipActivity"; + + // public PipToHomeTest(String beginRotationName, int beginRotation) { + public PipToHomeTest() { + // super(beginRotationName, beginRotation); + + this.mTestApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation()); + } + + @Before + public void runTransition() { + // run(exitPipModeToHome((PipAppHelper) mTestApp, mUiDevice, mBeginRotation) + run(exitPipModeToHome((PipAppHelper) mTestApp, mUiDevice, Surface.ROTATION_0) + .includeJankyRuns().build()); + } + + @Ignore + @Test + public void checkVisibility_pipWindowBecomesVisible() { + checkResults(result -> WmTraceSubject.assertThat(result) + .skipUntilFirstAssertion() + .showsAppWindowOnTop(sPipWindowTitle) + .then() + .hidesAppWindow(sPipWindowTitle) + .forAllEntries()); + } + + @Test + public void checkVisibility_pipLayerBecomesVisible() { + checkResults(result -> LayersTraceSubject.assertThat(result) + .skipUntilFirstAssertion() + .showsLayer(sPipWindowTitle) + .then() + .hidesLayer(sPipWindowTitle) + .forAllEntries()); + } + + @Ignore + @Test + public void checkVisibility_backgroundWindowVisibleBehindPipLayer() { + checkResults(result -> WmTraceSubject.assertThat(result) + .showsAppWindowOnTop(sPipWindowTitle) + .then() + .showsBelowAppWindow("Wallpaper") + .then() + .showsAppWindowOnTop("Wallpaper") + .forAllEntries()); + } +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java index 29b624005495..e36701be0cad 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java @@ -95,7 +95,7 @@ public class ResizeSplitScreenTest extends NonRotationTestBase { Rect displayBounds = getDisplayBounds(); checkResults(result -> { LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(), - result.getLayersTracePath()); + result.getLayersTracePath(), result.getLayersTraceChecksum()); assertThat(entries.getEntries()).isNotEmpty(); Rect startingDividerBounds = entries.getEntries().get(0).getVisibleBounds @@ -124,7 +124,7 @@ public class ResizeSplitScreenTest extends NonRotationTestBase { Rect displayBounds = getDisplayBounds(); checkResults(result -> { LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(), - result.getLayersTracePath()); + result.getLayersTracePath(), result.getLayersTraceChecksum()); assertThat(entries.getEntries()).isNotEmpty(); Rect endingDividerBounds = entries.getEntries().get( diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java index d00e11b2994d..d5f9a2062a17 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java @@ -40,4 +40,8 @@ public class PipAppHelper extends FlickerAppHelper { } } + public void closePipWindow(UiDevice device) { + AutomationUtils.closePipWindow(device); + } + } diff --git a/tests/GamePerformance/Android.bp b/tests/GamePerformance/Android.bp new file mode 100644 index 000000000000..648fd8151b4e --- /dev/null +++ b/tests/GamePerformance/Android.bp @@ -0,0 +1,32 @@ +// 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. + +android_test_helper_app { + name: "GamePerformance", + // Don't include this package in any target + dex_preopt: { + enabled: false, + }, + optimize: { + enabled: false, + }, + srcs: ["src/**/*.java"], + static_libs: ["android-support-test"], + libs: [ + "android.test.base", + "android.test.runner", + ], + platform_apis: true, + certificate: "platform", +} diff --git a/tests/GamePerformance/Android.mk b/tests/GamePerformance/Android.mk deleted file mode 100644 index 58654de34029..000000000000 --- a/tests/GamePerformance/Android.mk +++ /dev/null @@ -1,39 +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. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -# Don't include this package in any target -LOCAL_MODULE_TAGS := tests - -LOCAL_DEX_PREOPT := false - -LOCAL_PROGUARD_ENABLED := disabled - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_STATIC_JAVA_LIBRARIES := android-support-test - -LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner - -LOCAL_PACKAGE_NAME := GamePerformance - -LOCAL_PRIVATE_PLATFORM_APIS := true - -LOCAL_CERTIFICATE := platform - - -include $(BUILD_PACKAGE) diff --git a/tests/ProtoInputStreamTests/Android.bp b/tests/ProtoInputStreamTests/Android.bp new file mode 100644 index 000000000000..ecc405664128 --- /dev/null +++ b/tests/ProtoInputStreamTests/Android.bp @@ -0,0 +1,33 @@ +// 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. + +android_test { + name: "ProtoInputStreamTests", + proto: { + type: "nano", + }, + srcs: [ + "src/**/*.java", + "src/**/*.proto", + ], + platform_apis: true, + certificate: "platform", + test_suites: ["device-tests"], + libs: ["android.test.runner"], + static_libs: [ + "androidx.test.rules", + "frameworks-base-testutils", + "mockito-target-minus-junit4", + ], +} diff --git a/tests/ProtoInputStreamTests/Android.mk b/tests/ProtoInputStreamTests/Android.mk deleted file mode 100644 index eb747cc2cdcc..000000000000 --- a/tests/ProtoInputStreamTests/Android.mk +++ /dev/null @@ -1,34 +0,0 @@ -# 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. - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_PACKAGE_NAME := ProtoInputStreamTests -LOCAL_PROTOC_OPTIMIZE_TYPE := nano -LOCAL_MODULE_TAGS := tests optional -LOCAL_SRC_FILES := \ - $(call all-java-files-under, src) \ - $(call all-proto-files-under, src) -LOCAL_PRIVATE_PLATFORM_APIS := true -LOCAL_CERTIFICATE := platform -LOCAL_COMPATIBILITY_SUITE := device-tests - -LOCAL_JAVA_LIBRARIES := android.test.runner -LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx.test.rules \ - frameworks-base-testutils \ - mockito-target-minus-junit4 - -include $(BUILD_PACKAGE)
\ No newline at end of file diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt index ef15b668e24c..a50f0461fae6 100644 --- a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt +++ b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt @@ -39,12 +39,12 @@ class MatchAllNetworkSpecifierTest { } @Test(expected = IllegalStateException::class) - fun testSatisfiedBy() { + fun testCanBeSatisfiedBy() { 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) + specifier.canBeSatisfiedBy(wifiAwareNetworkSpecifier) } } diff --git a/tests/net/integration/AndroidManifest.xml b/tests/net/integration/AndroidManifest.xml index 09c0e4826075..f5a4234ede9e 100644 --- a/tests/net/integration/AndroidManifest.xml +++ b/tests/net/integration/AndroidManifest.xml @@ -16,50 +16,55 @@ * limitations under the License. */ --> + <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.server.net.integrationtests"> + package="com.android.server.net.integrationtests"> <!-- For ConnectivityService registerReceiverAsUser (receiving broadcasts) --> - <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/> <!-- PermissionMonitor sets network permissions for each user --> - <uses-permission android:name="android.permission.MANAGE_USERS" /> + <uses-permission android:name="android.permission.MANAGE_USERS"/> <!-- ConnectivityService sends notifications to BatteryStats --> - <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" /> + <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/> <!-- Reading network status --> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <uses-permission android:name="android.permission.NETWORK_FACTORY" /> - <uses-permission android:name="android.permission.NETWORK_STACK" /> - <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" /> - <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> + <uses-permission android:name="android.permission.NETWORK_FACTORY"/> + <!-- Obtain LinkProperties callbacks with sensitive fields --> + <uses-permission android:name="android.permission.NETWORK_SETTINGS" /> + <uses-permission android:name="android.permission.NETWORK_STACK"/> + <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY"/> + <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> <!-- Reading DeviceConfig flags --> - <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" /> + <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/> <application android:debuggable="true"> - <uses-library android:name="android.test.runner" /> + <uses-library android:name="android.test.runner"/> <!-- This manifest is merged with the base manifest of the real NetworkStack app. - Remove the NetworkStackService from the base (real) manifest, and replace with a test - service that responds to the same intent --> + Remove the NetworkStackService from the base (real) manifest, and replace with a test + service that responds to the same intent --> <service android:name=".TestNetworkStackService" - android:process="com.android.server.net.integrationtests.testnetworkstack"> + android:process="com.android.server.net.integrationtests.testnetworkstack" + android:exported="true"> <intent-filter> <action android:name="android.net.INetworkStackConnector.Test"/> </intent-filter> </service> <service android:name=".NetworkStackInstrumentationService" - android:process="com.android.server.net.integrationtests.testnetworkstack"> + android:process="com.android.server.net.integrationtests.testnetworkstack" + android:exported="true"> <intent-filter> <action android:name=".INetworkStackInstrumentation"/> </intent-filter> </service> <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService" - android:process="com.android.server.net.integrationtests.testnetworkstack" - android:permission="android.permission.BIND_JOB_SERVICE"/> + android:process="com.android.server.net.integrationtests.testnetworkstack" + android:permission="android.permission.BIND_JOB_SERVICE"/> </application> <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.server.net.integrationtests" - android:label="Frameworks Net Integration Tests" /> + android:targetPackage="com.android.server.net.integrationtests" + android:label="Frameworks Net Integration Tests"/> </manifest> diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt index c4801aab5c32..bc069e148b99 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt +++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt @@ -28,10 +28,13 @@ import android.net.INetd import android.net.INetworkPolicyManager import android.net.INetworkStatsService import android.net.LinkProperties +import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET +import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED import android.net.NetworkCapabilities.TRANSPORT_CELLULAR import android.net.NetworkRequest import android.net.TestNetworkStackClient +import android.net.Uri import android.net.metrics.IpConnectivityLog import android.os.ConditionVariable import android.os.IBinder @@ -64,6 +67,8 @@ import org.mockito.Mockito.spy import org.mockito.MockitoAnnotations import org.mockito.Spy import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNotNull import kotlin.test.assertTrue import kotlin.test.fail @@ -110,6 +115,10 @@ class ConnectivityServiceIntegrationTest { private val bindingCondition = ConditionVariable(false) private val realContext get() = InstrumentationRegistry.getInstrumentation().context + private val httpProbeUrl get() = + realContext.getResources().getString(R.string.config_captive_portal_http_url) + private val httpsProbeUrl get() = + realContext.getResources().getString(R.string.config_captive_portal_https_url) private class InstrumentationServiceConnection : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { @@ -188,12 +197,8 @@ class ConnectivityServiceIntegrationTest { val testCallback = TestableNetworkCallback() cm.registerNetworkCallback(request, testCallback) - nsInstrumentation.addHttpResponse(HttpResponse( - "http://test.android.com", - responseCode = 204, contentLength = 42, redirectUrl = null)) - nsInstrumentation.addHttpResponse(HttpResponse( - "https://secure.test.android.com", - responseCode = 204, contentLength = 42, redirectUrl = null)) + nsInstrumentation.addHttpResponse(HttpResponse(httpProbeUrl, responseCode = 204)) + nsInstrumentation.addHttpResponse(HttpResponse(httpsProbeUrl, responseCode = 204)) val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, LinkProperties(), context) networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS) @@ -204,4 +209,52 @@ class ConnectivityServiceIntegrationTest { testCallback.expectAvailableThenValidatedCallbacks(na.network, TEST_TIMEOUT_MS) assertEquals(2, nsInstrumentation.getRequestUrls().size) } + + @Test + fun testCapportApi() { + val request = NetworkRequest.Builder() + .clearCapabilities() + .addCapability(NET_CAPABILITY_INTERNET) + .build() + val testCb = TestableNetworkCallback() + val apiUrl = "https://capport.android.com" + + cm.registerNetworkCallback(request, testCb) + nsInstrumentation.addHttpResponse(HttpResponse( + apiUrl, + """ + |{ + | "captive": true, + | "user-portal-url": "https://login.capport.android.com", + | "venue-info-url": "https://venueinfo.capport.android.com" + |} + """.trimMargin())) + + // Tests will fail if a non-mocked query is received: mock the HTTPS probe, but not the + // HTTP probe as it should not be sent. + // Even if the HTTPS probe succeeds, a portal should be detected as the API takes precedence + // in that case. + nsInstrumentation.addHttpResponse(HttpResponse(httpsProbeUrl, responseCode = 204)) + + val lp = LinkProperties() + lp.captivePortalApiUrl = Uri.parse(apiUrl) + val na = NetworkAgentWrapper(TRANSPORT_CELLULAR, lp, context) + networkStackClient.verifyNetworkMonitorCreated(na.network, TEST_TIMEOUT_MS) + + na.addCapability(NET_CAPABILITY_INTERNET) + na.connect() + + testCb.expectAvailableCallbacks(na.network, validated = false, tmt = TEST_TIMEOUT_MS) + + val capportData = testCb.expectLinkPropertiesThat(na, TEST_TIMEOUT_MS) { + it.captivePortalData != null + }.lp.captivePortalData + assertNotNull(capportData) + assertTrue(capportData.isCaptive) + assertEquals(Uri.parse("https://login.capport.android.com"), capportData.userPortalUrl) + assertEquals(Uri.parse("https://venueinfo.capport.android.com"), capportData.venueInfoUrl) + + val nc = testCb.expectCapabilitiesWith(NET_CAPABILITY_CAPTIVE_PORTAL, na, TEST_TIMEOUT_MS) + assertFalse(nc.hasCapability(NET_CAPABILITY_VALIDATED)) + } }
\ No newline at end of file diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt b/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt index 45073d8df3f7..e2063138fef1 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt +++ b/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt @@ -22,16 +22,21 @@ import android.os.Parcelable data class HttpResponse( val requestUrl: String, val responseCode: Int, - val contentLength: Long, - val redirectUrl: String? + val content: String = "", + val redirectUrl: String? = null ) : Parcelable { - constructor(p: Parcel): this(p.readString(), p.readInt(), p.readLong(), p.readString()) + constructor(p: Parcel): this(p.readString(), p.readInt(), p.readString(), p.readString()) + constructor(requestUrl: String, contentBody: String): this( + requestUrl, + responseCode = 200, + content = contentBody, + redirectUrl = null) override fun writeToParcel(dest: Parcel, flags: Int) { with(dest) { writeString(requestUrl) writeInt(responseCode) - writeLong(contentLength) + writeString(content) writeString(redirectUrl) } } diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt index 4827d2997d93..e807952cec11 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt +++ b/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt @@ -65,6 +65,9 @@ class NetworkStackInstrumentationService : Service() { * * <p>For any subsequent HTTP/HTTPS query, the first response with a matching URL will be * used to mock the query response. + * + * <p>All requests that are expected to be sent must have a mock response: if an unexpected + * request is seen, the test will fail. */ override fun addHttpResponse(response: HttpResponse) { httpResponses.getValue(response.requestUrl).add(response) diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt index 8c2de4035d0b..a44ad1e05259 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt +++ b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt @@ -33,9 +33,11 @@ import com.android.server.net.integrationtests.NetworkStackInstrumentationServic import org.mockito.Mockito.doReturn import org.mockito.Mockito.mock import org.mockito.Mockito.spy +import java.io.ByteArrayInputStream import java.net.HttpURLConnection import java.net.URL import java.net.URLConnection +import java.nio.charset.StandardCharsets private const val TEST_NETID = 42 @@ -71,11 +73,13 @@ class TestNetworkStackService : Service() { private inner class TestNetwork(netId: Int) : Network(netId) { override fun openConnection(url: URL): URLConnection { val response = InstrumentationConnector.processRequest(url) + val responseBytes = response.content.toByteArray(StandardCharsets.UTF_8) val connection = mock(HttpURLConnection::class.java) doReturn(response.responseCode).`when`(connection).responseCode - doReturn(response.contentLength).`when`(connection).contentLengthLong + doReturn(responseBytes.size.toLong()).`when`(connection).contentLengthLong doReturn(response.redirectUrl).`when`(connection).getHeaderField("location") + doReturn(ByteArrayInputStream(responseBytes)).`when`(connection).inputStream return connection } } diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java index d6bf334ee56a..d74a621842f9 100644 --- a/tests/net/java/android/net/ConnectivityManagerTest.java +++ b/tests/net/java/android/net/ConnectivityManagerTest.java @@ -36,6 +36,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; @@ -213,7 +214,7 @@ public class ConnectivityManagerTest { // register callback when(mService.requestNetwork( - any(), captor.capture(), anyInt(), any(), anyInt(), any())) + any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class))) .thenReturn(request); manager.requestNetwork(request, callback, handler); @@ -242,7 +243,7 @@ public class ConnectivityManagerTest { // register callback when(mService.requestNetwork( - any(), captor.capture(), anyInt(), any(), anyInt(), any())) + any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class))) .thenReturn(req1); manager.requestNetwork(req1, callback, handler); @@ -261,7 +262,7 @@ public class ConnectivityManagerTest { // callback can be registered again when(mService.requestNetwork( - any(), captor.capture(), anyInt(), any(), anyInt(), any())) + any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class))) .thenReturn(req2); manager.requestNetwork(req2, callback, handler); @@ -285,8 +286,8 @@ public class ConnectivityManagerTest { info.targetSdkVersion = VERSION_CODES.N_MR1 + 1; when(mCtx.getApplicationInfo()).thenReturn(info); - when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any())) - .thenReturn(request); + when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any(), + nullable(String.class))).thenReturn(request); Handler handler = new Handler(Looper.getMainLooper()); manager.requestNetwork(request, callback, handler); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 385005f90c3b..bc853749e294 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -3054,6 +3054,13 @@ public class ConnectivityServiceTest { assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar); } + /** + * @return the context's attribution tag + */ + private String getAttributionTag() { + return null; + } + @Test public void testInvalidNetworkSpecifier() { assertThrows(IllegalArgumentException.class, () -> { @@ -3066,7 +3073,8 @@ public class ConnectivityServiceTest { networkCapabilities.addTransportType(TRANSPORT_WIFI) .setNetworkSpecifier(new MatchAllNetworkSpecifier()); mService.requestNetwork(networkCapabilities, null, 0, null, - ConnectivityManager.TYPE_WIFI, mContext.getPackageName()); + ConnectivityManager.TYPE_WIFI, mContext.getPackageName(), + getAttributionTag()); }); class NonParcelableSpecifier extends NetworkSpecifier { diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt index 42d4cf3c382b..a10a3c81bc86 100644 --- a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt +++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt @@ -14,6 +14,11 @@ * limitations under the License. */ +// Don't warn about deprecated types anywhere in this test, because LegacyTypeTracker's very reason +// for existence is to power deprecated APIs. The annotation has to apply to the whole file because +// otherwise warnings will be generated by the imports of deprecated constants like TYPE_xxx. +@file:Suppress("DEPRECATION") + package com.android.server import android.net.ConnectivityManager.TYPE_ETHERNET diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java index 39f849c340f7..5a29c2c96ba7 100644 --- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java @@ -76,7 +76,6 @@ import com.android.server.pm.PackageList; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; @@ -88,7 +87,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Set; - @RunWith(AndroidJUnit4.class) @SmallTest public class PermissionMonitorTest { @@ -116,8 +114,8 @@ public class PermissionMonitorTest { @Mock private INetd mNetdService; @Mock private PackageManagerInternal mMockPmi; @Mock private UserManager mUserManager; + @Mock private PermissionMonitor.Dependencies mDeps; - private PackageManagerInternal.PackageListObserver mObserver; private PermissionMonitor mPermissionMonitor; @Before @@ -131,7 +129,7 @@ public class PermissionMonitorTest { new UserInfo(MOCK_USER2, "", 0), })); - mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService)); + mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps)); LocalServices.removeServiceForTest(PackageManagerInternal.class); LocalServices.addService(PackageManagerInternal.class, mMockPmi); @@ -139,11 +137,7 @@ public class PermissionMonitorTest { /* observer */ null)); when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(/* empty app list */ null); mPermissionMonitor.startMonitoring(); - - final ArgumentCaptor<PackageManagerInternal.PackageListObserver> observerCaptor = - ArgumentCaptor.forClass(PackageManagerInternal.PackageListObserver.class); - verify(mMockPmi).getPackageList(observerCaptor.capture()); - mObserver = observerCaptor.getValue(); + verify(mMockPmi).getPackageList(mPermissionMonitor); } private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid, @@ -290,14 +284,14 @@ public class PermissionMonitorTest { @Test public void testHasRestrictedNetworkPermissionSystemUid() { - doReturn(VERSION_P).when(mPermissionMonitor).getDeviceFirstSdkInt(); + doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt(); assertTrue(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID)); assertTrue(hasRestrictedNetworkPermission( PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_INTERNAL)); assertTrue(hasRestrictedNetworkPermission( PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - doReturn(VERSION_Q).when(mPermissionMonitor).getDeviceFirstSdkInt(); + doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt(); assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID)); assertFalse(hasRestrictedNetworkPermission( PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_INTERNAL)); @@ -450,13 +444,13 @@ public class PermissionMonitorTest { new int[]{MOCK_UID1}); // Remove MOCK_UID1, expect no permission left for all user. - mPermissionMonitor.onPackageRemoved(MOCK_UID1); - removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, MOCK_UID1); + mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); + removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1); mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2}, new int[]{MOCK_UID1}); // Remove SYSTEM_PACKAGE1, expect permission downgrade. when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{SYSTEM_PACKAGE2}); - removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, SYSTEM_UID); + removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, SYSTEM_PACKAGE1, SYSTEM_UID); mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1, MOCK_USER2}, new int[]{SYSTEM_UID}); @@ -465,7 +459,7 @@ public class PermissionMonitorTest { // Remove all packages, expect no permission left. when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{}); - removePackageForUsers(new int[]{MOCK_USER2}, SYSTEM_UID); + removePackageForUsers(new int[]{MOCK_USER2}, SYSTEM_PACKAGE2, SYSTEM_UID); mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2}, new int[]{SYSTEM_UID, MOCK_UID1}); @@ -501,7 +495,8 @@ public class PermissionMonitorTest { reset(mNetdService); // When MOCK_UID1 package is uninstalled and reinstalled, expect Netd to be updated - mPermissionMonitor.onPackageRemoved(UserHandle.getUid(MOCK_USER1, MOCK_UID1)); + mPermissionMonitor.onPackageRemoved( + MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1)); verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1})); mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1)); verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), @@ -545,7 +540,8 @@ public class PermissionMonitorTest { aryEq(new int[] {MOCK_UID1})); // Removed package should have its uid rules removed - mPermissionMonitor.onPackageRemoved(UserHandle.getUid(MOCK_USER1, MOCK_UID1)); + mPermissionMonitor.onPackageRemoved( + MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1)); verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1})); } @@ -559,9 +555,9 @@ public class PermissionMonitorTest { } } - private void removePackageForUsers(int[] users, int uid) { + private void removePackageForUsers(int[] users, String packageName, int uid) { for (final int user : users) { - mPermissionMonitor.onPackageRemoved(UserHandle.getUid(user, uid)); + mPermissionMonitor.onPackageRemoved(packageName, UserHandle.getUid(user, uid)); } } @@ -647,7 +643,7 @@ public class PermissionMonitorTest { private PackageInfo addPackage(String packageName, int uid, String[] permissions) throws Exception { PackageInfo packageInfo = setPackagePermissions(packageName, uid, permissions); - mObserver.onPackageAdded(packageName, uid); + mPermissionMonitor.onPackageAdded(packageName, uid); return packageInfo; } @@ -678,7 +674,7 @@ public class PermissionMonitorTest { when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2); when(mPackageManager.getPackagesForUid(MOCK_UID1)) .thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2}); - mObserver.onPackageAdded(MOCK_PACKAGE2, MOCK_UID1); + mPermissionMonitor.onPackageAdded(MOCK_PACKAGE2, MOCK_UID1); mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); } @@ -692,7 +688,7 @@ public class PermissionMonitorTest { | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{}); - mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); + mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1}); } @@ -705,7 +701,7 @@ public class PermissionMonitorTest { | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1}); when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{}); - mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); + mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1}); addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET}); @@ -719,10 +715,7 @@ public class PermissionMonitorTest { addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {}); mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID1}); - // When updating a package, the broadcast receiver gets two broadcasts (a remove and then an - // add), but the observer sees only one callback (an update). - setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET}); - mObserver.onPackageChanged(MOCK_PACKAGE1, MOCK_UID1); + addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET}); mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1}); } @@ -740,7 +733,7 @@ public class PermissionMonitorTest { when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{ MOCK_PACKAGE2}); - mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); + mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1}); } diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index a1bb0d586916..1307a849f1eb 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -41,6 +41,7 @@ import static android.net.NetworkStats.TAG_ALL; 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.NETWORK_TYPE_ALL; import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.NetworkTemplate.buildTemplateMobileWithRatType; import static android.net.NetworkTemplate.buildTemplateWifiWildcard; @@ -62,6 +63,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -71,6 +73,7 @@ import android.app.AlarmManager; import android.app.usage.NetworkStatsManager; import android.content.Context; import android.content.Intent; +import android.database.ContentObserver; import android.net.DataUsageRequest; import android.net.INetworkManagementEventObserver; import android.net.INetworkStatsSession; @@ -94,6 +97,7 @@ import android.os.Message; import android.os.Messenger; import android.os.PowerManager; import android.os.SimpleClock; +import android.provider.Settings; import android.telephony.TelephonyManager; import androidx.test.InstrumentationRegistry; @@ -173,6 +177,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { private NetworkStatsService mService; private INetworkStatsSession mSession; private INetworkManagementEventObserver mNetworkObserver; + private ContentObserver mContentObserver; + private Handler mHandler; private final Clock mClock = new SimpleClock(ZoneOffset.UTC) { @Override @@ -212,6 +218,12 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { mService.systemReady(); // Verify that system ready fetches realtime stats verify(mStatsFactory).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL); + // Wait for posting onChange() event to handler thread and verify that when system ready, + // start monitoring data usage per RAT type because the settings value is mock as false + // by default in expectSettings(). + waitForIdle(); + verify(mNetworkStatsSubscriptionsMonitor).start(); + reset(mNetworkStatsSubscriptionsMonitor); mSession = mService.openSession(); assertNotNull("openSession() failed", mSession); @@ -233,11 +245,19 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { @Override public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor( - @NonNull Context context, @NonNull Executor executor, + @NonNull Context context, @NonNull Looper looper, @NonNull Executor executor, @NonNull NetworkStatsService service) { return mNetworkStatsSubscriptionsMonitor; } + + @Override + public ContentObserver makeContentObserver(Handler handler, + NetworkStatsSettings settings, NetworkStatsSubscriptionsMonitor monitor) { + mHandler = handler; + return mContentObserver = super.makeContentObserver(handler, settings, monitor); + } + }; } @@ -1191,6 +1211,99 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { provider.expectOnSetAlert(MB_IN_BYTES); } + private void setCombineSubtypeEnabled(boolean enable) { + when(mSettings.getCombineSubtypeEnabled()).thenReturn(enable); + mHandler.post(() -> mContentObserver.onChange(false, Settings.Global + .getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED))); + waitForIdle(); + if (enable) { + verify(mNetworkStatsSubscriptionsMonitor).stop(); + } else { + verify(mNetworkStatsSubscriptionsMonitor).start(); + } + } + + @Test + public void testDynamicWatchForNetworkRatTypeChanges() throws Exception { + // Build 3G template, type unknown template to get stats while network type is unknown + // and type all template to get the sum of all network type stats. + final NetworkTemplate template3g = + buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS); + final NetworkTemplate templateUnknown = + buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN); + final NetworkTemplate templateAll = + buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL); + final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)}; + + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + + // 3G network comes online. + 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(); + + // Since CombineSubtypeEnabled is false by default in unit test, the generated traffic + // will be split by RAT type. Verify 3G templates gets stats, while template with unknown + // RAT type gets nothing, and template with NETWORK_TYPE_ALL gets all stats. + assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); + assertUidTotal(templateUnknown, UID_RED, 0L, 0L, 0L, 0L, 0); + assertUidTotal(templateAll, UID_RED, 12L, 18L, 14L, 1L, 0); + + // Stop monitoring data usage per RAT type changes NetworkStatsService records data + // to {@link TelephonyManager#NETWORK_TYPE_UNKNOWN}. + setCombineSubtypeEnabled(true); + + // Call handleOnCollapsedRatTypeChanged manually to simulate the callback fired + // when stopping monitor, this is needed by NetworkStatsService to trigger updateIfaces. + mService.handleOnCollapsedRatTypeChanged(); + HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT); + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + // Append more traffic on existing snapshot. + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 12L + 4L, 18L + 4L, 14L + 3L, 1L + 1L, 0L)) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, + 35L, 29L, 7L, 11L, 1L))); + forcePollAndWaitForIdle(); + + // Verify 3G counters do not increase, while template with unknown RAT type gets new + // traffic and template with NETWORK_TYPE_ALL gets all stats. + assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0); + assertUidTotal(templateUnknown, UID_RED, 4L + 35L, 4L + 29L, 3L + 7L, 1L + 11L, 1); + assertUidTotal(templateAll, UID_RED, 16L + 35L, 22L + 29L, 17L + 7L, 2L + 11L, 1); + + // Start monitoring data usage per RAT type changes and NetworkStatsService records data + // by a granular subtype representative of the actual subtype + setCombineSubtypeEnabled(false); + + mService.handleOnCollapsedRatTypeChanged(); + HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT); + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + // Append more traffic on existing snapshot. + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 22L, 26L, 19L, 5L, 0L)) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, + 35L, 29L, 7L, 11L, 1L))); + forcePollAndWaitForIdle(); + + // Verify traffic is split by RAT type, no increase on template with unknown RAT type + // and template with NETWORK_TYPE_ALL gets all stats. + assertUidTotal(template3g, UID_RED, 6L + 12L , 4L + 18L, 2L + 14L, 3L + 1L, 0); + assertUidTotal(templateUnknown, UID_RED, 4L + 35L, 4L + 29L, 3L + 7L, 1L + 11L, 1); + assertUidTotal(templateAll, UID_RED, 22L + 35L, 26L + 29L, 19L + 7L, 5L + 11L, 1); + } + private static File getBaseDir(File statsDir) { File baseDir = new File(statsDir, "netstats"); baseDir.mkdirs(); @@ -1403,6 +1516,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { private void forcePollAndWaitForIdle() { mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); + waitForIdle(); + } + + private void waitForIdle() { HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT); } diff --git a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java index c91dfecf041b..6dc4fced19a2 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java @@ -18,6 +18,7 @@ package com.android.server.net; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.eq; @@ -31,7 +32,7 @@ import static org.mockito.Mockito.when; import android.annotation.NonNull; import android.content.Context; import android.net.NetworkTemplate; -import android.os.Looper; +import android.os.test.TestLooper; import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; @@ -39,7 +40,6 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import com.android.internal.util.CollectionUtils; -import com.android.server.net.NetworkStatsSubscriptionsMonitor.Delegate; import com.android.server.net.NetworkStatsSubscriptionsMonitor.RatTypeListener; import org.junit.Before; @@ -66,20 +66,17 @@ public final class NetworkStatsSubscriptionsMonitorTest { @Mock private Context mContext; @Mock private SubscriptionManager mSubscriptionManager; @Mock private TelephonyManager mTelephonyManager; - @Mock private Delegate mDelegate; + @Mock private NetworkStatsSubscriptionsMonitor.Delegate mDelegate; private final List<Integer> mTestSubList = new ArrayList<>(); private final Executor mExecutor = Executors.newSingleThreadExecutor(); private NetworkStatsSubscriptionsMonitor mMonitor; + private TestLooper mTestLooper = new TestLooper(); @Before public void setUp() { MockitoAnnotations.initMocks(this); - if (Looper.myLooper() == null) { - Looper.prepare(); - } - when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); when(mContext.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE))) @@ -87,7 +84,8 @@ public final class NetworkStatsSubscriptionsMonitorTest { when(mContext.getSystemService(eq(Context.TELEPHONY_SERVICE))) .thenReturn(mTelephonyManager); - mMonitor = new NetworkStatsSubscriptionsMonitor(mContext, mExecutor, mDelegate); + mMonitor = new NetworkStatsSubscriptionsMonitor(mContext, mTestLooper.getLooper(), + mExecutor, mDelegate); } @Test @@ -119,16 +117,18 @@ public final class NetworkStatsSubscriptionsMonitorTest { when(serviceState.getDataNetworkType()).thenReturn(type); final RatTypeListener match = CollectionUtils .find(listeners, it -> it.getSubId() == subId); - if (match != null) { - match.onServiceStateChanged(serviceState); + if (match == null) { + fail("Could not find listener with subId: " + subId); } + match.onServiceStateChanged(serviceState); } private void addTestSub(int subId, String subscriberId) { // add SubId to TestSubList. - if (!mTestSubList.contains(subId)) { - mTestSubList.add(subId); - } + if (mTestSubList.contains(subId)) fail("The subscriber list already contains this ID"); + + mTestSubList.add(subId); + final int[] subList = convertArrayListToIntArray(mTestSubList); when(mSubscriptionManager.getCompleteActiveSubscriptionIdList()).thenReturn(subList); when(mTelephonyManager.getSubscriberId(subId)).thenReturn(subscriberId); 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) { diff --git a/tools/aapt/tests/AaptConfig_test.cpp b/tools/aapt/tests/AaptConfig_test.cpp index 4f22fa581a88..b7c6bd25a565 100644 --- a/tools/aapt/tests/AaptConfig_test.cpp +++ b/tools/aapt/tests/AaptConfig_test.cpp @@ -20,7 +20,6 @@ #include "AaptConfig.h" #include "ConfigDescription.h" #include "SdkConstants.h" -#include "TestHelper.h" using android::String8; @@ -127,4 +126,4 @@ TEST(AaptConfigTest, HdrQualifier) { config.colorMode & android::ResTable_config::MASK_HDR); EXPECT_EQ(SDK_O, config.sdkVersion); EXPECT_EQ(String8("lowdr-v26"), config.toString()); -}
\ No newline at end of file +} diff --git a/tools/aapt/tests/AaptGroupEntry_test.cpp b/tools/aapt/tests/AaptGroupEntry_test.cpp index 7348a08a022f..bf5ca59a81c8 100644 --- a/tools/aapt/tests/AaptGroupEntry_test.cpp +++ b/tools/aapt/tests/AaptGroupEntry_test.cpp @@ -19,7 +19,6 @@ #include "AaptAssets.h" #include "ResourceFilter.h" -#include "TestHelper.h" using android::String8; diff --git a/tools/aapt/tests/ResourceTable_test.cpp b/tools/aapt/tests/ResourceTable_test.cpp index f2c696b2f87e..0d550df16767 100644 --- a/tools/aapt/tests/ResourceTable_test.cpp +++ b/tools/aapt/tests/ResourceTable_test.cpp @@ -19,7 +19,6 @@ #include "ConfigDescription.h" #include "ResourceTable.h" -#include "TestHelper.h" using android::String16; diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index c1d05e47bc19..ade0dc4d9c42 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -47,6 +47,7 @@ cc_defaults { cflags: ["-D_DARWIN_UNLIMITED_STREAMS"], }, }, + header_libs: ["jni_headers"], static_libs: [ "libandroidfw", "libutils", diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 234cbc4b37e0..931a14b1f650 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -449,6 +449,7 @@ bool ResourceParser::ParseResources(xml::XmlPullParser* parser) { ParsedResource parsed_resource; parsed_resource.config = config_; parsed_resource.source = source_.WithLine(parser->line_number()); + // NOLINTNEXTLINE(bugprone-use-after-move) move+reset comment parsed_resource.comment = std::move(comment); if (options_.visibility) { parsed_resource.visibility_level = options_.visibility.value(); @@ -979,6 +980,7 @@ bool ResourceParser::ParsePublicGroup(xml::XmlPullParser* parser, ParsedResource child_resource.name.type = *parsed_type; child_resource.name.entry = maybe_name.value().to_string(); child_resource.id = next_id; + // NOLINTNEXTLINE(bugprone-use-after-move) move+reset comment child_resource.comment = std::move(comment); child_resource.source = item_source; child_resource.visibility_level = Visibility::Level::kPublic; @@ -1698,6 +1700,7 @@ bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser, ParsedResource child_resource; child_resource.name = child_ref.name.value(); child_resource.source = item_source; + // NOLINTNEXTLINE(bugprone-use-after-move) move+reset comment child_resource.comment = std::move(comment); if (options_.visibility) { child_resource.visibility_level = options_.visibility.value(); diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp index f9faed84f5f0..e8873bf2d81b 100644 --- a/tools/aapt2/SdkConstants.cpp +++ b/tools/aapt2/SdkConstants.cpp @@ -27,7 +27,7 @@ namespace aapt { static ApiVersion sDevelopmentSdkLevel = 10000; static const auto sDevelopmentSdkCodeNames = std::unordered_set<StringPiece>({ - "Q", "R" + "Q", "R", "S" }); static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = { diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index 3a3fb2826b74..72cb41a1b172 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -1272,7 +1272,8 @@ class Linker { return false; } - ClassDefinition::WriteJavaFile(manifest_class.get(), package_utf8, true, &fout); + ClassDefinition::WriteJavaFile(manifest_class.get(), package_utf8, true, + false /* strip_api_annotations */, &fout); fout.Flush(); if (fout.HadError()) { diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp index cec59e75831d..482d91aeb491 100644 --- a/tools/aapt2/java/AnnotationProcessor.cpp +++ b/tools/aapt2/java/AnnotationProcessor.cpp @@ -123,7 +123,7 @@ void AnnotationProcessor::AppendNewLine() { } } -void AnnotationProcessor::Print(Printer* printer) const { +void AnnotationProcessor::Print(Printer* printer, bool strip_api_annotations) const { if (has_comments_) { std::string result = comment_.str(); for (const StringPiece& line : util::Tokenize(result, '\n')) { @@ -137,6 +137,9 @@ void AnnotationProcessor::Print(Printer* printer) const { printer->Println("@Deprecated"); } + if (strip_api_annotations) { + return; + } for (const AnnotationRule& rule : sAnnotationRules) { const auto& it = annotation_parameter_map_.find(rule.bit_mask); if (it != annotation_parameter_map_.end()) { diff --git a/tools/aapt2/java/AnnotationProcessor.h b/tools/aapt2/java/AnnotationProcessor.h index fdb58468d995..f217afb16f32 100644 --- a/tools/aapt2/java/AnnotationProcessor.h +++ b/tools/aapt2/java/AnnotationProcessor.h @@ -65,7 +65,7 @@ class AnnotationProcessor { void AppendNewLine(); // Writes the comments and annotations to the Printer. - void Print(text::Printer* printer) const; + void Print(text::Printer* printer, bool strip_api_annotations = false) const; private: std::stringstream comment_; diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp index 7d0a4e9af632..6bc8902a6dcf 100644 --- a/tools/aapt2/java/AnnotationProcessor_test.cpp +++ b/tools/aapt2/java/AnnotationProcessor_test.cpp @@ -91,6 +91,21 @@ TEST(AnnotationProcessorTest, EmitsTestApiAnnotationAndRemovesFromComment) { EXPECT_THAT(annotations, HasSubstr("This is a test API")); } +TEST(AnnotationProcessorTest, NotEmitSystemApiAnnotation) { + AnnotationProcessor processor; + processor.AppendComment("@SystemApi This is a system API"); + + std::string annotations; + StringOutputStream out(&annotations); + Printer printer(&out); + processor.Print(&printer, true /* strip_api_annotations */); + out.Flush(); + + EXPECT_THAT(annotations, Not(HasSubstr("@android.annotation.SystemApi"))); + EXPECT_THAT(annotations, Not(HasSubstr("@SystemApi"))); + EXPECT_THAT(annotations, HasSubstr("This is a system API")); +} + TEST(AnnotationProcessor, ExtractsFirstSentence) { EXPECT_THAT(AnnotationProcessor::ExtractFirstSentence("This is the only sentence"), Eq("This is the only sentence")); diff --git a/tools/aapt2/java/ClassDefinition.cpp b/tools/aapt2/java/ClassDefinition.cpp index f5f5b05491bb..3163497f0da6 100644 --- a/tools/aapt2/java/ClassDefinition.cpp +++ b/tools/aapt2/java/ClassDefinition.cpp @@ -23,15 +23,15 @@ using ::android::StringPiece; namespace aapt { -void ClassMember::Print(bool /*final*/, Printer* printer) const { - processor_.Print(printer); +void ClassMember::Print(bool /*final*/, Printer* printer, bool strip_api_annotations) const { + processor_.Print(printer, strip_api_annotations); } void MethodDefinition::AppendStatement(const StringPiece& statement) { statements_.push_back(statement.to_string()); } -void MethodDefinition::Print(bool final, Printer* printer) const { +void MethodDefinition::Print(bool final, Printer* printer, bool) const { printer->Print(signature_).Println(" {"); printer->Indent(); for (const auto& statement : statements_) { @@ -74,12 +74,12 @@ bool ClassDefinition::empty() const { return true; } -void ClassDefinition::Print(bool final, Printer* printer) const { +void ClassDefinition::Print(bool final, Printer* printer, bool strip_api_annotations) const { if (empty() && !create_if_empty_) { return; } - ClassMember::Print(final, printer); + ClassMember::Print(final, printer, strip_api_annotations); printer->Print("public "); if (qualifier_ == ClassQualifier::kStatic) { @@ -93,7 +93,7 @@ void ClassDefinition::Print(bool final, Printer* printer) const { // and takes precedence over a previous member with the same name. The overridden member is // set to nullptr. if (member != nullptr) { - member->Print(final, printer); + member->Print(final, printer, strip_api_annotations); printer->Println(); } } @@ -111,11 +111,11 @@ constexpr static const char* sWarningHeader = " */\n\n"; void ClassDefinition::WriteJavaFile(const ClassDefinition* def, const StringPiece& package, - bool final, io::OutputStream* out) { + bool final, bool strip_api_annotations, io::OutputStream* out) { Printer printer(out); printer.Print(sWarningHeader).Print("package ").Print(package).Println(";"); printer.Println(); - def->Print(final, &printer); + def->Print(final, &printer, strip_api_annotations); } } // namespace aapt diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h index fb11266f1761..1e4b6816075a 100644 --- a/tools/aapt2/java/ClassDefinition.h +++ b/tools/aapt2/java/ClassDefinition.h @@ -50,7 +50,7 @@ class ClassMember { // Writes the class member to the Printer. Subclasses should derive this method // to write their own data. Call this base method from the subclass to write out // this member's comments/annotations. - virtual void Print(bool final, text::Printer* printer) const; + virtual void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) const; private: AnnotationProcessor processor_; @@ -70,10 +70,11 @@ class PrimitiveMember : public ClassMember { return name_; } - void Print(bool final, text::Printer* printer) const override { + void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) + const override { using std::to_string; - ClassMember::Print(final, printer); + ClassMember::Print(final, printer, strip_api_annotations); printer->Print("public static "); if (final) { @@ -104,8 +105,9 @@ class PrimitiveMember<std::string> : public ClassMember { return name_; } - void Print(bool final, text::Printer* printer) const override { - ClassMember::Print(final, printer); + void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) + const override { + ClassMember::Print(final, printer, strip_api_annotations); printer->Print("public static "); if (final) { @@ -142,8 +144,9 @@ class PrimitiveArrayMember : public ClassMember { return name_; } - void Print(bool final, text::Printer* printer) const override { - ClassMember::Print(final, printer); + void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) + const override { + ClassMember::Print(final, printer, strip_api_annotations); printer->Print("public static final int[] ").Print(name_).Print("={"); printer->Indent(); @@ -195,7 +198,7 @@ class MethodDefinition : public ClassMember { return false; } - void Print(bool final, text::Printer* printer) const override; + void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) const override; private: DISALLOW_COPY_AND_ASSIGN(MethodDefinition); @@ -209,7 +212,7 @@ enum class ClassQualifier { kNone, kStatic }; class ClassDefinition : public ClassMember { public: static void WriteJavaFile(const ClassDefinition* def, const android::StringPiece& package, - bool final, io::OutputStream* out); + bool final, bool strip_api_annotations, io::OutputStream* out); ClassDefinition(const android::StringPiece& name, ClassQualifier qualifier, bool createIfEmpty) : name_(name.to_string()), qualifier_(qualifier), create_if_empty_(createIfEmpty) {} @@ -227,7 +230,7 @@ class ClassDefinition : public ClassMember { return name_; } - void Print(bool final, text::Printer* printer) const override; + void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) const override; private: DISALLOW_COPY_AND_ASSIGN(ClassDefinition); diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp index bb541fe2490b..dffad3b99c06 100644 --- a/tools/aapt2/java/JavaClassGenerator.cpp +++ b/tools/aapt2/java/JavaClassGenerator.cpp @@ -604,6 +604,8 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, rewrite_method->AppendStatement("final int packageIdBits = p << 24;"); } + const bool is_public = (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic); + for (const auto& package : table_->packages) { for (const auto& type : package->types) { if (type->type == ResourceType::kAttrPrivate) { @@ -612,8 +614,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, } // Stay consistent with AAPT and generate an empty type class if the R class is public. - const bool force_creation_if_empty = - (options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic); + const bool force_creation_if_empty = is_public; std::unique_ptr<ClassDefinition> class_def; if (out != nullptr) { @@ -637,8 +638,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, } } - if (out != nullptr && type->type == ResourceType::kStyleable && - options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic) { + if (out != nullptr && type->type == ResourceType::kStyleable && is_public) { // When generating a public R class, we don't want Styleable to be part // of the API. It is only emitted for documentation purposes. class_def->GetCommentBuilder()->AppendComment("@doconly"); @@ -657,7 +657,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, if (out != nullptr) { AppendJavaDocAnnotations(options_.javadoc_annotations, r_class.GetCommentBuilder()); - ClassDefinition::WriteJavaFile(&r_class, out_package_name, options_.use_final, out); + ClassDefinition::WriteJavaFile(&r_class, out_package_name, options_.use_final, !is_public, out); } return true; } diff --git a/tools/aapt2/java/ManifestClassGenerator_test.cpp b/tools/aapt2/java/ManifestClassGenerator_test.cpp index ab7f9a11d971..3858fc7f765e 100644 --- a/tools/aapt2/java/ManifestClassGenerator_test.cpp +++ b/tools/aapt2/java/ManifestClassGenerator_test.cpp @@ -26,6 +26,7 @@ using ::testing::Not; namespace aapt { static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xml::XmlResource* res, + bool strip_api_annotations, std::string* out_str); TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) { @@ -39,7 +40,8 @@ TEST(ManifestClassGeneratorTest, NameIsProperlyGeneratedFromSymbol) { </manifest>)"); std::string actual; - ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual)); + ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), + false /* strip_api_annotations */, &actual)); ASSERT_THAT(actual, HasSubstr("public static final class permission {")); ASSERT_THAT(actual, HasSubstr("public static final class permission_group {")); @@ -91,7 +93,8 @@ TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) { </manifest>)"); std::string actual; - ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual)); + ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), + false /* strip_api_annotations */, &actual)); const char* expected_access_internet = R"( /** * Required to access the internet. @@ -123,6 +126,55 @@ TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresent) { EXPECT_THAT(actual, HasSubstr(expected_test)); } +TEST(ManifestClassGeneratorTest, CommentsAndAnnotationsArePresentButNoApiAnnotations) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> manifest = test::BuildXmlDom(R"( + <manifest xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- Required to access the internet. + Added in API 1. --> + <permission android:name="android.permission.ACCESS_INTERNET" /> + <!-- @deprecated This permission is for playing outside. --> + <permission android:name="android.permission.PLAY_OUTSIDE" /> + <!-- This is a private permission for system only! + @hide + @SystemApi --> + <permission android:name="android.permission.SECRET" /> + <!-- @TestApi This is a test only permission. --> + <permission android:name="android.permission.TEST_ONLY" /> + </manifest>)"); + + std::string actual; + ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), + true /* strip_api_annotations */, &actual)); + + const char* expected_access_internet = R"( /** + * Required to access the internet. + * Added in API 1. + */ + public static final String ACCESS_INTERNET="android.permission.ACCESS_INTERNET";)"; + EXPECT_THAT(actual, HasSubstr(expected_access_internet)); + + const char* expected_play_outside = R"( /** + * @deprecated This permission is for playing outside. + */ + @Deprecated + public static final String PLAY_OUTSIDE="android.permission.PLAY_OUTSIDE";)"; + EXPECT_THAT(actual, HasSubstr(expected_play_outside)); + + const char* expected_secret = R"( /** + * This is a private permission for system only! + * @hide + */ + public static final String SECRET="android.permission.SECRET";)"; + EXPECT_THAT(actual, HasSubstr(expected_secret)); + + const char* expected_test = R"( /** + * This is a test only permission. + */ + public static final String TEST_ONLY="android.permission.TEST_ONLY";)"; + EXPECT_THAT(actual, HasSubstr(expected_test)); +} + // This is bad but part of public API behaviour so we need to preserve it. TEST(ManifestClassGeneratorTest, LastSeenPermissionWithSameLeafNameTakesPrecedence) { std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); @@ -135,7 +187,8 @@ TEST(ManifestClassGeneratorTest, LastSeenPermissionWithSameLeafNameTakesPreceden </manifest>)"); std::string actual; - ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual)); + ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), + false /* strip_api_annotations */, &actual)); EXPECT_THAT(actual, HasSubstr("ACCESS_INTERNET=\"com.android.aapt.test.ACCESS_INTERNET\";")); EXPECT_THAT(actual, Not(HasSubstr("ACCESS_INTERNET=\"android.permission.ACCESS_INTERNET\";"))); EXPECT_THAT(actual, Not(HasSubstr("ACCESS_INTERNET=\"com.android.sample.ACCESS_INTERNET\";"))); @@ -149,11 +202,13 @@ TEST(ManifestClassGeneratorTest, NormalizePermissionNames) { </manifest>)"); std::string actual; - ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), &actual)); + ASSERT_TRUE(GetManifestClassText(context.get(), manifest.get(), + false /* strip_api_annotations */, &actual)); EXPECT_THAT(actual, HasSubstr("access_internet=\"android.permission.access-internet\";")); } static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xml::XmlResource* res, + bool strip_api_annotations, std::string* out_str) { std::unique_ptr<ClassDefinition> manifest_class = GenerateManifestClass(context->GetDiagnostics(), res); @@ -162,7 +217,7 @@ static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xm } StringOutputStream out(out_str); - manifest_class->WriteJavaFile(manifest_class.get(), "android", true, &out); + manifest_class->WriteJavaFile(manifest_class.get(), "android", true, strip_api_annotations, &out); out.Flush(); return ::testing::AssertionSuccess(); } diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp index 0db1807c75d9..d9a4caa34e0d 100644 --- a/tools/aapt2/java/ProguardRules.cpp +++ b/tools/aapt2/java/ProguardRules.cpp @@ -115,15 +115,10 @@ class LayoutVisitor : public BaseVisitor { void Visit(xml::Element* node) override { bool is_view = false; - bool is_fragment = false; if (node->namespace_uri.empty()) { if (node->name == "view") { is_view = true; - } else if (node->name == "fragment") { - is_fragment = true; } - } else if (node->namespace_uri == xml::kSchemaAndroid) { - is_fragment = node->name == "fragment"; } for (const auto& attr : node->attributes) { @@ -132,12 +127,12 @@ class LayoutVisitor : public BaseVisitor { if (is_view) { AddClass(node->line_number, attr.value, "android.content.Context, android.util.AttributeSet"); - } else if (is_fragment) { + } else { AddClass(node->line_number, attr.value, ""); } } } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "name") { - if (is_fragment && util::IsJavaClassName(attr.value)) { + if (util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value, ""); } } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") { diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp index b6e76021ccc1..c7ae0b6a75cc 100644 --- a/tools/aapt2/java/ProguardRules_test.cpp +++ b/tools/aapt2/java/ProguardRules_test.cpp @@ -131,6 +131,61 @@ TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }")); } +TEST(ProguardRulesTest, FragmentContainerViewNameRuleIsEmitted) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( + <androidx.fragment.app.FragmentContainerView + xmlns:android="http://schemas.android.com/apk/res/android" + android:name="com.foo.Bar"/>)"); + layout->file.name = test::ParseNameOrDie("layout/foo"); + + proguard::KeepSet set; + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); + + std::string actual = GetKeepSetString(set, /** minimal_rules */ false); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); + + actual = GetKeepSetString(set, /** minimal_rules */ true); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }")); +} + +TEST(ProguardRulesTest, FragmentContainerViewClassRuleIsEmitted) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> layout = + test::BuildXmlDom(R"(<androidx.fragment.app.FragmentContainerView class="com.foo.Bar"/>)"); + layout->file.name = test::ParseNameOrDie("layout/foo"); + + proguard::KeepSet set; + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); + + std::string actual = GetKeepSetString(set, /** minimal_rules */ false); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); + + actual = GetKeepSetString(set, /** minimal_rules */ true); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }")); +} + +TEST(ProguardRulesTest, FragmentContainerViewNameAndClassRulesAreEmitted) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( + <androidx.fragment.app.FragmentContainerView + xmlns:android="http://schemas.android.com/apk/res/android" + android:name="com.foo.Baz" + class="com.foo.Bar"/>)"); + layout->file.name = test::ParseNameOrDie("layout/foo"); + + proguard::KeepSet set; + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); + + std::string actual = GetKeepSetString(set, /** minimal_rules */ false); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }")); + + actual = GetKeepSetString(set, /** minimal_rules */ true); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }")); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }")); +} + TEST(ProguardRulesTest, NavigationFragmentNameAndClassRulesAreEmitted) { std::unique_ptr<IAaptContext> context = test::ContextBuilder() .SetCompilationPackage("com.base").Build(); diff --git a/tools/aapt2/util/BigBuffer_test.cpp b/tools/aapt2/util/BigBuffer_test.cpp index a7776e33ae74..64dcc1dad9a2 100644 --- a/tools/aapt2/util/BigBuffer_test.cpp +++ b/tools/aapt2/util/BigBuffer_test.cpp @@ -62,7 +62,7 @@ TEST(BigBufferTest, AppendAndMoveBlock) { *b1 = 44; buffer.AppendBuffer(std::move(buffer2)); - EXPECT_EQ(0u, buffer2.size()); + EXPECT_EQ(0u, buffer2.size()); // NOLINT EXPECT_EQ(buffer2.begin(), buffer2.end()); } diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp index 9a725fad8727..005eeb936612 100644 --- a/tools/aapt2/xml/XmlDom.cpp +++ b/tools/aapt2/xml/XmlDom.cpp @@ -305,6 +305,8 @@ std::unique_ptr<XmlResource> Inflate(const void* data, size_t len, std::string* if (pending_element == nullptr) { pending_element = util::make_unique<Element>(); } + // pending_element is not nullptr + // NOLINTNEXTLINE(bugprone-use-after-move) pending_element->namespace_decls.push_back(std::move(decl)); break; } diff --git a/tools/bit/adb.cpp b/tools/bit/adb.cpp index fa7d3d4031d4..f521a63255e1 100644 --- a/tools/bit/adb.cpp +++ b/tools/bit/adb.cpp @@ -200,7 +200,7 @@ skip_bytes(int fd, ssize_t size, char* scratch, int scratchSize) static int skip_unknown_field(int fd, uint64_t tag, char* scratch, int scratchSize) { - bool done; + bool done = false; int err; uint64_t size; switch (tag & 0x7) { diff --git a/tools/dump-coverage/Android.bp b/tools/dump-coverage/Android.bp index 4519ce3636bf..94356ebac035 100644 --- a/tools/dump-coverage/Android.bp +++ b/tools/dump-coverage/Android.bp @@ -19,6 +19,7 @@ cc_library { name: "libdumpcoverage", srcs: ["dump_coverage.cc"], header_libs: [ + "jni_headers", "libopenjdkjvmti_headers", ], diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py index 6683e2abb0da..a4a315b7e371 100755 --- a/tools/fonts/fontchain_linter.py +++ b/tools/fonts/fontchain_linter.py @@ -286,7 +286,7 @@ def parse_fonts_xml(fonts_xml_path): if not fallback_for: if not name or name == 'sans-serif': - for _, fallback in _fallback_chains.iteritems(): + for _, fallback in _fallback_chains.items(): fallback.append(record) else: _fallback_chains[name].append(record) @@ -327,7 +327,7 @@ def check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji): assert sequence in all_emoji, ( 'Emoji font should not support %s.' % printable(sequence)) - for first, second in sorted(equivalent_emoji.items()): + for first, second in equivalent_emoji.items(): assert coverage[first] == coverage[second], ( '%s and %s should map to the same glyph.' % ( printable(first), @@ -352,7 +352,7 @@ def check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji): def check_emoji_defaults(default_emoji): missing_text_chars = _emoji_properties['Emoji'] - default_emoji - for name, fallback_chain in _fallback_chains.iteritems(): + for name, fallback_chain in _fallback_chains.items(): emoji_font_seen = False for record in fallback_chain: if 'Zsye' in record.scripts: @@ -369,7 +369,7 @@ def check_emoji_defaults(default_emoji): continue # Check default emoji-style characters - assert_font_supports_none_of_chars(record.font, sorted(default_emoji), name) + assert_font_supports_none_of_chars(record.font, default_emoji, name) # Mark default text-style characters appearing in fonts above the emoji # font as seen @@ -412,7 +412,7 @@ def parse_unicode_datafile(file_path, reverse=False): char_start, char_end = chars.split('..') char_start = int(char_start, 16) char_end = int(char_end, 16) - additions = xrange(char_start, char_end+1) + additions = range(char_start, char_end+1) else: # singe character additions = [int(chars, 16)] if reverse: @@ -478,7 +478,7 @@ def parse_ucd(ucd_path): # Unicode 12.0 adds Basic_Emoji in emoji-sequences.txt. We ignore them here since we are already # checking the emoji presentations with emoji-variation-sequences.txt. # Please refer to http://unicode.org/reports/tr51/#def_basic_emoji_set . - _emoji_sequences = {k: v for k, v in _emoji_sequences.iteritems() if not v == 'Basic_Emoji' } + _emoji_sequences = {k: v for k, v in _emoji_sequences.items() if not v == 'Basic_Emoji' } def remove_emoji_variation_exclude(source, items): @@ -551,7 +551,7 @@ def reverse_emoji(seq): rev = list(reversed(seq)) # if there are fitzpatrick modifiers in the sequence, keep them after # the emoji they modify - for i in xrange(1, len(rev)): + for i in range(1, len(rev)): if is_fitzpatrick_modifier(rev[i-1]): rev[i], rev[i-1] = rev[i-1], rev[i] return tuple(rev) @@ -620,7 +620,7 @@ def compute_expected_emoji(): def check_compact_only_fallback(): - for name, fallback_chain in _fallback_chains.iteritems(): + for name, fallback_chain in _fallback_chains.items(): for record in fallback_chain: if record.variant == 'compact': same_script_elegants = [x for x in fallback_chain @@ -650,7 +650,7 @@ def check_vertical_metrics(): def check_cjk_punctuation(): cjk_scripts = {'Hans', 'Hant', 'Jpan', 'Kore'} cjk_punctuation = range(0x3000, 0x301F + 1) - for name, fallback_chain in _fallback_chains.iteritems(): + for name, fallback_chain in _fallback_chains.items(): for record in fallback_chain: if record.scripts.intersection(cjk_scripts): # CJK font seen. Stop checking the rest of the fonts. diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py index 0b2077d9bba0..de6b4785ec37 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists.py +++ b/tools/hiddenapi/generate_hiddenapi_lists.py @@ -18,10 +18,10 @@ Generate API lists for non-SDK API enforcement. """ import argparse from collections import defaultdict +import functools import os -import sys import re -import functools +import sys # Names of flags recognized by the `hiddenapi` tool. FLAG_WHITELIST = "whitelist" @@ -30,6 +30,7 @@ FLAG_BLACKLIST = "blacklist" FLAG_GREYLIST_MAX_O = "greylist-max-o" FLAG_GREYLIST_MAX_P = "greylist-max-p" FLAG_GREYLIST_MAX_Q = "greylist-max-q" +FLAG_GREYLIST_MAX_R = "greylist-max-r" FLAG_CORE_PLATFORM_API = "core-platform-api" FLAG_PUBLIC_API = "public-api" FLAG_SYSTEM_API = "system-api" @@ -43,13 +44,14 @@ FLAGS_API_LIST = [ FLAG_GREYLIST_MAX_O, FLAG_GREYLIST_MAX_P, FLAG_GREYLIST_MAX_Q, + FLAG_GREYLIST_MAX_R, ] ALL_FLAGS = FLAGS_API_LIST + [ FLAG_CORE_PLATFORM_API, FLAG_PUBLIC_API, FLAG_SYSTEM_API, FLAG_TEST_API, - ] +] FLAGS_API_LIST_SET = set(FLAGS_API_LIST) ALL_FLAGS_SET = set(ALL_FLAGS) diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp index 786223a430ae..dd266ffe0f16 100644 --- a/tools/incident_section_gen/main.cpp +++ b/tools/incident_section_gen/main.cpp @@ -368,10 +368,13 @@ static bool generatePrivacyFlags(const Descriptor* descriptor, const Destination // Don't generate a variable twice if (!hasDefaultFlags[i]) variableNames[fieldName] = false; } + // hasDefaultFlags[i] has been initialized in the above for-loop, + // but clang-tidy analyzer still report uninitized values. + // So we use NOLINT to suppress those false positives. bool allDefaults = true; for (size_t i=0; i<fieldsInOrder.size(); i++) { - allDefaults &= hasDefaultFlags[i]; + allDefaults &= hasDefaultFlags[i]; // NOLINT(clang-analyzer-core.uninitialized.Assign) } parents->erase(messageName); // erase the message type name when exit the message. @@ -384,7 +387,7 @@ static bool generatePrivacyFlags(const Descriptor* descriptor, const Destination printf("Privacy* %s[] = {\n", messageName.c_str()); for (size_t i=0; i<fieldsInOrder.size(); i++) { const FieldDescriptor* field = fieldsInOrder[i]; - if (hasDefaultFlags[i]) continue; + if (hasDefaultFlags[i]) continue; // NOLINT(clang-analyzer-core.uninitialized.Branch) printf(" &%s,\n", getFieldName(field).c_str()); policyCount++; } diff --git a/wifi/Android.bp b/wifi/Android.bp index 941ff61b3ba5..02616aff2a3f 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -73,6 +73,7 @@ test_access_hidden_api_whitelist = [ "//external/robolectric-shadows:__subpackages__", "//frameworks/base/packages/SettingsLib/tests/integ", "//external/sl4a:__subpackages__", + "//packages/apps/Settings/tests/robotests", // TODO(b/161767237): remove ] // wifi-service needs pre-jarjared version of framework-wifi so it can reference copied utility |