diff options
269 files changed, 4304 insertions, 1559 deletions
diff --git a/Android.bp b/Android.bp index 3e92748c5aec..e22d4a6a250d 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"], @@ -533,6 +607,9 @@ java_library { static_libs: [ "exoplayer2-extractor", "android.hardware.wifi-V1.0-java-constants", + + // Additional dependencies needed to build the ike API classes. + "ike-internals", ], apex_available: ["//apex_available:platform"], visibility: [ @@ -1036,13 +1113,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, + }, }, } @@ -1216,6 +1293,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. " + @@ -1265,4 +1343,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..d8532489a786 100644 --- a/Android.mk +++ b/Android.mk @@ -60,7 +60,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..9f5b183913c0 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: { @@ -246,6 +247,10 @@ droidstubs { 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", @@ -305,12 +310,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", 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 c1715a002d6d..c54debe29855 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -76,6 +76,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. @@ -230,6 +234,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/api/current.txt b/api/current.txt index 952ccdad992c..61ecf26434bc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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); @@ -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 addServiceAnnouncementFile(@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 getMaximumServiceAnnouncementFileSize(); 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_FILE = 404; // 0x194 field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192 field public static final int ERROR_UNKNOWN_FILE_INFO = 403; // 0x193 } diff --git a/api/system-current.txt b/api/system-current.txt index f07ebaf19cb6..855a083e9c32 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 addServiceAnnouncementFile(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 ed4c9b13dacd..53e42ccd9bdd 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -3731,7 +3731,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 { @@ -4781,6 +4781,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 addServiceAnnouncementFile(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/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/Android.bp b/cmds/idmap2/Android.bp index ef5c4cec9166..d787d55d8bd7 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -25,7 +25,7 @@ cc_defaults { ], tidy_flags: [ "-system-headers", - "-warnings-as-errors=*", + "-warnings-as-errors=*,-bugprone*", ], } diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index a93184ff4787..afe754f2f35b 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -150,7 +150,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 61e5eb07130c..7fc999af6f78 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 47bab2947aaf..82734c23acaf 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -1090,36 +1090,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); @@ -1130,7 +1120,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..927e965d5fc7 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -11952,6 +11952,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 353f786da153..cf242d37d859 100644 --- a/config/preloaded-classes-blacklist +++ b/config/preloaded-classes-blacklist @@ -3,4 +3,4 @@ android.net.ConnectivityThread$Singleton android.os.FileObserver android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask android.widget.Magnifier -sun.nio.fs.UnixChannelFactory + 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/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index ae8a2cbf5120..b3137d84c3f1 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -36,7 +36,6 @@ import android.util.proto.ProtoOutputStream; import libcore.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/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/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/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/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/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 36ffe50ef82d..5277ff6093c9 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,14 +2249,30 @@ 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); } /** {@hide} */ - public static final void enforceTetherChangePermission(Context context, String callingPkg) { + public static final void enforceTetherChangePermission(Context context, String callingPkg, + String callingAttributionTag) { Preconditions.checkNotNull(context, "Context cannot be null"); Preconditions.checkNotNull(callingPkg, "callingPkg cannot be null"); @@ -2261,12 +2286,26 @@ public class ConnectivityManager { int uid = Binder.getCallingUid(); // If callingPkg's uid is not same as Binder.getCallingUid(), // AppOpsService throws SecurityException. - Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPkg, - true /* throwException */); + checkAndNoteWriteSettingsOperation(context, uid, callingPkg, + callingAttributionTag, true /* 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); + } + + /** * @deprecated - use getSystemService. This is a kludge to support static access in certain * situations where a Context pointer is unavailable. * @hide @@ -3706,7 +3745,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); @@ -3982,7 +4022,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/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/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 ef2a8a122e95..36510e51f41f 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.product.hardware.sku"); + + /** * Whether this build was for an emulator device. * @hide */ 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/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 1b19e1290121..5bf5a383e03a 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11583,17 +11583,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/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index e4fbf9f0e187..bda026fc844c 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -762,7 +762,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/text/format/Time.java b/core/java/android/text/format/Time.java index 49cebc141636..f1a8565efde1 100644 --- a/core/java/android/text/format/Time.java +++ b/core/java/android/text/format/Time.java @@ -21,7 +21,6 @@ import android.util.TimeFormatException; import libcore.timezone.ZoneInfoDb; import libcore.util.ZoneInfo; -import java.io.IOException; import java.util.Locale; import java.util.TimeZone; @@ -1117,19 +1116,14 @@ public class Time { } 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); + 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; } public void switchTimeZone(String timezone) { 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..8fd303b8a64c 100644 --- a/core/java/android/timezone/CountryTimeZones.java +++ b/core/java/android/timezone/CountryTimeZones.java @@ -158,7 +158,7 @@ public final class CountryTimeZones { * supplied. */ public boolean matchesCountryCode(@NonNull String countryIso) { - return mDelegate.isForCountryCode(countryIso); + return mDelegate.matchesCountryCode(countryIso); } /** 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/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 6f73e8985a8a..ef8342dbfa1b 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -2438,7 +2438,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/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/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/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/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 505a05eb9c23..93dc6ae2be25 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -1079,6 +1079,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/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_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_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp index 151dbfce7af3..a88f8919ed08 100644 --- a/core/jni/android_os_HwParcel.cpp +++ b/core/jni/android_os_HwParcel.cpp @@ -292,19 +292,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 +304,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_Parcel.cpp b/core/jni/android_os_Parcel.cpp index e7a2fb428b50..a2b2b2e1870d 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -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..3cee8edcd8b0 100644 --- a/core/jni/android_os_SELinux.cpp +++ b/core/jni/android_os_SELinux.cpp @@ -15,6 +15,10 @@ */ #define LOG_TAG "SELinuxJNI" + +#include <errno.h> +#include <fcntl.h> + #include <utils/Log.h> #include <nativehelper/JNIHelp.h> @@ -22,7 +26,6 @@ #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..a812c35036f3 100644 --- a/core/jni/android_os_SharedMemory.cpp +++ b/core/jni/android_os_SharedMemory.cpp @@ -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_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..9886e38f6d9a 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> 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 fc2005a31696..97008f6186cf 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> @@ -344,6 +347,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, @@ -1598,6 +1603,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, @@ -1732,7 +1759,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)); @@ -2427,6 +2470,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); @@ -2471,6 +2522,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/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/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/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index ad3d20ee5f24..aa023b6e7777 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -685,6 +685,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 f30d482e06b2..5026e1196113 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3363,6 +3363,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/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index 70917e76f8b4..d5733e34a8ef 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -39,7 +39,7 @@ <!-- Albania: 5 digits, known short codes listed --> <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" /> - <!-- Argentia: 5 digits, known short codes listed --> + <!-- Argentina: 5 digits, known short codes listed --> <shortcode country="ar" pattern="\\d{5}" free="11711|28291" /> <!-- Armenia: 3-4 digits, emergency numbers 10[123] --> @@ -70,7 +70,7 @@ <shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" /> <!-- Canada: 5-6 digits --> - <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188|43030" standard="244444" /> + <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188|43030" standard="244444" free="455677" /> <!-- Switzerland: 3-5 digits: http://www.swisscom.ch/fxres/kmu/thirdpartybusiness_code_of_conduct_en.pdf --> <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111|30118" free="98765|30075|30047" /> 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/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/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/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/core/xsd/vts/Android.mk b/core/xsd/vts/Android.mk deleted file mode 100644 index a5754a494d94..000000000000 --- a/core/xsd/vts/Android.mk +++ /dev/null @@ -1,22 +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_MODULE := VtsValidatePermission -include test/vts/tools/build/Android.host_config.mk 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/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/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java index c52fd48459cb..d4cf53e874f1 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; @@ -50,6 +51,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 +497,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 +620,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)); 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/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/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/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/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/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/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..a05de4fac2a6 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -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); @@ -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 addServiceAnnouncementFile(@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 getMaximumServiceAnnouncementFileSize(); 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_FILE = 404; // 0x194 field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192 field public static final int ERROR_UNKNOWN_FILE_INFO = 403; // 0x193 } diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index 256bf33f9cc8..eff406631d8d 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 addServiceAnnouncementFile(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/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..34878035051d 100644 --- a/packages/CtsShim/Android.bp +++ b/packages/CtsShim/Android.bp @@ -43,6 +43,15 @@ android_app_import { }, }, presigned: true, + + apex_available: [ + "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 +80,13 @@ android_app_import { }, }, presigned: true, + + apex_available: [ + "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/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS index a28ba8584054..cb36c4c1004f 100644 --- a/packages/SettingsLib/OWNERS +++ b/packages/SettingsLib/OWNERS @@ -4,10 +4,8 @@ edgarwang@google.com emilychuang@google.com evanlaird@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..231809bfece4 100644 --- a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java +++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java @@ -242,7 +242,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/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 fa87b62bd73a..d01f4fceac2e 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -465,7 +465,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/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/res/drawable/ic_qs_nfc_enabled.xml b/packages/SystemUI/res/drawable/ic_qs_nfc.xml index becb18ad8ba2..2c080964b48e 100644 --- a/packages/SystemUI/res/drawable/ic_qs_nfc_enabled.xml +++ b/packages/SystemUI/res/drawable/ic_qs_nfc.xml @@ -14,8 +14,8 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="48dp" + android:height="48dp" android:viewportWidth="24" android:viewportHeight="24"> diff --git a/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml deleted file mode 100644 index 558f3d083f42..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M4 20h16V4H4v16z" /> - <path - android:fillColor="#4DFFFFFF" - android:pathData="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1 .9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 -18H4V4h16v16zM18 6h-5c-1.1 0-2 .9-2 2v2.28c-.6 .35 -1 .98-1 1.72 0 1.1 .9 2 2 -2s2-.9 2-2c0-.74-.4-1.38-1-1.72V8h3v8H8V8h2V6H6v12h12V6z" /> - <path - android:pathData="M0 0h24v24H0z" /> -</vector> diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml index 24374e80b211..df717f601763 100644 --- a/packages/SystemUI/res/layout/menu_ime.xml +++ b/packages/SystemUI/res/layout/menu_ime.xml @@ -17,13 +17,13 @@ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:id="@+id/menu_container" - android:layout_width="@dimen/navigation_key_width" + android:layout_width="@dimen/navigation_side_padding" android:layout_height="match_parent" android:importantForAccessibility="no" > <!-- Use nav button width & height=match_parent for parent FrameLayout and buttons because they are placed inside a view that has a size controlled by weight. Ensure weight is large enough to - support icon size. --> + support icon size. Use layout_width=navigation_side_padding like other navbar buttons. --> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/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/Tethering/Android.bp b/packages/Tethering/Android.bp index d07a70c1af9b..9eba6bd0dc5a 100644 --- a/packages/Tethering/Android.bp +++ b/packages/Tethering/Android.bp @@ -25,7 +25,7 @@ java_defaults { ], static_libs: [ "androidx.annotation_annotation", - "netd_aidl_interface-V3-java", + "netd_aidl_interface-unstable-java", "netlink-client", "networkstack-aidl-interfaces-java", "android.hardware.tetheroffload.config-V1.0-java", 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/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java index cc095a0bb4a7..05af5c9d0ef1 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java @@ -484,7 +484,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); } @@ -492,6 +492,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 @@ -509,7 +516,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); } @@ -536,7 +543,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); } @@ -735,7 +743,8 @@ public class TetheringManager { }); } }; - getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener)); + getConnector(c -> c.startTethering(request.getParcel(), callerPkg, + getAttributionTag(), listener)); } /** @@ -775,7 +784,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 @@ -861,7 +871,7 @@ public class TetheringManager { Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg); getConnector(c -> c.requestLatestTetheringEntitlementResult( - type, receiver, showEntitlementUi, callerPkg)); + type, receiver, showEntitlementUi, callerPkg, getAttributionTag())); } /** @@ -1312,7 +1322,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); } @@ -1335,14 +1345,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/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java index f08429bb0696..088b88cb3145 100644 --- a/packages/Tethering/src/android/net/ip/IpServer.java +++ b/packages/Tethering/src/android/net/ip/IpServer.java @@ -33,7 +33,6 @@ import android.net.LinkAddress; import android.net.LinkProperties; import android.net.MacAddress; import android.net.RouteInfo; -import android.net.TetherOffloadRuleParcel; import android.net.TetheredClient; import android.net.TetheringManager; import android.net.TetheringRequestParcel; @@ -65,6 +64,8 @@ import androidx.annotation.Nullable; import com.android.internal.util.MessageUtils; import com.android.internal.util.State; import com.android.internal.util.StateMachine; +import com.android.networkstack.tethering.BpfCoordinator; +import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule; import com.android.networkstack.tethering.PrivateAddressCoordinator; import java.io.IOException; @@ -225,6 +226,8 @@ public class IpServer extends StateMachine { private final SharedLog mLog; private final INetd mNetd; + @NonNull + private final BpfCoordinator mBpfCoordinator; private final Callback mCallback; private final InterfaceController mInterfaceCtrl; private final PrivateAddressCoordinator mPrivateAddressCoordinator; @@ -269,40 +272,6 @@ public class IpServer extends StateMachine { } } - static class Ipv6ForwardingRule { - public final int upstreamIfindex; - public final int downstreamIfindex; - public final Inet6Address address; - public final MacAddress srcMac; - public final MacAddress dstMac; - - Ipv6ForwardingRule(int upstreamIfindex, int downstreamIfIndex, Inet6Address address, - MacAddress srcMac, MacAddress dstMac) { - this.upstreamIfindex = upstreamIfindex; - this.downstreamIfindex = downstreamIfIndex; - this.address = address; - this.srcMac = srcMac; - this.dstMac = dstMac; - } - - public Ipv6ForwardingRule onNewUpstream(int newUpstreamIfindex) { - return new Ipv6ForwardingRule(newUpstreamIfindex, downstreamIfindex, address, srcMac, - dstMac); - } - - // Don't manipulate TetherOffloadRuleParcel directly because implementing onNewUpstream() - // would be error-prone due to generated stable AIDL classes not having a copy constructor. - public TetherOffloadRuleParcel toTetherOffloadRuleParcel() { - final TetherOffloadRuleParcel parcel = new TetherOffloadRuleParcel(); - parcel.inputInterfaceIndex = upstreamIfindex; - parcel.outputInterfaceIndex = downstreamIfindex; - parcel.destination = address.getAddress(); - parcel.prefixLength = 128; - parcel.srcL2Address = srcMac.toByteArray(); - parcel.dstL2Address = dstMac.toByteArray(); - return parcel; - } - } private final LinkedHashMap<Inet6Address, Ipv6ForwardingRule> mIpv6ForwardingRules = new LinkedHashMap<>(); @@ -314,11 +283,13 @@ public class IpServer extends StateMachine { // object. It helps to reduce the arguments of the constructor. public IpServer( String ifaceName, Looper looper, int interfaceType, SharedLog log, - INetd netd, Callback callback, boolean usingLegacyDhcp, boolean usingBpfOffload, + INetd netd, @NonNull BpfCoordinator coordinator, Callback callback, + boolean usingLegacyDhcp, boolean usingBpfOffload, PrivateAddressCoordinator addressCoordinator, Dependencies deps) { super(ifaceName, looper); mLog = log.forSubComponent(ifaceName); mNetd = netd; + mBpfCoordinator = coordinator; mCallback = callback; mInterfaceCtrl = new InterfaceController(ifaceName, mNetd, mLog); mIfaceName = ifaceName; @@ -754,6 +725,14 @@ public class IpServer extends StateMachine { } upstreamIfindex = mDeps.getIfindex(upstreamIface); + + // Add upstream index to name mapping for the tether stats usage in the coordinator. + // Although this mapping could be added by both class Tethering and IpServer, adding + // mapping from IpServer guarantees that the mapping is added before the adding + // forwarding rules. That is because there are different state machines in both + // classes. It is hard to guarantee the link property update order between multiple + // state machines. + mBpfCoordinator.addUpstreamNameToLookupTable(upstreamIfindex, upstreamIface); } // If v6only is null, we pass in null to setRaParams(), which handles diff --git a/packages/Tethering/src/android/net/util/TetheringUtils.java b/packages/Tethering/src/android/net/util/TetheringUtils.java index dd67dddae1cd..b17b4ba77cfb 100644 --- a/packages/Tethering/src/android/net/util/TetheringUtils.java +++ b/packages/Tethering/src/android/net/util/TetheringUtils.java @@ -15,19 +15,94 @@ */ package android.net.util; +import android.net.TetherStatsParcel; import android.net.TetheringRequestParcel; +import androidx.annotation.NonNull; + import java.io.FileDescriptor; import java.net.SocketException; import java.util.Objects; /** - * Native methods for tethering utilization. + * The classes and the methods for tethering utilization. * * {@hide} */ public class TetheringUtils { /** + * The object which records offload Tx/Rx forwarded bytes/packets. + * TODO: Replace the inner class ForwardedStats of class OffloadHardwareInterface with + * this class as well. + */ + public static class ForwardedStats { + public final long rxBytes; + public final long rxPackets; + public final long txBytes; + public final long txPackets; + + public ForwardedStats() { + rxBytes = 0; + rxPackets = 0; + txBytes = 0; + txPackets = 0; + } + + public ForwardedStats(long rxBytes, long txBytes) { + this.rxBytes = rxBytes; + this.rxPackets = 0; + this.txBytes = txBytes; + this.txPackets = 0; + } + + public ForwardedStats(long rxBytes, long rxPackets, long txBytes, long txPackets) { + this.rxBytes = rxBytes; + this.rxPackets = rxPackets; + this.txBytes = txBytes; + this.txPackets = txPackets; + } + + public ForwardedStats(@NonNull TetherStatsParcel tetherStats) { + rxBytes = tetherStats.rxBytes; + rxPackets = tetherStats.rxPackets; + txBytes = tetherStats.txBytes; + txPackets = tetherStats.txPackets; + } + + public ForwardedStats(@NonNull ForwardedStats other) { + rxBytes = other.rxBytes; + rxPackets = other.rxPackets; + txBytes = other.txBytes; + txPackets = other.txPackets; + } + + /** Add Tx/Rx bytes/packets and return the result as a new object. */ + @NonNull + public ForwardedStats add(@NonNull ForwardedStats other) { + return new ForwardedStats(rxBytes + other.rxBytes, rxPackets + other.rxPackets, + txBytes + other.txBytes, txPackets + other.txPackets); + } + + /** Subtract Tx/Rx bytes/packets and return the result as a new object. */ + @NonNull + public ForwardedStats subtract(@NonNull ForwardedStats other) { + // TODO: Perhaps throw an exception if any negative difference value just in case. + final long rxBytesDiff = Math.max(rxBytes - other.rxBytes, 0); + final long rxPacketsDiff = Math.max(rxPackets - other.rxPackets, 0); + final long txBytesDiff = Math.max(txBytes - other.txBytes, 0); + final long txPacketsDiff = Math.max(txPackets - other.txPackets, 0); + return new ForwardedStats(rxBytesDiff, rxPacketsDiff, txBytesDiff, txPacketsDiff); + } + + /** Returns the string representation of this object. */ + @NonNull + public String toString() { + return String.format("ForwardedStats(rxb: %d, rxp: %d, txb: %d, txp: %d)", rxBytes, + rxPackets, txBytes, txPackets); + } + } + + /** * Configures a socket for receiving ICMPv6 router solicitations and sending advertisements. * @param fd the socket's {@link FileDescriptor}. * @param ifIndex the interface index. diff --git a/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java new file mode 100644 index 000000000000..6b854f2ac941 --- /dev/null +++ b/packages/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java @@ -0,0 +1,329 @@ +/* + * 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.networkstack.tethering; + +import static android.net.NetworkStats.DEFAULT_NETWORK_NO; +import static android.net.NetworkStats.METERED_NO; +import static android.net.NetworkStats.ROAMING_NO; +import static android.net.NetworkStats.SET_DEFAULT; +import static android.net.NetworkStats.TAG_NONE; +import static android.net.NetworkStats.UID_ALL; +import static android.net.NetworkStats.UID_TETHERING; + +import android.app.usage.NetworkStatsManager; +import android.net.INetd; +import android.net.MacAddress; +import android.net.NetworkStats; +import android.net.NetworkStats.Entry; +import android.net.TetherOffloadRuleParcel; +import android.net.TetherStatsParcel; +import android.net.netstats.provider.NetworkStatsProvider; +import android.net.util.SharedLog; +import android.net.util.TetheringUtils.ForwardedStats; +import android.os.Handler; +import android.os.RemoteException; +import android.os.ServiceSpecificException; +import android.util.Log; +import android.util.SparseArray; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.internal.annotations.VisibleForTesting; + +import java.net.Inet6Address; + +/** + * This coordinator is responsible for providing BPF offload relevant functionality. + * - Get tethering stats. + * + * @hide + */ +public class BpfCoordinator { + private static final String TAG = BpfCoordinator.class.getSimpleName(); + @VisibleForTesting + static final int DEFAULT_PERFORM_POLL_INTERVAL_MS = 5000; // TODO: Make it customizable. + + @VisibleForTesting + enum StatsType { + STATS_PER_IFACE, + STATS_PER_UID, + } + + @NonNull + private final Handler mHandler; + @NonNull + private final INetd mNetd; + @NonNull + private final SharedLog mLog; + @NonNull + private final Dependencies mDeps; + @Nullable + private final BpfTetherStatsProvider mStatsProvider; + private boolean mStarted = false; + + // Maps upstream interface index to offloaded traffic statistics. + // Always contains the latest total bytes/packets, since each upstream was started, received + // from the BPF maps for each interface. + private SparseArray<ForwardedStats> mStats = new SparseArray<>(); + + // Maps upstream interface index to interface names. + // Store all interface name since boot. Used for lookup what interface name it is from the + // tether stats got from netd because netd reports interface index to present an interface. + // TODO: Remove the unused interface name. + private SparseArray<String> mInterfaceNames = new SparseArray<>(); + + // Runnable that used by scheduling next polling of stats. + private final Runnable mScheduledPollingTask = () -> { + updateForwardedStatsFromNetd(); + maybeSchedulePollingStats(); + }; + + @VisibleForTesting + static class Dependencies { + int getPerformPollInterval() { + // TODO: Consider make this configurable. + return DEFAULT_PERFORM_POLL_INTERVAL_MS; + } + } + + BpfCoordinator(@NonNull Handler handler, @NonNull INetd netd, + @NonNull NetworkStatsManager nsm, @NonNull SharedLog log, @NonNull Dependencies deps) { + mHandler = handler; + mNetd = netd; + mLog = log.forSubComponent(TAG); + BpfTetherStatsProvider provider = new BpfTetherStatsProvider(); + try { + nsm.registerNetworkStatsProvider(getClass().getSimpleName(), provider); + } catch (RuntimeException e) { + // TODO: Perhaps not allow to use BPF offload because the reregistration failure + // implied that no data limit could be applies on a metered upstream if any. + Log.wtf(TAG, "Cannot register offload stats provider: " + e); + provider = null; + } + mStatsProvider = provider; + mDeps = deps; + } + + /** + * Start BPF tethering offload stats polling when the first upstream is started. + * Note that this can be only called on handler thread. + * TODO: Perhaps check BPF support before starting. + * TODO: Start the stats polling only if there is any client on the downstream. + */ + public void start() { + if (mStarted) return; + + mStarted = true; + maybeSchedulePollingStats(); + + mLog.i("BPF tethering coordinator started"); + } + + /** + * Stop BPF tethering offload stats polling and cleanup upstream parameters. + * Note that this can be only called on handler thread. + */ + public void stop() { + if (!mStarted) return; + + // Stop scheduled polling tasks and poll the latest stats from BPF maps. + if (mHandler.hasCallbacks(mScheduledPollingTask)) { + mHandler.removeCallbacks(mScheduledPollingTask); + } + updateForwardedStatsFromNetd(); + + mStarted = false; + + mLog.i("BPF tethering coordinator stopped"); + } + + /** + * Add upstream name to lookup table. The lookup table is used for tether stats interface name + * lookup because the netd only reports interface index in BPF tether stats but the service + * expects the interface name in NetworkStats object. + * Note that this can be only called on handler thread. + */ + public void addUpstreamNameToLookupTable(int upstreamIfindex, String upstreamIface) { + if (upstreamIfindex == 0) return; + + // The same interface index to name mapping may be added by different IpServer objects or + // re-added by reconnection on the same upstream interface. Ignore the duplicate one. + final String iface = mInterfaceNames.get(upstreamIfindex); + if (iface == null) { + mInterfaceNames.put(upstreamIfindex, upstreamIface); + } else if (iface != upstreamIface) { + Log.wtf(TAG, "The upstream interface name " + upstreamIface + + " is different from the existing interface name " + + iface + " for index " + upstreamIfindex); + } + } + + /** IPv6 forwarding rule class. */ + public static class Ipv6ForwardingRule { + public final int upstreamIfindex; + public final int downstreamIfindex; + public final Inet6Address address; + public final MacAddress srcMac; + public final MacAddress dstMac; + + public Ipv6ForwardingRule(int upstreamIfindex, int downstreamIfIndex, Inet6Address address, + MacAddress srcMac, MacAddress dstMac) { + this.upstreamIfindex = upstreamIfindex; + this.downstreamIfindex = downstreamIfIndex; + this.address = address; + this.srcMac = srcMac; + this.dstMac = dstMac; + } + + /** Return a new rule object which updates with new upstream index. */ + public Ipv6ForwardingRule onNewUpstream(int newUpstreamIfindex) { + return new Ipv6ForwardingRule(newUpstreamIfindex, downstreamIfindex, address, srcMac, + dstMac); + } + + /** + * Don't manipulate TetherOffloadRuleParcel directly because implementing onNewUpstream() + * would be error-prone due to generated stable AIDL classes not having a copy constructor. + */ + public TetherOffloadRuleParcel toTetherOffloadRuleParcel() { + final TetherOffloadRuleParcel parcel = new TetherOffloadRuleParcel(); + parcel.inputInterfaceIndex = upstreamIfindex; + parcel.outputInterfaceIndex = downstreamIfindex; + parcel.destination = address.getAddress(); + parcel.prefixLength = 128; + parcel.srcL2Address = srcMac.toByteArray(); + parcel.dstL2Address = dstMac.toByteArray(); + return parcel; + } + } + + /** + * A BPF tethering stats provider to provide network statistics to the system. + * Note that this class's data may only be accessed on the handler thread. + */ + @VisibleForTesting + class BpfTetherStatsProvider extends NetworkStatsProvider { + // The offloaded traffic statistics per interface that has not been reported since the + // last call to pushTetherStats. Only the interfaces that were ever tethering upstreams + // and has pending tether stats delta are included in this NetworkStats object. + private NetworkStats mIfaceStats = new NetworkStats(0L, 0); + + // The same stats as above, but counts network stats per uid. + private NetworkStats mUidStats = new NetworkStats(0L, 0); + + @Override + public void onRequestStatsUpdate(int token) { + mHandler.post(() -> pushTetherStats()); + } + + @Override + public void onSetAlert(long quotaBytes) { + // no-op + } + + @Override + public void onSetLimit(@NonNull String iface, long quotaBytes) { + // no-op + } + + @VisibleForTesting + void pushTetherStats() { + try { + // The token is not used for now. See b/153606961. + notifyStatsUpdated(0 /* token */, mIfaceStats, mUidStats); + + // Clear the accumulated tether stats delta after reported. Note that create a new + // empty object because NetworkStats#clear is @hide. + mIfaceStats = new NetworkStats(0L, 0); + mUidStats = new NetworkStats(0L, 0); + } catch (RuntimeException e) { + mLog.e("Cannot report network stats: ", e); + } + } + + private void accumulateDiff(@NonNull NetworkStats ifaceDiff, + @NonNull NetworkStats uidDiff) { + mIfaceStats = mIfaceStats.add(ifaceDiff); + mUidStats = mUidStats.add(uidDiff); + } + } + + @NonNull + private NetworkStats buildNetworkStats(@NonNull StatsType type, int ifIndex, + @NonNull ForwardedStats diff) { + NetworkStats stats = new NetworkStats(0L, 0); + final String iface = mInterfaceNames.get(ifIndex); + if (iface == null) { + // TODO: Use Log.wtf once the coordinator owns full control of tether stats from netd. + // For now, netd may add the empty stats for the upstream which is not monitored by + // the coordinator. Silently ignore it. + return stats; + } + final int uid = (type == StatsType.STATS_PER_UID) ? UID_TETHERING : UID_ALL; + // Note that the argument 'metered', 'roaming' and 'defaultNetwork' are not recorded for + // network stats snapshot. See NetworkStatsRecorder#recordSnapshotLocked. + return stats.addEntry(new Entry(iface, uid, SET_DEFAULT, TAG_NONE, METERED_NO, + ROAMING_NO, DEFAULT_NETWORK_NO, diff.rxBytes, diff.rxPackets, + diff.txBytes, diff.txPackets, 0L /* operations */)); + } + + private void updateForwardedStatsFromNetd() { + final TetherStatsParcel[] tetherStatsList; + try { + // The reported tether stats are total data usage for all currently-active upstream + // interfaces since tethering start. + tetherStatsList = mNetd.tetherOffloadGetStats(); + } catch (RemoteException | ServiceSpecificException e) { + mLog.e("Problem fetching tethering stats: ", e); + return; + } + + for (TetherStatsParcel tetherStats : tetherStatsList) { + final Integer ifIndex = tetherStats.ifIndex; + final ForwardedStats curr = new ForwardedStats(tetherStats); + final ForwardedStats base = mStats.get(ifIndex); + final ForwardedStats diff = (base != null) ? curr.subtract(base) : curr; + + // Update the local cache for counting tether stats delta. + mStats.put(ifIndex, curr); + + // Update the accumulated tether stats delta to the stats provider for the service + // querying. + if (mStatsProvider != null) { + try { + mStatsProvider.accumulateDiff( + buildNetworkStats(StatsType.STATS_PER_IFACE, ifIndex, diff), + buildNetworkStats(StatsType.STATS_PER_UID, ifIndex, diff)); + } catch (ArrayIndexOutOfBoundsException e) { + Log.wtf("Fail to update the accumulated stats delta for interface index " + + ifIndex + " : ", e); + } + } + } + } + + private void maybeSchedulePollingStats() { + if (!mStarted) return; + + if (mHandler.hasCallbacks(mScheduledPollingTask)) { + mHandler.removeCallbacks(mScheduledPollingTask); + } + + mHandler.postDelayed(mScheduledPollingTask, mDeps.getPerformPollInterval()); + } +} diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index 69eec8df9864..cfe9feade898 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -232,6 +232,7 @@ public class Tethering { private final TetheringThreadExecutor mExecutor; private final TetheringNotificationUpdater mNotificationUpdater; private final UserManager mUserManager; + private final BpfCoordinator mBpfCoordinator; private final PrivateAddressCoordinator mPrivateAddressCoordinator; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; // All the usage of mTetheringEventCallback should run in the same thread. @@ -284,6 +285,8 @@ public class Tethering { mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog, TetherMasterSM.EVENT_UPSTREAM_CALLBACK); mForwardedDownstreams = new LinkedHashSet<>(); + mBpfCoordinator = mDeps.getBpfCoordinator( + mHandler, mNetd, mLog, new BpfCoordinator.Dependencies()); IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_CARRIER_CONFIG_CHANGED); @@ -1704,6 +1707,9 @@ public class Tethering { chooseUpstreamType(true); mTryCell = false; } + + // TODO: Check the upstream interface if it is managed by BPF offload. + mBpfCoordinator.start(); } @Override @@ -1716,6 +1722,7 @@ public class Tethering { mTetherUpstream = null; reportUpstreamChanged(null); } + mBpfCoordinator.stop(); } private boolean updateUpstreamWanted() { @@ -2341,7 +2348,7 @@ public class Tethering { mLog.log("adding TetheringInterfaceStateMachine for: " + iface); final TetherState tetherState = new TetherState( - new IpServer(iface, mLooper, interfaceType, mLog, mNetd, + new IpServer(iface, mLooper, interfaceType, mLog, mNetd, mBpfCoordinator, makeControlCallback(), mConfig.enableLegacyDhcpServer, mConfig.enableBpfOffload, mPrivateAddressCoordinator, mDeps.getIpServerDependencies())); diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java index ce546c701a61..d637c8646b4a 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java @@ -41,6 +41,17 @@ import java.util.ArrayList; */ public abstract class TetheringDependencies { /** + * Get a reference to the BpfCoordinator to be used by tethering. + */ + public @NonNull BpfCoordinator getBpfCoordinator( + @NonNull Handler handler, @NonNull INetd netd, @NonNull SharedLog log, + @NonNull BpfCoordinator.Dependencies deps) { + final NetworkStatsManager statsManager = + (NetworkStatsManager) getContext().getSystemService(Context.NETWORK_STATS_SERVICE); + return new BpfCoordinator(handler, netd, statsManager, log, deps); + } + + /** * Get a reference to the offload hardware interface to be used by tethering. */ public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) { 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/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java index 0cda29a32f59..433aacfaff44 100644 --- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java +++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java @@ -87,6 +87,7 @@ import android.text.TextUtils; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.networkstack.tethering.BpfCoordinator; import com.android.networkstack.tethering.PrivateAddressCoordinator; import org.junit.Before; @@ -126,6 +127,7 @@ public class IpServerTest { private final IpPrefix mBluetoothPrefix = new IpPrefix("192.168.44.0/24"); @Mock private INetd mNetd; + @Mock private BpfCoordinator mBpfCoordinator; @Mock private IpServer.Callback mCallback; @Mock private SharedLog mSharedLog; @Mock private IDhcpServer mDhcpServer; @@ -179,7 +181,7 @@ public class IpServerTest { neighborCaptor.capture()); mIpServer = new IpServer( - IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd, + IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd, mBpfCoordinator, mCallback, usingLegacyDhcp, usingBpfOffload, mAddressCoordinator, mDependencies); mIpServer.start(); mNeighborEventConsumer = neighborCaptor.getValue(); @@ -222,8 +224,8 @@ public class IpServerTest { when(mDependencies.getIpNeighborMonitor(any(), any(), any())) .thenReturn(mIpNeighborMonitor); mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), TETHERING_BLUETOOTH, mSharedLog, - mNetd, mCallback, false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD, - mAddressCoordinator, mDependencies); + mNetd, mBpfCoordinator, mCallback, false /* usingLegacyDhcp */, + DEFAULT_USING_BPF_OFFLOAD, mAddressCoordinator, mDependencies); mIpServer.start(); mLooper.dispatchAll(); verify(mCallback).updateInterfaceState( diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java new file mode 100644 index 000000000000..b029b43d194f --- /dev/null +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java @@ -0,0 +1,207 @@ +/* + * 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.networkstack.tethering; + +import static android.net.NetworkStats.DEFAULT_NETWORK_NO; +import static android.net.NetworkStats.METERED_NO; +import static android.net.NetworkStats.ROAMING_NO; +import static android.net.NetworkStats.SET_DEFAULT; +import static android.net.NetworkStats.TAG_NONE; +import static android.net.NetworkStats.UID_ALL; +import static android.net.NetworkStats.UID_TETHERING; + +import static com.android.networkstack.tethering.BpfCoordinator + .DEFAULT_PERFORM_POLL_INTERVAL_MS; +import static com.android.networkstack.tethering.BpfCoordinator.StatsType; +import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_IFACE; +import static com.android.networkstack.tethering.BpfCoordinator.StatsType.STATS_PER_UID; + +import static junit.framework.Assert.assertNotNull; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.annotation.NonNull; +import android.app.usage.NetworkStatsManager; +import android.net.INetd; +import android.net.NetworkStats; +import android.net.TetherStatsParcel; +import android.net.util.SharedLog; +import android.os.Handler; +import android.os.test.TestLooper; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.testutils.TestableNetworkStatsProviderCbBinder; + +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 java.util.ArrayList; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class BpfCoordinatorTest { + @Mock private NetworkStatsManager mStatsManager; + @Mock private INetd mNetd; + // Late init since methods must be called by the thread that created this object. + private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb; + private BpfCoordinator.BpfTetherStatsProvider mTetherStatsProvider; + private final ArgumentCaptor<ArrayList> mStringArrayCaptor = + ArgumentCaptor.forClass(ArrayList.class); + private final TestLooper mTestLooper = new TestLooper(); + private BpfCoordinator.Dependencies mDeps = + new BpfCoordinator.Dependencies() { + @Override + int getPerformPollInterval() { + return DEFAULT_PERFORM_POLL_INTERVAL_MS; + } + }; + + @Before public void setUp() { + MockitoAnnotations.initMocks(this); + } + + private void waitForIdle() { + mTestLooper.dispatchAll(); + } + + private void setupFunctioningNetdInterface() throws Exception { + when(mNetd.tetherOffloadGetStats()).thenReturn(new TetherStatsParcel[0]); + } + + @NonNull + private BpfCoordinator makeBpfCoordinator() throws Exception { + BpfCoordinator coordinator = new BpfCoordinator( + new Handler(mTestLooper.getLooper()), mNetd, mStatsManager, new SharedLog("test"), + mDeps); + final ArgumentCaptor<BpfCoordinator.BpfTetherStatsProvider> + tetherStatsProviderCaptor = + ArgumentCaptor.forClass(BpfCoordinator.BpfTetherStatsProvider.class); + verify(mStatsManager).registerNetworkStatsProvider(anyString(), + tetherStatsProviderCaptor.capture()); + mTetherStatsProvider = tetherStatsProviderCaptor.getValue(); + assertNotNull(mTetherStatsProvider); + mTetherStatsProviderCb = new TestableNetworkStatsProviderCbBinder(); + mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb); + return coordinator; + } + + @NonNull + private static NetworkStats.Entry buildTestEntry(@NonNull StatsType how, + @NonNull String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { + return new NetworkStats.Entry(iface, how == STATS_PER_IFACE ? UID_ALL : UID_TETHERING, + SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, rxBytes, + rxPackets, txBytes, txPackets, 0L); + } + + @NonNull + private static TetherStatsParcel buildTestTetherStatsParcel(@NonNull Integer ifIndex, + long rxBytes, long rxPackets, long txBytes, long txPackets) { + final TetherStatsParcel parcel = new TetherStatsParcel(); + parcel.ifIndex = ifIndex; + parcel.rxBytes = rxBytes; + parcel.rxPackets = rxPackets; + parcel.txBytes = txBytes; + parcel.txPackets = txPackets; + return parcel; + } + + private void setTetherOffloadStatsList(TetherStatsParcel[] tetherStatsList) throws Exception { + when(mNetd.tetherOffloadGetStats()).thenReturn(tetherStatsList); + mTestLooper.moveTimeForward(DEFAULT_PERFORM_POLL_INTERVAL_MS); + waitForIdle(); + } + + @Test + public void testGetForwardedStats() throws Exception { + setupFunctioningNetdInterface(); + + final BpfCoordinator coordinator = makeBpfCoordinator(); + coordinator.start(); + + final String wlanIface = "wlan0"; + final Integer wlanIfIndex = 100; + final String mobileIface = "rmnet_data0"; + final Integer mobileIfIndex = 101; + + // Add interface name to lookup table. In realistic case, the upstream interface name will + // be added by IpServer when IpServer has received with a new IPv6 upstream update event. + coordinator.addUpstreamNameToLookupTable(wlanIfIndex, wlanIface); + coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface); + + // [1] Both interface stats are changed. + // Setup the tether stats of wlan and mobile interface. Note that move forward the time of + // the looper to make sure the new tether stats has been updated by polling update thread. + setTetherOffloadStatsList(new TetherStatsParcel[] { + buildTestTetherStatsParcel(wlanIfIndex, 1000, 100, 2000, 200), + buildTestTetherStatsParcel(mobileIfIndex, 3000, 300, 4000, 400)}); + + final NetworkStats expectedIfaceStats = new NetworkStats(0L, 2) + .addEntry(buildTestEntry(STATS_PER_IFACE, wlanIface, 1000, 100, 2000, 200)) + .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 3000, 300, 4000, 400)); + + final NetworkStats expectedUidStats = new NetworkStats(0L, 2) + .addEntry(buildTestEntry(STATS_PER_UID, wlanIface, 1000, 100, 2000, 200)) + .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 3000, 300, 4000, 400)); + + // Force pushing stats update to verify the stats reported. + // TODO: Perhaps make #expectNotifyStatsUpdated to use test TetherStatsParcel object for + // verifying the notification. + mTetherStatsProvider.pushTetherStats(); + mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStats, expectedUidStats); + + // [2] Only one interface stats is changed. + // The tether stats of mobile interface is accumulated and The tether stats of wlan + // interface is the same. + setTetherOffloadStatsList(new TetherStatsParcel[] { + buildTestTetherStatsParcel(wlanIfIndex, 1000, 100, 2000, 200), + buildTestTetherStatsParcel(mobileIfIndex, 3010, 320, 4030, 440)}); + + final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2) + .addEntry(buildTestEntry(STATS_PER_IFACE, wlanIface, 0, 0, 0, 0)) + .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 10, 20, 30, 40)); + + final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2) + .addEntry(buildTestEntry(STATS_PER_UID, wlanIface, 0, 0, 0, 0)) + .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 10, 20, 30, 40)); + + // Force pushing stats update to verify that only diff of stats is reported. + mTetherStatsProvider.pushTetherStats(); + mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStatsDiff, + expectedUidStatsDiff); + + // [3] Stop coordinator. + // Shutdown the coordinator and clear the invocation history, especially the + // tetherOffloadGetStats() calls. + coordinator.stop(); + clearInvocations(mNetd); + + // Verify the polling update thread stopped. + mTestLooper.moveTimeForward(DEFAULT_PERFORM_POLL_INTERVAL_MS); + waitForIdle(); + verify(mNetd, never()).tetherOffloadGetStats(); + } +} 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/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 bb65b18edb8a..8146a58dddcb 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 @@ -203,6 +203,7 @@ public class TetheringTest { @Mock private ConnectivityManager mCm; @Mock private EthernetManager mEm; @Mock private TetheringNotificationUpdater mNotificationUpdater; + @Mock private BpfCoordinator mBpfCoordinator; private final MockIpServerDependencies mIpServerDependencies = spy(new MockIpServerDependencies()); @@ -337,6 +338,12 @@ public class TetheringTest { } @Override + public BpfCoordinator getBpfCoordinator(Handler handler, INetd netd, + SharedLog log, BpfCoordinator.Dependencies deps) { + return mBpfCoordinator; + } + + @Override public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) { return mOffloadHardwareInterface; } 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/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/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 1634f6e62897..9616fe177b23 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1374,10 +1374,9 @@ public class ConnectivityService extends IConnectivityManager.Stub if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) { return; } - String action = blocked ? "BLOCKED" : "UNBLOCKED"; - log(String.format("Blocked status changed to %s for %d(%d) on netId %d", blocked, - nri.mUid, nri.request.requestId, net.netId)); - mNetworkInfoBlockingLogs.log(action + " " + nri.mUid); + final String action = blocked ? "BLOCKED" : "UNBLOCKED"; + mNetworkInfoBlockingLogs.log(String.format( + "%s %d(%d) on netId %d", action, nri.mUid, nri.request.requestId, net.netId)); } /** @@ -1829,11 +1828,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(); } @@ -2087,8 +2087,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() { @@ -5475,7 +5475,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"); @@ -5493,7 +5493,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 @@ -5528,11 +5529,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); } } @@ -5583,11 +5585,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/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 9f2a77c05d2b..169cb9475420 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 5427dd2328a6..2efe2f3a825c 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3776,7 +3776,7 @@ public class AudioService extends IAudioService.Stub iter.remove(); 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 8ed864c71625..b694fc3c86dc 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; @@ -326,6 +327,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"); @@ -333,6 +338,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"); @@ -340,6 +349,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/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index b84d3226362b..b39211ea4c2c 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -22,7 +22,6 @@ import android.hardware.tv.cec.V1_0.SendMessageResult; import android.os.Handler; import android.os.Looper; import android.os.MessageQueue; -import android.os.SystemProperties; import android.util.Slog; import android.util.SparseArray; @@ -117,18 +116,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)); } /** @@ -221,8 +212,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)) { diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 0ac4f9ee4c6d..d0bd635c2255 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -213,9 +213,11 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { mLocalDeviceAddresses = initLocalDeviceAddresses(); resetSelectRequestBuffer(); launchDeviceDiscovery(); + if (!mDelayedMessageBuffer.isBuffered(Constants.MESSAGE_ACTIVE_SOURCE)) { + mService.sendCecCommand(HdmiCecMessageBuilder.buildRequestActiveSource(mAddress)); + } } - @ServiceThreadOnly private List<Integer> initLocalDeviceAddresses() { assertRunOnServiceThread(); @@ -1095,10 +1097,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 9de95abafdda..1b361e727650 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -185,10 +185,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. */ @@ -782,10 +778,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); @@ -1200,10 +1192,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/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 9d3385f20695..043673830f22 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -6949,6 +6949,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 a490b9c99bb4..d03c23e0acfa 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -861,13 +861,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/OWNERS b/services/core/java/com/android/server/pm/OWNERS index f8c173f6a9c1..6fdde7a196cc 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -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/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp index e79612fbf3d3..a99c0a3fa23e 100644 --- a/services/core/jni/com_android_server_AlarmManagerService.cpp +++ b/services/core/jni/com_android_server_AlarmManagerService.cpp @@ -40,6 +40,7 @@ #include <linux/rtc.h> #include <array> +#include <limits> #include <memory> namespace android { @@ -213,22 +214,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; diff --git a/services/core/jni/com_android_server_SerialService.cpp b/services/core/jni/com_android_server_SerialService.cpp index aef0b25503c8..c9459994a658 100644 --- a/services/core/jni/com_android_server_SerialService.cpp +++ b/services/core/jni/com_android_server_SerialService.cpp @@ -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..72dce4dca0da 100644 --- a/services/core/jni/com_android_server_UsbDeviceManager.cpp +++ b/services/core/jni/com_android_server_UsbDeviceManager.cpp @@ -19,6 +19,7 @@ #include "jni.h" #include <nativehelper/JNIHelp.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..a40bcd0d7c07 100644 --- a/services/core/jni/com_android_server_UsbHostManager.cpp +++ b/services/core/jni/com_android_server_UsbHostManager.cpp @@ -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..8ac2c4f37ecd 100644 --- a/services/core/jni/com_android_server_UsbMidiDevice.cpp +++ b/services/core/jni/com_android_server_UsbMidiDevice.cpp @@ -20,6 +20,7 @@ #include "jni.h" #include <nativehelper/JNIHelp.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_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp index 098b2ef6439d..4e1a23416330 100644 --- a/services/core/jni/com_android_server_tv_TvInputHal.cpp +++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp @@ -301,6 +301,7 @@ private: JTvInputHal(JNIEnv* env, jobject thiz, sp<ITvInput> tvInput, const sp<Looper>& looper); Mutex mLock; + Mutex mStreamLock; jweak mThiz; sp<Looper> mLooper; @@ -338,6 +339,7 @@ JTvInputHal* JTvInputHal::createInstance(JNIEnv* env, jobject thiz, const sp<Loo } int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp<Surface>& surface) { + Mutex::Autolock autoLock(&mStreamLock); KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); if (connections.indexOfKey(streamId) < 0) { connections.add(streamId, Connection()); @@ -412,6 +414,7 @@ int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp<Surface> } int JTvInputHal::removeStream(int deviceId, int streamId) { + Mutex::Autolock autoLock(&mStreamLock); KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); if (connections.indexOfKey(streamId) < 0) { return BAD_VALUE; diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp index de639c5d0760..1a828a9567b4 100644 --- a/services/incremental/Android.bp +++ b/services/incremental/Android.bp @@ -53,7 +53,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 e790a196ad64..8d2afc1bea37 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..20fc272e4e2e 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -180,6 +180,8 @@ import com.android.server.wm.ActivityTaskManagerService; import com.android.server.wm.WindowManagerGlobalLock; import com.android.server.wm.WindowManagerService; +import libcore.timezone.ZoneInfoDb; + import dalvik.system.VMRuntime; import com.google.android.startop.iorap.IorapForwardingService; @@ -199,12 +201,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 +440,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"); } @@ -623,6 +620,12 @@ public final class SystemServer { 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/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 5412bb5106ff..40ff44fe02e8 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 com.google.common.truth.Expect import com.google.common.truth.Truth.assertWithMessage +import org.junit.Ignore import org.junit.Rule import org.junit.Test @@ -34,6 +35,7 @@ class AndroidPackageParsingEquivalenceTest : AndroidPackageParsingTestBase() { val expect = Expect.create() @Test + @Ignore("b/155935153") fun applicationInfoEquality() { val flags = PackageManager.GET_META_DATA or PackageManager.GET_SHARED_LIBRARY_FILES val oldAppInfo = oldPackages.asSequence().map { oldAppInfo(it, flags) } @@ -53,6 +55,7 @@ class AndroidPackageParsingEquivalenceTest : AndroidPackageParsingTestBase() { } @Test + @Ignore("b/155935153") fun packageInfoEquality() { val flags = PackageManager.GET_ACTIVITIES or PackageManager.GET_CONFIGURATIONS or diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java index 3062584aee20..389a03868d80 100644 --- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java @@ -38,6 +38,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; @@ -159,6 +160,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { LocalServices.addService(clazz, service); } + @Ignore // b/152719290 - Fails on stage-aosp-master @Test public void setAutoMode_screenOffRegistered() throws RemoteException { try { @@ -168,6 +170,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 622a203c5242..749a234985f2 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/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/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 87330d66ab84..34b1c4d35182 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. */ @@ -3752,6 +3780,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}. */ @@ -3874,6 +3911,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); @@ -4320,6 +4359,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); @@ -4582,6 +4622,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/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..3d96fc634d6a 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_FILE_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 file that can be provided via + * {@link #addServiceAnnouncementFile} + * @return The maximum length of the byte array passed as an argument to + * {@link #addServiceAnnouncementFile}. + */ + public static int getMaximumServiceAnnouncementFileSize() { + return MAX_SERVICE_ANNOUNCEMENT_FILE_SIZE; + } + private int bindAndInitialize() { mServiceConnection = new ServiceConnection() { @Override @@ -424,6 +436,60 @@ public class MbmsDownloadSession implements AutoCloseable { } /** + * Inform the middleware of a service announcement file received from a group communication + * server. + * + * When participating in a group call via the {@link MbmsGroupCallSession} API, applications may + * receive a service announcement file 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 file 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 file is too large. + * + * @param fileContents The contents of the service announcement file received from the group + * call server. If the size of this array is greater than the value of + * {@link #getMaximumServiceAnnouncementFileSize()}, an + * {@link IllegalArgumentException} will be thrown. + */ + public void addServiceAnnouncementFile(@NonNull byte[] fileContents) { + IMbmsDownloadService downloadService = mService.get(); + if (downloadService == null) { + throw new IllegalStateException("Middleware not yet bound"); + } + + if (fileContents.length > MAX_SERVICE_ANNOUNCEMENT_FILE_SIZE) { + throw new IllegalArgumentException("File too large"); + } + + try { + int returnCode = downloadService.addServiceAnnouncementFile( + mSubscriptionId, fileContents); + 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/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/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index e537f666d4c0..347dcc81ce4e 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -321,12 +321,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 +339,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 +510,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/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/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..8611d26bc85b 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 file passed via + * {@link android.telephony.MbmsDownloadSession#addServiceAnnouncementFile(byte[])} + * is malformed. + */ + public static final int ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE = 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_FILE, + 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..36136ab280c4 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 addServiceAnnouncementFile(int subId, in byte[] fileContents); + 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..3279ce66cd17 100644 --- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java +++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java @@ -216,6 +216,28 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub { } /** + * Called when the client application wishes to receive file information according to a + * service announcement file received from a group call server. + * + * The service announcement file is in the format of a multipart MIME file with XML parts, + * though no validation is performed on the contents of the {@code fileContents} argument -- + * implementing middleware applications should perform their own validation and return + * {@link MbmsErrors.DownloadErrors#ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE} if the file is + * malformed. + * + * @param subscriptionId The subscription id the service announcement applies to. + * @param fileContents The contents of the service announcement file. + * @return {@link MbmsErrors#SUCCESS}, or + * {@link MbmsErrors.DownloadErrors#ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE} + */ + // TODO: are there any public specifications of what the file format is that I can link to? + @Override + public @MbmsErrors.MbmsError int addServiceAnnouncementFile( + int subscriptionId, @NonNull byte[] fileContents) { + return 0; + } + + /** * 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/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..4fbafb78fe3c 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; @@ -540,8 +542,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; diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index 08580012ad17..ccb14749109d 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; @@ -178,7 +179,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(); 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/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 c86d388a3db9..ea4982ed7c7d 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -3051,6 +3051,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, () -> { @@ -3063,7 +3070,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/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/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++; } |