diff options
219 files changed, 2954 insertions, 952 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index bd693850f45e..c76be6f43372 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -17,7 +17,9 @@ aconfig_srcjars = [ ":aconfig_mediacodec_flags_java_lib{.generated_srcjars}", ":android.content.pm.flags-aconfig-java{.generated_srcjars}", ":android.content.res.flags-aconfig-java{.generated_srcjars}", + ":android.crashrecovery.flags-aconfig-java{.generated_srcjars}", ":android.hardware.biometrics.flags-aconfig-java{.generated_srcjars}", + ":android.media.playback.flags-aconfig-java{.generated_srcjars}", ":android.net.vcn.flags-aconfig-java{.generated_srcjars}", ":android.nfc.flags-aconfig-java{.generated_srcjars}", ":android.os.flags-aconfig-java{.generated_srcjars}", @@ -25,11 +27,33 @@ aconfig_srcjars = [ ":com.android.hardware.camera2-aconfig-java{.generated_srcjars}", ":com.android.hardware.input-aconfig-java{.generated_srcjars}", ":com.android.net.flags-aconfig-java{.generated_srcjars}", + ":com.android.net.thread.flags-aconfig-java{.generated_srcjars}", ":com.android.text.flags-aconfig-java{.generated_srcjars}", ":com.android.window.flags.window-aconfig-java{.generated_srcjars}", // !!! KEEP THIS LIST ALPHABETICAL !!! ] +stubs_defaults { + name: "framework-minus-apex-aconfig-declarations", + aconfig_declarations: [ + "android.content.pm.flags-aconfig", + "android.content.res.flags-aconfig", + "android.crashrecovery.flags-aconfig", + "android.hardware.biometrics.flags-aconfig", + "android.media.playback.flags-aconfig", + "android.net.vcn.flags-aconfig", + "android.nfc.flags-aconfig", + "android.os.flags-aconfig", + "android.security.flags-aconfig", + "com.android.hardware.camera2-aconfig", + "com.android.hardware.input.input-aconfig", + "com.android.net.thread.flags-aconfig", + "com.android.window.flags.window-aconfig", + "com.android.text.flags-aconfig", + "com.android.net.flags-aconfig", + ], +} + filegroup { name: "framework-minus-apex-aconfig-srcjars", srcs: aconfig_srcjars, @@ -122,7 +146,7 @@ java_aconfig_library { aconfig_declarations { name: "android.nfc.flags-aconfig", package: "android.nfc", - srcs: ["core/java/android/nfc/*.aconfig"], + srcs: ["nfc/java/android/nfc/*.aconfig"], } cc_aconfig_library { @@ -140,7 +164,7 @@ cc_aconfig_library { java_aconfig_library { name: "android.nfc.flags-aconfig-java", aconfig_declarations: "android.nfc.flags-aconfig", - min_sdk_version: "VanillaIceCream", + min_sdk_version: "34", apex_available: [ "//apex_available:platform", "com.android.nfcservices", @@ -227,12 +251,25 @@ aconfig_declarations { srcs: ["core/java/android/net/flags.aconfig"], } +// Thread network +aconfig_declarations { + name: "com.android.net.thread.flags-aconfig", + package: "com.android.net.thread.flags", + srcs: ["core/java/android/net/thread/flags.aconfig"], +} + java_aconfig_library { name: "com.android.net.flags-aconfig-java", aconfig_declarations: "com.android.net.flags-aconfig", defaults: ["framework-minus-apex-aconfig-java-defaults"], } +java_aconfig_library { + name: "com.android.net.thread.flags-aconfig-java", + aconfig_declarations: "com.android.net.thread.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // Media aconfig_declarations { name: "android.media.playback.flags-aconfig", @@ -263,3 +300,16 @@ java_aconfig_library { aconfig_declarations: "android.net.vcn.flags-aconfig", defaults: ["framework-minus-apex-aconfig-java-defaults"], } + +// CrashRecovery Module +aconfig_declarations { + name: "android.crashrecovery.flags-aconfig", + package: "android.crashrecovery.flags", + srcs: ["packages/CrashRecovery/aconfig/flags.aconfig"], +} + +java_aconfig_library { + name: "android.crashrecovery.flags-aconfig-java", + aconfig_declarations: "android.crashrecovery.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} diff --git a/Android.bp b/Android.bp index 2113e4b85248..6f4593b1595d 100644 --- a/Android.bp +++ b/Android.bp @@ -427,7 +427,6 @@ java_library { name: "framework-non-updatable-unbundled-impl-libs", static_libs: [ "framework-location.impl", - "framework-nfc.impl", ], sdk_version: "core_platform", installable: false, @@ -39,3 +39,5 @@ per-file *ravenwood* = file:ravenwood/OWNERS per-file *Ravenwood* = file:ravenwood/OWNERS per-file PERFORMANCE_OWNERS = file:/PERFORMANCE_OWNERS + +per-file PACKAGE_MANAGER_OWNERS = file:/PACKAGE_MANAGER_OWNERS
\ No newline at end of file diff --git a/PACKAGE_MANAGER_OWNERS b/PACKAGE_MANAGER_OWNERS index e4549b4de164..eb5842ba58ce 100644 --- a/PACKAGE_MANAGER_OWNERS +++ b/PACKAGE_MANAGER_OWNERS @@ -1,3 +1,3 @@ -chiuwinson@google.com +alexbuy@google.com patb@google.com schfan@google.com
\ No newline at end of file diff --git a/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt b/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt index aadbc2319a62..add0a086201b 100644 --- a/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt +++ b/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt @@ -16,8 +16,6 @@ package android.input -import android.content.Context -import android.content.res.Resources import android.os.SystemProperties import android.perftests.utils.PerfStatusReporter import android.view.InputDevice @@ -38,8 +36,6 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mockito.mock -import org.mockito.Mockito.`when` import java.time.Duration @@ -68,18 +64,6 @@ private fun getStylusMotionEvent( InputDevice.SOURCE_STYLUS, /*flags=*/0) } -private fun getPredictionContext(offset: Duration, enablePrediction: Boolean): Context { - val context = mock(Context::class.java) - val resources: Resources = mock(Resources::class.java) - `when`(context.getResources()).thenReturn(resources) - `when`(resources.getInteger( - com.android.internal.R.integer.config_motionPredictionOffsetNanos)).thenReturn( - offset.toNanos().toInt()) - `when`(resources.getBoolean( - com.android.internal.R.bool.config_enableMotionPrediction)).thenReturn(enablePrediction) - return context -} - @RunWith(AndroidJUnit4::class) @LargeTest class MotionPredictorBenchmark { @@ -115,7 +99,7 @@ class MotionPredictorBenchmark { var eventPosition = 0f val positionInterval = 10f - val predictor = MotionPredictor(getPredictionContext(offset, /*enablePrediction=*/true)) + val predictor = MotionPredictor(/*isPredictionEnabled=*/true, offset.toNanos().toInt()) // ACTION_DOWN t=0 x=0 y=0 predictor.record(getStylusMotionEvent( eventTime, ACTION_DOWN, /*x=*/eventPosition, /*y=*/eventPosition)) @@ -141,12 +125,11 @@ class MotionPredictorBenchmark { */ @Test fun timeCreatePredictor() { - val context = getPredictionContext( - /*offset=*/Duration.ofMillis(20), /*enablePrediction=*/true) + val offsetNanos = Duration.ofMillis(20).toNanos().toInt() val state = perfStatusReporter.getBenchmarkState() while (state.keepRunning()) { - MotionPredictor(context) + MotionPredictor(/*isPredictionEnabled=*/true, offsetNanos) } } } diff --git a/api/Android.bp b/api/Android.bp index 7dd13e3f8a09..7fb427eb715a 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -310,6 +310,7 @@ packages_to_document = [ // classpath (or sources) somehow. stubs_defaults { name: "android-non-updatable-stubs-defaults", + defaults: ["framework-minus-apex-aconfig-declarations"], srcs: [":android-non-updatable-stub-sources"], sdk_version: "none", system_modules: "none", diff --git a/api/ApiDocs.bp b/api/ApiDocs.bp index d7e25834905c..62f0b6e9a2e0 100644 --- a/api/ApiDocs.bp +++ b/api/ApiDocs.bp @@ -51,6 +51,7 @@ stubs_defaults { ":framework-graphics-srcs", ":framework-mediaprovider-sources", ":framework-nearby-sources", + ":framework-nfc-updatable-sources", ":framework-ondevicepersonalization-sources", ":framework-permission-sources", ":framework-permission-s-sources", diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp index ec4fc46a76fb..59c01284ab27 100644 --- a/api/StubLibraries.bp +++ b/api/StubLibraries.bp @@ -779,7 +779,6 @@ java_defaults { api_contributions: [ "framework-virtualization.stubs.source.test.api.contribution", "framework-location.stubs.source.test.api.contribution", - "framework-nfc.stubs.source.test.api.contribution", ], } diff --git a/api/api.go b/api/api.go index a632582ce76d..fa2be21db09f 100644 --- a/api/api.go +++ b/api/api.go @@ -31,7 +31,6 @@ const conscrypt = "conscrypt.module.public.api" const i18n = "i18n.module.public.api" const virtualization = "framework-virtualization" const location = "framework-location" -const nfc = "framework-nfc" var core_libraries_modules = []string{art, conscrypt, i18n} @@ -43,7 +42,7 @@ var core_libraries_modules = []string{art, conscrypt, i18n} // APIs. // In addition, the modules in this list are allowed to contribute to test APIs // stubs. -var non_updatable_modules = []string{virtualization, location, nfc} +var non_updatable_modules = []string{virtualization, location} // The intention behind this soong plugin is to generate a number of "merged" // API-related modules that would otherwise require a large amount of very diff --git a/core/api/Android.bp b/core/api/Android.bp index 907916a125da..8d8a82b69b55 100644 --- a/core/api/Android.bp +++ b/core/api/Android.bp @@ -96,21 +96,3 @@ filegroup { name: "non-updatable-test-lint-baseline.txt", srcs: ["test-lint-baseline.txt"], } - -java_api_contribution { - name: "api-stubs-docs-non-updatable-public-stubs", - api_surface: "public", - api_file: "current.txt", - visibility: [ - "//build/orchestrator/apis", - ], -} - -java_api_contribution { - name: "frameworks-base-core-api-module-lib-stubs", - api_surface: "module-lib", - api_file: "module-lib-current.txt", - visibility: [ - "//build/orchestrator/apis", - ], -} diff --git a/core/api/current.txt b/core/api/current.txt index e26632a72183..ea1cd21d5aee 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -22573,6 +22573,7 @@ package android.media { method @NonNull public java.util.List<java.lang.String> getSupportedVendorParameters(); method @Nullable public static android.media.Image mapHardwareBuffer(@NonNull android.hardware.HardwareBuffer); method public void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException; + method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") public void queueInputBuffers(int, @NonNull java.util.ArrayDeque<android.media.MediaCodec.BufferInfo>); method public void queueSecureInputBuffer(int, int, @NonNull android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException; method public void release(); method public void releaseOutputBuffer(int, boolean); @@ -22634,6 +22635,7 @@ package android.media { method public abstract void onError(@NonNull android.media.MediaCodec, @NonNull android.media.MediaCodec.CodecException); method public abstract void onInputBufferAvailable(@NonNull android.media.MediaCodec, int); method public abstract void onOutputBufferAvailable(@NonNull android.media.MediaCodec, int, @NonNull android.media.MediaCodec.BufferInfo); + method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") public void onOutputBuffersAvailable(@NonNull android.media.MediaCodec, int, @NonNull java.util.ArrayDeque<android.media.MediaCodec.BufferInfo>); method public abstract void onOutputFormatChanged(@NonNull android.media.MediaCodec, @NonNull android.media.MediaFormat); } @@ -22721,6 +22723,7 @@ package android.media { } public static final class MediaCodec.OutputFrame { + method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") @NonNull public java.util.ArrayDeque<android.media.MediaCodec.BufferInfo> getBufferInfos(); method @NonNull public java.util.Set<java.lang.String> getChangedKeys(); method public int getFlags(); method @NonNull public android.media.MediaFormat getFormat(); @@ -22736,6 +22739,7 @@ package android.media { public final class MediaCodec.QueueRequest { method public void queue(); + method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") @NonNull public android.media.MediaCodec.QueueRequest setBufferInfos(@NonNull java.util.ArrayDeque<android.media.MediaCodec.BufferInfo>); method @NonNull public android.media.MediaCodec.QueueRequest setByteBufferParameter(@NonNull String, @NonNull java.nio.ByteBuffer); method @NonNull public android.media.MediaCodec.QueueRequest setEncryptedLinearBlock(@NonNull android.media.MediaCodec.LinearBlock, int, int, @NonNull android.media.MediaCodec.CryptoInfo); method @NonNull public android.media.MediaCodec.QueueRequest setFlags(int); @@ -29043,444 +29047,6 @@ package android.net.vcn { } -package android.nfc { - - public final class AvailableNfcAntenna implements android.os.Parcelable { - ctor public AvailableNfcAntenna(int, int); - method public int describeContents(); - method public int getLocationX(); - method public int getLocationY(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.nfc.AvailableNfcAntenna> CREATOR; - } - - public class FormatException extends java.lang.Exception { - ctor public FormatException(); - ctor public FormatException(String); - ctor public FormatException(String, Throwable); - } - - public final class NdefMessage implements android.os.Parcelable { - ctor public NdefMessage(byte[]) throws android.nfc.FormatException; - ctor public NdefMessage(android.nfc.NdefRecord, android.nfc.NdefRecord...); - ctor public NdefMessage(android.nfc.NdefRecord[]); - method public int describeContents(); - method public int getByteArrayLength(); - method public android.nfc.NdefRecord[] getRecords(); - method public byte[] toByteArray(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefMessage> CREATOR; - } - - public final class NdefRecord implements android.os.Parcelable { - ctor public NdefRecord(short, byte[], byte[], byte[]); - ctor @Deprecated public NdefRecord(byte[]) throws android.nfc.FormatException; - method public static android.nfc.NdefRecord createApplicationRecord(String); - method public static android.nfc.NdefRecord createExternal(String, String, byte[]); - method public static android.nfc.NdefRecord createMime(String, byte[]); - method public static android.nfc.NdefRecord createTextRecord(String, String); - method public static android.nfc.NdefRecord createUri(android.net.Uri); - method public static android.nfc.NdefRecord createUri(String); - method public int describeContents(); - method public byte[] getId(); - method public byte[] getPayload(); - method public short getTnf(); - method public byte[] getType(); - method @Deprecated public byte[] toByteArray(); - method public String toMimeType(); - method public android.net.Uri toUri(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefRecord> CREATOR; - field public static final byte[] RTD_ALTERNATIVE_CARRIER; - field public static final byte[] RTD_HANDOVER_CARRIER; - field public static final byte[] RTD_HANDOVER_REQUEST; - field public static final byte[] RTD_HANDOVER_SELECT; - field public static final byte[] RTD_SMART_POSTER; - field public static final byte[] RTD_TEXT; - field public static final byte[] RTD_URI; - field public static final short TNF_ABSOLUTE_URI = 3; // 0x3 - field public static final short TNF_EMPTY = 0; // 0x0 - field public static final short TNF_EXTERNAL_TYPE = 4; // 0x4 - field public static final short TNF_MIME_MEDIA = 2; // 0x2 - field public static final short TNF_UNCHANGED = 6; // 0x6 - field public static final short TNF_UNKNOWN = 5; // 0x5 - field public static final short TNF_WELL_KNOWN = 1; // 0x1 - } - - public final class NfcAdapter { - method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean allowTransaction(); - method public void disableForegroundDispatch(android.app.Activity); - method public void disableReaderMode(android.app.Activity); - method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean disallowTransaction(); - method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]); - method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle); - method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context); - method @Nullable public android.nfc.NfcAntennaInfo getNfcAntennaInfo(); - method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler); - method public boolean isEnabled(); - method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean isObserveModeSupported(); - method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionEnabled(); - method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionSupported(); - method public boolean isSecureNfcEnabled(); - method public boolean isSecureNfcSupported(); - method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void resetDiscoveryTechnology(@NonNull android.app.Activity); - method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void setDiscoveryTechnology(@NonNull android.app.Activity, int, int); - field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED"; - field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED"; - field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED"; - field public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED"; - field public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED"; - field @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT) public static final String ACTION_TRANSACTION_DETECTED = "android.nfc.action.TRANSACTION_DETECTED"; - field public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE"; - field public static final String EXTRA_AID = "android.nfc.extra.AID"; - field public static final String EXTRA_DATA = "android.nfc.extra.DATA"; - field public static final String EXTRA_ID = "android.nfc.extra.ID"; - field public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES"; - field public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON = "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON"; - field public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence"; - field public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME"; - field public static final String EXTRA_TAG = "android.nfc.extra.TAG"; - field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_DISABLE = 0; // 0x0 - field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_KEEP = -1; // 0xffffffff - field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_A = 1; // 0x1 - field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_B = 2; // 0x2 - field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_F = 4; // 0x4 - field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_DISABLE = 0; // 0x0 - field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_KEEP = -1; // 0xffffffff - field public static final int FLAG_READER_NFC_A = 1; // 0x1 - field public static final int FLAG_READER_NFC_B = 2; // 0x2 - field public static final int FLAG_READER_NFC_BARCODE = 16; // 0x10 - field public static final int FLAG_READER_NFC_F = 4; // 0x4 - field public static final int FLAG_READER_NFC_V = 8; // 0x8 - field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100 - field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80 - field public static final int PREFERRED_PAYMENT_CHANGED = 2; // 0x2 - field public static final int PREFERRED_PAYMENT_LOADED = 1; // 0x1 - field public static final int PREFERRED_PAYMENT_UPDATED = 3; // 0x3 - field public static final int STATE_OFF = 1; // 0x1 - field public static final int STATE_ON = 3; // 0x3 - field public static final int STATE_TURNING_OFF = 4; // 0x4 - field public static final int STATE_TURNING_ON = 2; // 0x2 - } - - @Deprecated public static interface NfcAdapter.CreateBeamUrisCallback { - method @Deprecated public android.net.Uri[] createBeamUris(android.nfc.NfcEvent); - } - - @Deprecated public static interface NfcAdapter.CreateNdefMessageCallback { - method @Deprecated public android.nfc.NdefMessage createNdefMessage(android.nfc.NfcEvent); - } - - @Deprecated public static interface NfcAdapter.OnNdefPushCompleteCallback { - method @Deprecated public void onNdefPushComplete(android.nfc.NfcEvent); - } - - public static interface NfcAdapter.OnTagRemovedListener { - method public void onTagRemoved(); - } - - public static interface NfcAdapter.ReaderCallback { - method public void onTagDiscovered(android.nfc.Tag); - } - - public final class NfcAntennaInfo implements android.os.Parcelable { - ctor public NfcAntennaInfo(int, int, boolean, @NonNull java.util.List<android.nfc.AvailableNfcAntenna>); - method public int describeContents(); - method @NonNull public java.util.List<android.nfc.AvailableNfcAntenna> getAvailableNfcAntennas(); - method public int getDeviceHeight(); - method public int getDeviceWidth(); - method public boolean isDeviceFoldable(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NfcAntennaInfo> CREATOR; - } - - public final class NfcEvent { - field public final android.nfc.NfcAdapter nfcAdapter; - field public final int peerLlcpMajorVersion; - field public final int peerLlcpMinorVersion; - } - - public final class NfcManager { - method public android.nfc.NfcAdapter getDefaultAdapter(); - } - - public final class Tag implements android.os.Parcelable { - method public int describeContents(); - method public byte[] getId(); - method public String[] getTechList(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.nfc.Tag> CREATOR; - } - - public class TagLostException extends java.io.IOException { - ctor public TagLostException(); - ctor public TagLostException(String); - } - -} - -package android.nfc.cardemulation { - - public final class CardEmulation { - method public boolean categoryAllowsForegroundPreference(String); - method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService(); - method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String); - method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService(); - method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter); - method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService(); - method public int getSelectionModeForCategory(String); - method public boolean isDefaultServiceForAid(android.content.ComponentName, String); - method public boolean isDefaultServiceForCategory(android.content.ComponentName, String); - method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>); - method public boolean removeAidsForService(android.content.ComponentName, String); - method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean setOffHostForService(@NonNull android.content.ComponentName, @NonNull String); - method public boolean setPreferredService(android.app.Activity, android.content.ComponentName); - method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setServiceObserveModeDefault(@NonNull android.content.ComponentName, boolean); - method public boolean supportsAidPrefixRegistration(); - method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName); - method public boolean unsetPreferredService(android.app.Activity); - field public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT"; - field public static final String CATEGORY_OTHER = "other"; - field public static final String CATEGORY_PAYMENT = "payment"; - field public static final String EXTRA_CATEGORY = "category"; - field public static final String EXTRA_SERVICE_COMPONENT = "component"; - field public static final int SELECTION_MODE_ALWAYS_ASK = 1; // 0x1 - field public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2; // 0x2 - field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0 - } - - public abstract class HostApduService extends android.app.Service { - ctor public HostApduService(); - method public final void notifyUnhandled(); - method public final android.os.IBinder onBind(android.content.Intent); - method public abstract void onDeactivated(int); - method public abstract byte[] processCommandApdu(byte[], android.os.Bundle); - method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.os.Bundle>); - method public final void sendResponseApdu(byte[]); - field public static final int DEACTIVATION_DESELECTED = 1; // 0x1 - field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String POLLING_LOOP_DATA_KEY = "android.nfc.cardemulation.DATA"; - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String POLLING_LOOP_GAIN_KEY = "android.nfc.cardemulation.GAIN"; - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String POLLING_LOOP_TIMESTAMP_KEY = "android.nfc.cardemulation.TIMESTAMP"; - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_A = 65; // 0x0041 'A' - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_B = 66; // 0x0042 'B' - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_F = 70; // 0x0046 'F' - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String POLLING_LOOP_TYPE_KEY = "android.nfc.cardemulation.TYPE"; - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_OFF = 88; // 0x0058 'X' - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_ON = 79; // 0x004f 'O' - field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_UNKNOWN = 85; // 0x0055 'U' - field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_APDU_SERVICE"; - field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service"; - } - - public abstract class HostNfcFService extends android.app.Service { - ctor public HostNfcFService(); - method public final android.os.IBinder onBind(android.content.Intent); - method public abstract void onDeactivated(int); - method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle); - method public final void sendResponsePacket(byte[]); - field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 - field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE"; - field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service"; - } - - public final class NfcFCardEmulation { - method public boolean disableService(android.app.Activity) throws java.lang.RuntimeException; - method public boolean enableService(android.app.Activity, android.content.ComponentName) throws java.lang.RuntimeException; - method public static android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter); - method public String getNfcid2ForService(android.content.ComponentName) throws java.lang.RuntimeException; - method public String getSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException; - method public boolean registerSystemCodeForService(android.content.ComponentName, String) throws java.lang.RuntimeException; - method public boolean setNfcid2ForService(android.content.ComponentName, String) throws java.lang.RuntimeException; - method public boolean unregisterSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException; - } - - public abstract class OffHostApduService extends android.app.Service { - ctor public OffHostApduService(); - field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"; - field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service"; - } - -} - -package android.nfc.tech { - - public final class IsoDep implements android.nfc.tech.TagTechnology { - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public static android.nfc.tech.IsoDep get(android.nfc.Tag); - method public byte[] getHiLayerResponse(); - method public byte[] getHistoricalBytes(); - method public int getMaxTransceiveLength(); - method public android.nfc.Tag getTag(); - method public int getTimeout(); - method public boolean isConnected(); - method public boolean isExtendedLengthApduSupported(); - method public void setTimeout(int); - method public byte[] transceive(byte[]) throws java.io.IOException; - } - - public final class MifareClassic implements android.nfc.tech.TagTechnology { - method public boolean authenticateSectorWithKeyA(int, byte[]) throws java.io.IOException; - method public boolean authenticateSectorWithKeyB(int, byte[]) throws java.io.IOException; - method public int blockToSector(int); - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public void decrement(int, int) throws java.io.IOException; - method public static android.nfc.tech.MifareClassic get(android.nfc.Tag); - method public int getBlockCount(); - method public int getBlockCountInSector(int); - method public int getMaxTransceiveLength(); - method public int getSectorCount(); - method public int getSize(); - method public android.nfc.Tag getTag(); - method public int getTimeout(); - method public int getType(); - method public void increment(int, int) throws java.io.IOException; - method public boolean isConnected(); - method public byte[] readBlock(int) throws java.io.IOException; - method public void restore(int) throws java.io.IOException; - method public int sectorToBlock(int); - method public void setTimeout(int); - method public byte[] transceive(byte[]) throws java.io.IOException; - method public void transfer(int) throws java.io.IOException; - method public void writeBlock(int, byte[]) throws java.io.IOException; - field public static final int BLOCK_SIZE = 16; // 0x10 - field public static final byte[] KEY_DEFAULT; - field public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY; - field public static final byte[] KEY_NFC_FORUM; - field public static final int SIZE_1K = 1024; // 0x400 - field public static final int SIZE_2K = 2048; // 0x800 - field public static final int SIZE_4K = 4096; // 0x1000 - field public static final int SIZE_MINI = 320; // 0x140 - field public static final int TYPE_CLASSIC = 0; // 0x0 - field public static final int TYPE_PLUS = 1; // 0x1 - field public static final int TYPE_PRO = 2; // 0x2 - field public static final int TYPE_UNKNOWN = -1; // 0xffffffff - } - - public final class MifareUltralight implements android.nfc.tech.TagTechnology { - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public static android.nfc.tech.MifareUltralight get(android.nfc.Tag); - method public int getMaxTransceiveLength(); - method public android.nfc.Tag getTag(); - method public int getTimeout(); - method public int getType(); - method public boolean isConnected(); - method public byte[] readPages(int) throws java.io.IOException; - method public void setTimeout(int); - method public byte[] transceive(byte[]) throws java.io.IOException; - method public void writePage(int, byte[]) throws java.io.IOException; - field public static final int PAGE_SIZE = 4; // 0x4 - field public static final int TYPE_ULTRALIGHT = 1; // 0x1 - field public static final int TYPE_ULTRALIGHT_C = 2; // 0x2 - field public static final int TYPE_UNKNOWN = -1; // 0xffffffff - } - - public final class Ndef implements android.nfc.tech.TagTechnology { - method public boolean canMakeReadOnly(); - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public static android.nfc.tech.Ndef get(android.nfc.Tag); - method public android.nfc.NdefMessage getCachedNdefMessage(); - method public int getMaxSize(); - method public android.nfc.NdefMessage getNdefMessage() throws android.nfc.FormatException, java.io.IOException; - method public android.nfc.Tag getTag(); - method public String getType(); - method public boolean isConnected(); - method public boolean isWritable(); - method public boolean makeReadOnly() throws java.io.IOException; - method public void writeNdefMessage(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException; - field public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic"; - field public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1"; - field public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2"; - field public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3"; - field public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4"; - } - - public final class NdefFormatable implements android.nfc.tech.TagTechnology { - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public void format(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException; - method public void formatReadOnly(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException; - method public static android.nfc.tech.NdefFormatable get(android.nfc.Tag); - method public android.nfc.Tag getTag(); - method public boolean isConnected(); - } - - public final class NfcA implements android.nfc.tech.TagTechnology { - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public static android.nfc.tech.NfcA get(android.nfc.Tag); - method public byte[] getAtqa(); - method public int getMaxTransceiveLength(); - method public short getSak(); - method public android.nfc.Tag getTag(); - method public int getTimeout(); - method public boolean isConnected(); - method public void setTimeout(int); - method public byte[] transceive(byte[]) throws java.io.IOException; - } - - public final class NfcB implements android.nfc.tech.TagTechnology { - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public static android.nfc.tech.NfcB get(android.nfc.Tag); - method public byte[] getApplicationData(); - method public int getMaxTransceiveLength(); - method public byte[] getProtocolInfo(); - method public android.nfc.Tag getTag(); - method public boolean isConnected(); - method public byte[] transceive(byte[]) throws java.io.IOException; - } - - public final class NfcBarcode implements android.nfc.tech.TagTechnology { - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public static android.nfc.tech.NfcBarcode get(android.nfc.Tag); - method public byte[] getBarcode(); - method public android.nfc.Tag getTag(); - method public int getType(); - method public boolean isConnected(); - field public static final int TYPE_KOVIO = 1; // 0x1 - field public static final int TYPE_UNKNOWN = -1; // 0xffffffff - } - - public final class NfcF implements android.nfc.tech.TagTechnology { - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public static android.nfc.tech.NfcF get(android.nfc.Tag); - method public byte[] getManufacturer(); - method public int getMaxTransceiveLength(); - method public byte[] getSystemCode(); - method public android.nfc.Tag getTag(); - method public int getTimeout(); - method public boolean isConnected(); - method public void setTimeout(int); - method public byte[] transceive(byte[]) throws java.io.IOException; - } - - public final class NfcV implements android.nfc.tech.TagTechnology { - method public void close() throws java.io.IOException; - method public void connect() throws java.io.IOException; - method public static android.nfc.tech.NfcV get(android.nfc.Tag); - method public byte getDsfId(); - method public int getMaxTransceiveLength(); - method public byte getResponseFlags(); - method public android.nfc.Tag getTag(); - method public boolean isConnected(); - method public byte[] transceive(byte[]) throws java.io.IOException; - } - - public interface TagTechnology extends java.io.Closeable { - method public void connect() throws java.io.IOException; - method public android.nfc.Tag getTag(); - method public boolean isConnected(); - } - -} - package android.opengl { public class EGL14 { @@ -34032,6 +33598,7 @@ package android.os { field public static final String DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI = "no_sharing_admin_configured_wifi"; field public static final String DISALLOW_SMS = "no_sms"; field public static final String DISALLOW_SYSTEM_ERROR_DIALOGS = "no_system_error_dialogs"; + field @FlaggedApi("com.android.net.thread.flags.thread_user_restriction_enabled") public static final String DISALLOW_THREAD_NETWORK = "no_thread_network"; field public static final String DISALLOW_ULTRA_WIDEBAND_RADIO = "no_ultra_wideband_radio"; field public static final String DISALLOW_UNIFIED_PASSWORD = "no_unified_password"; field public static final String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps"; diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 91c082a1692d..2940ca10e55b 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -356,11 +356,6 @@ package android.net.wifi { package android.nfc { - public class NfcFrameworkInitializer { - method public static void registerServiceWrappers(); - method public static void setNfcServiceManager(@NonNull android.nfc.NfcServiceManager); - } - public class NfcServiceManager { method @NonNull public android.nfc.NfcServiceManager.ServiceRegisterer getNfcManagerServiceRegisterer(); } diff --git a/core/api/removed.txt b/core/api/removed.txt index 8b3696a1e6d9..1fa1e89fb46e 100644 --- a/core/api/removed.txt +++ b/core/api/removed.txt @@ -252,22 +252,6 @@ package android.net { } -package android.nfc { - - public final class NfcAdapter { - method @Deprecated public void disableForegroundNdefPush(android.app.Activity); - method @Deprecated public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage); - method @Deprecated public boolean invokeBeam(android.app.Activity); - method @Deprecated public boolean isNdefPushEnabled(); - method @Deprecated public void setBeamPushUris(android.net.Uri[], android.app.Activity); - method @Deprecated public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity); - method @Deprecated public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...); - method @Deprecated public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...); - method @Deprecated public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...); - } - -} - package android.os { public class BatteryManager { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 8eca0fe4b775..34c620f4a13c 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -10236,42 +10236,6 @@ package android.net.wifi.sharedconnectivity.service { } -package android.nfc { - - public final class NfcAdapter { - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean addNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler, String[]); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(boolean); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable(); - method @FlaggedApi("android.nfc.enable_nfc_reader_option") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableReaderOption(boolean); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean); - method @FlaggedApi("android.nfc.enable_nfc_mainline") public int getAdapterState(); - method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int); - method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn(); - method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported(); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagIntentAppPreferenceSupported(); - method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler); - method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean); - method @FlaggedApi("android.nfc.enable_nfc_mainline") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setReaderMode(boolean); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean); - method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener); - field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC = "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC"; - field public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff - field public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0; // 0x0 - field public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2; // 0xfffffffe - } - - public static interface NfcAdapter.ControllerAlwaysOnListener { - method public void onControllerAlwaysOnChanged(boolean); - } - - public static interface NfcAdapter.NfcUnlockHandler { - method public boolean onUnlockAttempted(android.nfc.Tag); - } - -} - package android.nfc.cardemulation { @FlaggedApi("android.nfc.enable_nfc_mainline") public final class AidGroup implements android.os.Parcelable { @@ -10320,10 +10284,6 @@ package android.nfc.cardemulation { field @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.ApduServiceInfo> CREATOR; } - public final class CardEmulation { - method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int); - } - @FlaggedApi("android.nfc.enable_nfc_mainline") public final class NfcFServiceInfo implements android.os.Parcelable { ctor @FlaggedApi("android.nfc.enable_nfc_mainline") public NfcFServiceInfo(@NonNull android.content.pm.PackageManager, @NonNull android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method @FlaggedApi("android.nfc.enable_nfc_mainline") public int describeContents(); diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt index 1e9e9be881d3..9eddab5423e5 100644 --- a/core/api/system-lint-baseline.txt +++ b/core/api/system-lint-baseline.txt @@ -173,16 +173,6 @@ SamShouldBeLast: android.media.session.MediaSessionManager#addOnActiveSessionsCh SAM-compatible parameters (such as parameter 1, "sessionListener", in android.media.session.MediaSessionManager.addOnActiveSessionsChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions SamShouldBeLast: android.media.session.MediaSessionManager#addOnSession2TokensChangedListener(android.media.session.MediaSessionManager.OnSession2TokensChangedListener, android.os.Handler): SAM-compatible parameters (such as parameter 1, "listener", in android.media.session.MediaSessionManager.addOnSession2TokensChangedListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions -SamShouldBeLast: android.nfc.NfcAdapter#enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle): - SAM-compatible parameters (such as parameter 2, "callback", in android.nfc.NfcAdapter.enableReaderMode) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions -SamShouldBeLast: android.nfc.NfcAdapter#ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler): - SAM-compatible parameters (such as parameter 3, "tagRemovedListener", in android.nfc.NfcAdapter.ignore) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions -SamShouldBeLast: android.nfc.NfcAdapter#setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity): - SAM-compatible parameters (such as parameter 1, "callback", in android.nfc.NfcAdapter.setBeamPushUrisCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions -SamShouldBeLast: android.nfc.NfcAdapter#setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...): - SAM-compatible parameters (such as parameter 1, "callback", in android.nfc.NfcAdapter.setNdefPushMessageCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions -SamShouldBeLast: android.nfc.NfcAdapter#setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...): - SAM-compatible parameters (such as parameter 1, "callback", in android.nfc.NfcAdapter.setOnNdefPushCompleteCallback) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions SamShouldBeLast: android.os.Binder#attachInterface(android.os.IInterface, String): SAM-compatible parameters (such as parameter 1, "owner", in android.os.Binder.attachInterface) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions SamShouldBeLast: android.os.Binder#linkToDeath(android.os.IBinder.DeathRecipient, int): diff --git a/core/api/system-removed.txt b/core/api/system-removed.txt index 1c10356c6b03..2c5acf182d51 100644 --- a/core/api/system-removed.txt +++ b/core/api/system-removed.txt @@ -140,17 +140,6 @@ package android.media.tv { } -package android.nfc { - - public final class NfcAdapter { - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush(); - method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush(); - method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int); - field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1 - } - -} - package android.os { public class Build { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index ab770afb078b..440257605e69 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2583,7 +2583,6 @@ package android.os.storage { method @NonNull public static String convert(@NonNull java.util.UUID); method @Nullable public String getCloudMediaProvider(); method public boolean isAppIoBlocked(@NonNull java.util.UUID, int, int, int); - method public static boolean isUserKeyUnlocked(int); field public static final String CACHE_RESERVE_PERCENT_HIGH_KEY = "cache_reserve_percent_high"; field public static final String CACHE_RESERVE_PERCENT_LOW_KEY = "cache_reserve_percent_low"; field public static final String STORAGE_THRESHOLD_PERCENT_HIGH_KEY = "storage_threshold_percent_high"; diff --git a/core/java/Android.bp b/core/java/Android.bp index d0b958ec6da5..0ad621d300ce 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -14,20 +14,12 @@ aidl_library { hdrs: ["android/hardware/HardwareBuffer.aidl"], } -// TODO (b/303286040): Remove this once |ENABLE_NFC_MAINLINE_FLAG| is rolled out -filegroup { - name: "framework-core-nfc-infcadapter-sources", - srcs: [ - "android/nfc/INfcAdapter.aidl", - ], - visibility: ["//frameworks/base/services/core"], -} - filegroup { name: "framework-core-sources", srcs: [ "**/*.java", "**/*.aidl", + ":framework-nfc-non-updatable-sources", ], visibility: ["//frameworks/base"], } diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index c072feb5b46e..10734782fba2 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -717,28 +717,28 @@ public class KeyguardManager { /** * Returns whether the device is currently locked for the user. * <p> - * This returns the device locked state for the {@link Context}'s user. If this user is the - * current user, then the device is considered "locked" when the lock screen is showing (i.e. - * {@link #isKeyguardLocked()} returns {@code true}) and is not trivially dismissible (e.g. with - * swipe), and the user has a PIN, pattern, or password. + * This method returns the device locked state for the {@link Context}'s user. The device is + * considered to be locked for a user when the user's apps are currently inaccessible and some + * form of lock screen authentication is required to regain access to them. The lock screen + * authentication typically uses PIN, pattern, password, or biometric. Some devices may support + * additional methods, such as unlock using a paired smartwatch. "Swipe" does not count as + * authentication; if the lock screen is dismissible with swipe, for example due to the lock + * screen being set to Swipe or due to the device being kept unlocked by being near a trusted + * bluetooth device or in a trusted location, the device is considered unlocked. + * <div class="note"> * <p> - * Note: the above definition implies that a user with no PIN, pattern, or password is never - * considered locked, even if the lock screen is showing and requesting a SIM card PIN. The - * device PIN and SIM PIN are separate. Also, the user is not considered locked if face - * authentication has just completed or a trust agent is keeping the device unlocked, since in - * these cases the lock screen is dismissible with swipe. + * <b>Note:</b> In the case of multiple full users, each user can have their own lock screen + * authentication configured. The device-locked state may differ between different users. For + * example, the device may be unlocked for the current user, but locked for a non-current user + * if lock screen authentication would be required to access that user's apps after switching to + * that user. * <p> - * For a user that is not the current user but can be switched to (usually this means "another - * full user"), and that has a PIN, pattern, or password, the device is always considered - * locked. - * <p> - * For a profile with a unified challenge, the device locked state is the same as that of the - * parent user. - * <p> - * For a profile with a separate challenge, the device becomes unlocked when the profile's PIN, - * pattern, password, or biometric is verified. It becomes locked when the parent user becomes - * locked, the screen turns off, the device reboots, the device policy controller locks the - * profile, or the timeout set by the device policy controller expires. + * In the case of a profile, when the device goes to the main lock screen, up to two layers of + * authentication may be required to regain access to the profile's apps: one to unlock the main + * lock screen, and one to unlock the profile (when a separate profile challenge is required). + * For a profile, the device is considered to be locked as long as any challenge remains, either + * the parent user's challenge (when applicable) or the profile's challenge (when applicable). + * </div> * * @return {@code true} if the device is currently locked for the user * @see #isKeyguardLocked() diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS index 27636f27fbc4..41d79329f4f2 100644 --- a/core/java/android/app/OWNERS +++ b/core/java/android/app/OWNERS @@ -82,8 +82,8 @@ per-file IInstantAppResolver.aidl = file:/services/core/java/com/android/server/ per-file InstantAppResolveInfo.aidl = file:/services/core/java/com/android/server/pm/OWNERS # BackgroundInstallControlManager -per-file BackgroundInstallControlManager.java = file:/services/core/java/com/android/server/pm/OWNERS -per-file background_install_control_manager.aconfig = file:/services/core/java/com/android/server/pm/OWNERS +per-file BackgroundInstallControlManager.java = file:/services/core/java/com/android/server/pm/BACKGROUND_INSTALL_OWNERS +per-file background_install_control_manager.aconfig = file:/services/core/java/com/android/server/pm/BACKGROUND_INSTALL_OWNERS # ResourcesManager per-file ResourcesManager.java = file:RESOURCES_OWNERS diff --git a/core/java/android/app/contextualsearch/OWNERS b/core/java/android/app/contextualsearch/OWNERS new file mode 100644 index 000000000000..0c2612c9957b --- /dev/null +++ b/core/java/android/app/contextualsearch/OWNERS @@ -0,0 +1 @@ +include /core/java/android/service/contextualsearch/OWNERS diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 2200af679531..c5356fe4f49b 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -182,7 +182,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * * @param context A Context object which should be some mock instance (like the * instance of {@link android.test.mock.MockContext}). - * @param readPermission The read permision you want this instance should have in the + * @param readPermission The read permission you want this instance should have in the * test, which is available via {@link #getReadPermission()}. * @param writePermission The write permission you want this instance should have * in the test, which is available via {@link #getWritePermission()}. diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index b2cd7e90f291..a97ca0abb7b4 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -387,7 +387,7 @@ public abstract class ContentResolver implements ContentInterface { * {@link Bundle} under {@link #EXTRA_HONORED_ARGS}. * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in * the arguments {@link Bundle}, the Content framework will attempt to - * synthesize an QUERY_ARG_SQL* argument using the corresponding + * synthesize a QUERY_ARG_SQL* argument using the corresponding * QUERY_ARG_SORT* values. */ public static final String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns"; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index c8ba47bbc1b2..1bc0418ef19c 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4276,6 +4276,10 @@ public abstract class PackageManager { * the Android Keystore backed by an isolated execution environment. The version indicates * which features are implemented in the isolated execution environment: * <ul> + * <li>300: Ability to include a second IMEI in the ID attestation record, see + * {@link android.app.admin.DevicePolicyManager#ID_TYPE_IMEI}. + * <li>200: Hardware support for Curve 25519 (including both Ed25519 signature generation and + * X25519 key agreement). * <li>100: Hardware support for ECDH (see {@link javax.crypto.KeyAgreement}) and support * for app-generated attestation keys (see {@link * android.security.keystore.KeyGenParameterSpec.Builder#setAttestKeyAlias(String)}). @@ -4305,6 +4309,11 @@ public abstract class PackageManager { * StrongBox</a>. If this feature has a version, the version number indicates which features are * implemented in StrongBox: * <ul> + * <li>300: Ability to include a second IMEI in the ID attestation record, see + * {@link android.app.admin.DevicePolicyManager#ID_TYPE_IMEI}. + * <li>200: No new features for StrongBox (the Android Keystore environment backed by an + * isolated execution environment has gained support for Curve 25519 in this version, but + * the implementation backed by a dedicated secure processor is not expected to implement it). * <li>100: Hardware support for ECDH (see {@link javax.crypto.KeyAgreement}) and support * for app-generated attestation keys (see {@link * android.security.keystore.KeyGenParameterSpec.Builder#setAttestKeyAlias(String)}). diff --git a/core/java/android/content/pm/verify/domain/OWNERS b/core/java/android/content/pm/verify/domain/OWNERS index c669112e0512..b451fe4b1077 100644 --- a/core/java/android/content/pm/verify/domain/OWNERS +++ b/core/java/android/content/pm/verify/domain/OWNERS @@ -1,5 +1,4 @@ # Bug component: 36137 +include /PACKAGE_MANAGER_OWNERS -chiuwinson@google.com -patb@google.com -toddke@google.com
\ No newline at end of file +wloh@google.com
\ No newline at end of file diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java index afa1c209c811..c00c18c14e56 100644 --- a/core/java/android/database/Cursor.java +++ b/core/java/android/database/Cursor.java @@ -510,7 +510,7 @@ public interface Cursor extends Closeable { Bundle getExtras(); /** - * This is an out-of-band way for the the user of a cursor to communicate with the cursor. The + * This is an out-of-band way for the user of a cursor to communicate with the cursor. The * structure of each bundle is entirely defined by the cursor. * * <p>One use of this is to tell a cursor that it should retry its network request after it diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 365f9130ddd7..594ec18d9996 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -16,6 +16,7 @@ package android.net; +import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; import static android.app.ActivityManager.procStateToString; import static android.content.pm.PackageManager.GET_SIGNATURES; @@ -170,6 +171,8 @@ public class NetworkPolicyManager { public static final String FIREWALL_CHAIN_NAME_RESTRICTED = "restricted"; /** @hide */ public static final String FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY = "low_power_standby"; + /** @hide */ + public static final String FIREWALL_CHAIN_NAME_BACKGROUND = "background"; private static final boolean ALLOW_PLATFORM_APP_POLICY = true; @@ -180,6 +183,9 @@ public class NetworkPolicyManager { /** @hide */ public static final int TOP_THRESHOLD_STATE = ActivityManager.PROCESS_STATE_BOUND_TOP; + /** @hide */ + public static final int BACKGROUND_THRESHOLD_STATE = ActivityManager.PROCESS_STATE_TOP_SLEEPING; + /** * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it * applies to. @@ -264,6 +270,16 @@ public class NetworkPolicyManager { * @hide */ public static final int ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST = 1 << 6; + + /** + * Flag to indicate that the app is exempt from always-on background network restrictions. + * Note that this is explicitly different to the flag NOT_FOREGROUND which is used to grant + * shared exception to apps from power restrictions like doze, battery saver and app-standby. + * + * @hide + */ + public static final int ALLOWED_REASON_NOT_IN_BACKGROUND = 1 << 7; + /** * Flag to indicate that app is exempt from certain metered network restrictions because user * explicitly exempted it. @@ -822,6 +838,21 @@ public class NetworkPolicyManager { } /** + * This is currently only used as an implementation detail for + * {@link com.android.server.net.NetworkPolicyManagerService}. + * Only put here to be together with other isProcStateAllowed* methods. + * + * @hide + */ + public static boolean isProcStateAllowedNetworkWhileBackground(@Nullable UidState uidState) { + if (uidState == null) { + return false; + } + return uidState.procState < BACKGROUND_THRESHOLD_STATE + || (uidState.capability & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0; + } + + /** * Returns true if {@param procState} is considered foreground and as such will be allowed * to access network when the device is in data saver mode. Otherwise, false. * @hide diff --git a/core/java/android/net/thread/OWNERS b/core/java/android/net/thread/OWNERS new file mode 100644 index 000000000000..55c307b5eb62 --- /dev/null +++ b/core/java/android/net/thread/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 1203089 + +include platform/packages/modules/ThreadNetwork:/OWNERS diff --git a/core/java/android/net/thread/flags.aconfig b/core/java/android/net/thread/flags.aconfig new file mode 100644 index 000000000000..6e72f8ebd8d1 --- /dev/null +++ b/core/java/android/net/thread/flags.aconfig @@ -0,0 +1,8 @@ +package: "com.android.net.thread.flags" + +flag { + name: "thread_user_restriction_enabled" + namespace: "thread_network" + description: "Controls whether user restriction on thread networks is enabled" + bug: "307679182" +} diff --git a/core/java/android/nfc/TEST_MAPPING b/core/java/android/nfc/TEST_MAPPING deleted file mode 100644 index 5b5ea3790010..000000000000 --- a/core/java/android/nfc/TEST_MAPPING +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presubmit": [ - { - "name": "NfcManagerTests" - }, - { - "name": "CtsNfcTestCases" - } - ] -} diff --git a/core/java/android/nfc/tech/OWNERS b/core/java/android/nfc/tech/OWNERS deleted file mode 100644 index 35e9713f5715..000000000000 --- a/core/java/android/nfc/tech/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# Bug component: 48448 -include platform/packages/apps/Nfc:/OWNERS diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 9b77b798facf..bccea93d150d 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -1471,7 +1471,15 @@ public class Process { @UnsupportedAppUsage public static final native long getPss(int pid); - /** @hide */ + /** + * Gets the total Rss value for a given process, in bytes. + * + * @param pid the process to the Rss for + * @return an ordered array containing multiple values, they are: + * [total_rss, file, anon, swap, shmem]. + * or NULL if the value cannot be determined + * @hide + */ public static final native long[] getRss(int pid); /** diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 97b53d781083..cdef20afb11d 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1847,6 +1847,30 @@ public class UserManager { "no_near_field_communication_radio"; /** + * This user restriction specifies if Thread network is disallowed on the device. If Thread + * network is disallowed it cannot be turned on via Settings. + * + * <p>This restriction can only be set by a device owner or a profile owner of an + * organization-owned managed profile on the parent profile. + * In both cases, the restriction applies globally on the device and will turn off the + * Thread network radio if it's currently on and prevent the radio from being turned + * on in the future. + * + * <p> <a href="https://www.threadgroup.org">Thread</a> is a low-power and low-latency wireless + * mesh networking protocol built on IPv6. + * + * <p>Default is <code>false</code>. + * + * <p>Key for user restrictions. + * <p>Type: Boolean + * @see DevicePolicyManager#addUserRestriction(ComponentName, String) + * @see DevicePolicyManager#clearUserRestriction(ComponentName, String) + * @see #getUserRestrictions() + */ + @FlaggedApi("com.android.net.thread.flags.thread_user_restriction_enabled") + public static final String DISALLOW_THREAD_NETWORK = "no_thread_network"; + + /** * List of key values that can be passed into the various user restriction related methods * in {@link UserManager} & {@link DevicePolicyManager}. * Note: This is slightly different from the real set of user restrictions listed in {@link @@ -1931,6 +1955,7 @@ public class UserManager { DISALLOW_ULTRA_WIDEBAND_RADIO, DISALLOW_GRANT_ADMIN, DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO, + DISALLOW_THREAD_NETWORK, }) @Retention(RetentionPolicy.SOURCE) public @interface UserRestrictionKey {} diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 3cb5c60259eb..c0539d6845a1 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -71,7 +71,7 @@ import java.util.UUID; */ public class ZygoteProcess { - private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000; + private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 60000; /** * Use a relatively short delay, because for app zygote, this is in the critical path of diff --git a/core/java/android/os/incremental/OWNERS b/core/java/android/os/incremental/OWNERS index 47eee6406206..a925564fbbb6 100644 --- a/core/java/android/os/incremental/OWNERS +++ b/core/java/android/os/incremental/OWNERS @@ -1,6 +1,4 @@ # Bug component: 554432 -alexbuy@google.com -schfan@google.com -toddke@google.com +include /PACKAGE_MANAGER_OWNERS + zyy@google.com -patb@google.com diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index eb1db3eaa06e..4c3f330ab4f3 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -1669,12 +1669,6 @@ public class StorageManager { } } - /** {@hide} */ - @TestApi - public static boolean isUserKeyUnlocked(int userId) { - return isCeStorageUnlocked(userId); - } - /** * Returns true if the user's credential-encrypted (CE) storage is unlocked. * diff --git a/core/java/android/security/OWNERS b/core/java/android/security/OWNERS index 533d459e532b..8bd6c858be7c 100644 --- a/core/java/android/security/OWNERS +++ b/core/java/android/security/OWNERS @@ -1,7 +1,7 @@ # Bug component: 36824 brambonne@google.com -brufino@google.com +eranm@google.com jeffv@google.com per-file *NetworkSecurityPolicy.java = file:net/OWNERS diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index 1994058441d5..43163b3b9051 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -58,3 +58,10 @@ flag { bug: "290312729" is_fixed_read_only: true } + +flag { + name: "report_primary_auth_attempts" + namespace: "biometrics" + description: "Report primary auth attempts from LockSettingsService" + bug: "285053096" +} diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig index fe6c4a4321e9..0bae459fefc3 100644 --- a/core/java/android/security/responsible_apis_flags.aconfig +++ b/core/java/android/security/responsible_apis_flags.aconfig @@ -27,3 +27,17 @@ flag { description: "Enables the content URI permission APIs" bug: "293467489" } + +flag { + name: "enforce_intent_filter_match" + namespace: "responsible_apis" + description: "Make delivered intents match components' intent filters" + bug: "293560872" +} + +flag { + name: "block_null_action_intents" + namespace: "responsible_apis" + description: "Do not allow intents without an action to match any intent filters" + bug: "293560872" +} diff --git a/core/java/android/service/contextualsearch/OWNERS b/core/java/android/service/contextualsearch/OWNERS new file mode 100644 index 000000000000..463adf48dd3e --- /dev/null +++ b/core/java/android/service/contextualsearch/OWNERS @@ -0,0 +1,3 @@ +srazdan@google.com +volnov@google.com +hackz@google.com diff --git a/core/java/android/view/MotionPredictor.java b/core/java/android/view/MotionPredictor.java index 27af3000fc8b..db2efaa81ef3 100644 --- a/core/java/android/view/MotionPredictor.java +++ b/core/java/android/view/MotionPredictor.java @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import com.android.internal.annotations.VisibleForTesting; + import libcore.util.NativeAllocationRegistry; /** @@ -57,11 +59,21 @@ public final class MotionPredictor { * @param context The context for the predictions */ public MotionPredictor(@NonNull Context context) { - mIsPredictionEnabled = context.getResources().getBoolean( - com.android.internal.R.bool.config_enableMotionPrediction); - final int offsetNanos = context.getResources().getInteger( - com.android.internal.R.integer.config_motionPredictionOffsetNanos); - mPtr = nativeInitialize(offsetNanos); + this( + context.getResources().getBoolean( + com.android.internal.R.bool.config_enableMotionPrediction), + context.getResources().getInteger( + com.android.internal.R.integer.config_motionPredictionOffsetNanos)); + } + + /** + * Internal constructor for testing. + * @hide + */ + @VisibleForTesting + public MotionPredictor(boolean isPredictionEnabled, int motionPredictionOffsetNanos) { + mIsPredictionEnabled = isPredictionEnabled; + mPtr = nativeInitialize(motionPredictionOffsetNanos); RegistryHolder.REGISTRY.registerNativeAllocation(this, mPtr); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 6ad1960cbda9..2bc584a8301e 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -423,12 +423,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te int mMotionViewNewTop; /** - * The X value associated with the the down motion event + * The X value associated with the down motion event */ int mMotionX; /** - * The Y value associated with the the down motion event + * The Y value associated with the down motion event */ @UnsupportedAppUsage int mMotionY; @@ -7346,7 +7346,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te scrap.dispatchStartTemporaryDetach(); - // The the accessibility state of the view may change while temporary + // the accessibility state of the view may change while temporary // detached and we do not allow detached views to fire accessibility // events. So we are announcing that the subtree changed giving a chance // to clients holding on to a view in this subtree to refresh it. @@ -7715,7 +7715,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } /** - * Abstract positon scroller used to handle smooth scrolling. + * Abstract position scroller used to handle smooth scrolling. */ static abstract class AbsPositionScroller { public abstract void start(int position); diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java index 76e97ad7a0f6..3b7e1e91f839 100644 --- a/core/java/android/widget/AbsSpinner.java +++ b/core/java/android/widget/AbsSpinner.java @@ -170,7 +170,7 @@ public abstract class AbsSpinner extends AdapterView<SpinnerAdapter> { * @see android.view.View#measure(int, int) * * Figure out the dimensions of this Spinner. The width comes from - * the widthMeasureSpec as Spinnners can't have their width set to + * the widthMeasureSpec as Spinners can't have their width set to * UNSPECIFIED. The height is based on the height of the selected item * plus padding. */ diff --git a/core/java/android/widget/OWNERS b/core/java/android/widget/OWNERS index e20357fa2dd9..1dc90edbd1e5 100644 --- a/core/java/android/widget/OWNERS +++ b/core/java/android/widget/OWNERS @@ -15,3 +15,5 @@ per-file SpellChecker.java = file:../view/inputmethod/OWNERS per-file Remote* = file:../appwidget/OWNERS per-file Toast.java = juliacr@google.com, jeffdq@google.com + +per-file flags/notification_widget_flags.aconfig = juliacr@google.com, jeffdq@google.com diff --git a/core/java/com/android/internal/widget/ILockSettingsStateListener.aidl b/core/java/com/android/internal/widget/ILockSettingsStateListener.aidl new file mode 100644 index 000000000000..25e30034fe8f --- /dev/null +++ b/core/java/com/android/internal/widget/ILockSettingsStateListener.aidl @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 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.internal.widget; + +/** + * Callback interface between LockSettingService and other system services to be notified about the + * state of primary authentication (i.e. PIN/pattern/password). + * @hide + */ +oneway interface ILockSettingsStateListener { + /** + * Defines behavior in response to a successful authentication + * @param userId The user Id for the requested authentication + */ + void onAuthenticationSucceeded(int userId); + + /** + * Defines behavior in response to a failed authentication + * @param userId The user Id for the requested authentication + */ + void onAuthenticationFailed(int userId); +}
\ No newline at end of file diff --git a/core/java/com/android/internal/widget/LockSettingsInternal.java b/core/java/com/android/internal/widget/LockSettingsInternal.java index 8114e1fd3bb0..627e8779f9d0 100644 --- a/core/java/com/android/internal/widget/LockSettingsInternal.java +++ b/core/java/com/android/internal/widget/LockSettingsInternal.java @@ -166,4 +166,16 @@ public abstract class LockSettingsInternal { * Refreshes pending strong auth timeout with the latest admin requirement set by device policy. */ public abstract void refreshStrongAuthTimeout(int userId); + + /** + * Register a LockSettingsStateListener + * @param listener The listener to be registered + */ + public abstract void registerLockSettingsStateListener(ILockSettingsStateListener listener); + + /** + * Unregister a LockSettingsStateListener + * @param listener The listener to be unregistered + */ + public abstract void unregisterLockSettingsStateListener(ILockSettingsStateListener listener); } diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp index 2f29cae42d07..917d28348d04 100644 --- a/core/jni/android_opengl_EGL14.cpp +++ b/core/jni/android_opengl_EGL14.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" diff --git a/core/jni/android_opengl_EGL15.cpp b/core/jni/android_opengl_EGL15.cpp index b9c36b9ed9aa..447b8ec58ca7 100644 --- a/core/jni/android_opengl_EGL15.cpp +++ b/core/jni/android_opengl_EGL15.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" diff --git a/core/jni/android_opengl_EGLExt.cpp b/core/jni/android_opengl_EGLExt.cpp index cdc985273472..ffd75ea053d5 100644 --- a/core/jni/android_opengl_EGLExt.cpp +++ b/core/jni/android_opengl_EGLExt.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" @@ -54,11 +55,11 @@ nativeClassInit(JNIEnv *_env, jclass glImplClass) jclass eglsurfaceClassLocal = _env->FindClass("android/opengl/EGLSurface"); eglsurfaceClass = (jclass) _env->NewGlobalRef(eglsurfaceClassLocal); jclass eglsyncClassLocal = _env->FindClass("android/opengl/EGLSync"); - eglsyncClass = (jclass)_env->NewGlobalRef(eglsyncClassLocal); + eglsyncClass = (jclass) _env->NewGlobalRef(eglsyncClassLocal); egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getNativeHandle", "()J"); eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getNativeHandle", "()J"); - eglsyncGetHandleID = _env->GetMethodID(eglsyncClassLocal, "getNativeHandle", "()J"); + eglsyncGetHandleID = _env->GetMethodID(eglsyncClass, "getNativeHandle", "()J"); } static void * @@ -72,6 +73,14 @@ fromEGLHandle(JNIEnv *_env, jmethodID mid, jobject obj) { return reinterpret_cast<void*>(_env->CallLongMethod(obj, mid)); } +// TODO: this should be generated from the .spec file, but needs to be renamed and made private +static jint android_eglDupNativeFenceFDANDROID(JNIEnv *env, jobject, jobject dpy, jobject sync) { + EGLDisplay dpy_native = (EGLDisplay)fromEGLHandle(env, egldisplayGetHandleID, dpy); + EGLSync sync_native = (EGLSync)fromEGLHandle(env, eglsyncGetHandleID, sync); + + return eglDupNativeFenceFDANDROID(dpy_native, sync_native); +} + // -------------------------------------------------------------------------- /* EGLBoolean eglPresentationTimeANDROID ( EGLDisplay dpy, EGLSurface sur, EGLnsecsANDROID time ) */ static jboolean @@ -89,21 +98,12 @@ android_eglPresentationTimeANDROID return (jboolean)_returnValue; } -static jint android_eglDupNativeFenceFDANDROID(JNIEnv *env, jobject, jobject dpy, jobject sync) { - EGLDisplay dpy_native = (EGLDisplay)fromEGLHandle(env, egldisplayGetHandleID, dpy); - EGLSync sync_native = (EGLSync)fromEGLHandle(env, eglsyncGetHandleID, sync); - - return eglDupNativeFenceFDANDROID(dpy_native, sync_native); -} - static const char *classPathName = "android/opengl/EGLExt"; static const JNINativeMethod methods[] = { - {"_nativeClassInit", "()V", (void *)nativeClassInit}, - {"eglPresentationTimeANDROID", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;J)Z", - (void *)android_eglPresentationTimeANDROID}, - {"eglDupNativeFenceFDANDROIDImpl", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;)I", - (void *)android_eglDupNativeFenceFDANDROID}, +{"_nativeClassInit", "()V", (void*)nativeClassInit }, +{"eglPresentationTimeANDROID", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSurface;J)Z", (void *) android_eglPresentationTimeANDROID }, +{"eglDupNativeFenceFDANDROIDImpl", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;)I", (void *)android_eglDupNativeFenceFDANDROID }, }; int register_android_opengl_jni_EGLExt(JNIEnv *_env) diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp index d65b498404fa..2d921ad59458 100644 --- a/core/jni/android_opengl_GLES10.cpp +++ b/core/jni/android_opengl_GLES10.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES/gl.h> diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp index 3638b87e201f..35a9a68cd8ab 100644 --- a/core/jni/android_opengl_GLES10Ext.cpp +++ b/core/jni/android_opengl_GLES10Ext.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES/gl.h> diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp index 9724e6c2a5dd..e04b56e5fa44 100644 --- a/core/jni/android_opengl_GLES11.cpp +++ b/core/jni/android_opengl_GLES11.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES/gl.h> diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp index 1ffa4ec67ae1..bccbda6d3f08 100644 --- a/core/jni/android_opengl_GLES11Ext.cpp +++ b/core/jni/android_opengl_GLES11Ext.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES/gl.h> diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp index d832558aa368..165262e0893d 100644 --- a/core/jni/android_opengl_GLES20.cpp +++ b/core/jni/android_opengl_GLES20.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES2/gl2.h> diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp index 719c6b32fec6..d3fe439eafb7 100644 --- a/core/jni/android_opengl_GLES30.cpp +++ b/core/jni/android_opengl_GLES30.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES3/gl3.h> diff --git a/core/jni/android_opengl_GLES31.cpp b/core/jni/android_opengl_GLES31.cpp index afe7c63b6d47..b123f9d403df 100644 --- a/core/jni/android_opengl_GLES31.cpp +++ b/core/jni/android_opengl_GLES31.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <stdint.h> diff --git a/core/jni/android_opengl_GLES31Ext.cpp b/core/jni/android_opengl_GLES31Ext.cpp index 81274331ffa4..1e4049b8671d 100644 --- a/core/jni/android_opengl_GLES31Ext.cpp +++ b/core/jni/android_opengl_GLES31Ext.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <GLES3/gl31.h> diff --git a/core/jni/android_opengl_GLES32.cpp b/core/jni/android_opengl_GLES32.cpp index 7ed754850ea3..e0175f079ab7 100644 --- a/core/jni/android_opengl_GLES32.cpp +++ b/core/jni/android_opengl_GLES32.cpp @@ -17,6 +17,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include <stdint.h> diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 7af69f2dff08..d2e58bb62c46 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -28,6 +28,7 @@ #include <meminfo/sysmeminfo.h> #include <processgroup/processgroup.h> #include <processgroup/sched_policy.h> +#include <android-base/logging.h> #include <android-base/unique_fd.h> #include <algorithm> @@ -232,6 +233,31 @@ void android_os_Process_setThreadGroupAndCpuset(JNIEnv* env, jobject clazz, int } } +// Look up the user ID of a process in /proc/${pid}/status. The Uid: line is present in +// /proc/${pid}/status since at least kernel v2.5. +static int uid_from_pid(int pid) +{ + int uid = -1; + std::array<char, 64> path; + int res = snprintf(path.data(), path.size(), "/proc/%d/status", pid); + if (res < 0 || res >= static_cast<int>(path.size())) { + DCHECK(false); + return uid; + } + FILE* f = fopen(path.data(), "r"); + if (!f) { + return uid; + } + char line[256]; + while (fgets(line, sizeof(line), f)) { + if (sscanf(line, "Uid: %d", &uid) == 1) { + break; + } + } + fclose(f); + return uid; +} + void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp) { ALOGV("%s pid=%d grp=%" PRId32, __func__, pid, grp); @@ -275,7 +301,12 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin } } - if (!SetProcessProfilesCached(0, pid, {get_cpuset_policy_profile_name((SchedPolicy)grp)})) + const int uid = uid_from_pid(pid); + if (uid < 0) { + signalExceptionForGroupError(env, ESRCH, pid); + return; + } + if (!SetProcessProfilesCached(uid, pid, {get_cpuset_policy_profile_name((SchedPolicy)grp)})) signalExceptionForGroupError(env, errno ? errno : EPERM, pid); } @@ -1134,12 +1165,11 @@ static jlong android_os_Process_getPss(JNIEnv* env, jobject clazz, jint pid) static jlongArray android_os_Process_getRss(JNIEnv* env, jobject clazz, jint pid) { - // total, file, anon, swap - jlong rss[4] = {0, 0, 0, 0}; + // total, file, anon, swap, shmem + jlong rss[5] = {0, 0, 0, 0, 0}; std::string status_path = android::base::StringPrintf("/proc/%d/status", pid); UniqueFile file = MakeUniqueFile(status_path.c_str(), "re"); - char line[256]; while (file != nullptr && fgets(line, sizeof(line), file.get())) { jlong v; @@ -1151,17 +1181,18 @@ static jlongArray android_os_Process_getRss(JNIEnv* env, jobject clazz, jint pid rss[2] = v; } else if ( sscanf(line, "VmSwap: %" SCNd64 " kB", &v) == 1) { rss[3] = v; + } else if ( sscanf(line, "RssShmem: %" SCNd64 " kB", &v) == 1) { + rss[4] = v; } } - jlongArray rssArray = env->NewLongArray(4); + jlongArray rssArray = env->NewLongArray(5); if (rssArray == NULL) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); return NULL; } - env->SetLongArrayRegion(rssArray, 0, 4, rss); - + env->SetLongArrayRegion(rssArray, 0, 5, rss); return rssArray; } diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp index 21de72397384..ef29c880a8a1 100644 --- a/core/jni/com_google_android_gles_jni_GLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp @@ -18,6 +18,7 @@ // This source file is automatically generated #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" diff --git a/core/proto/OWNERS b/core/proto/OWNERS index a854e3626e78..381580b7628e 100644 --- a/core/proto/OWNERS +++ b/core/proto/OWNERS @@ -13,7 +13,7 @@ ogunwale@google.com jjaggi@google.com kwekua@google.com roosa@google.com -per-file package_item_info.proto = toddke@google.com,patb@google.com +per-file package_item_info.proto = file:/PACKAGE_MANAGER_OWNERS per-file usagestatsservice.proto, usagestatsservice_v2.proto = file:/core/java/android/app/usage/OWNERS per-file apphibernationservice.proto = file:/core/java/android/apphibernation/OWNERS per-file android/hardware/sensorprivacy.proto = ntmyren@google.com,evanseverson@google.com diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index 3a2e50aa06e8..9bb249999d99 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -34,7 +34,7 @@ http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ --> <!-- Arab Emirates --> - <shortcode country="ae" pattern="\\d{1,5}" free="1017|1355|3214" /> + <shortcode country="ae" pattern="\\d{1,5}" free="1017|1355|3214|6253" /> <!-- Albania: 5 digits, known short codes listed --> <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" /> @@ -86,7 +86,7 @@ <shortcode country="cn" premium="1066.*" free="1065.*" /> <!-- Colombia: 1-6 digits (not confirmed) --> - <shortcode country="co" pattern="\\d{1,6}" free="890350|908160|892255|898002|898880|899960|899948|87739|85517" /> + <shortcode country="co" pattern="\\d{1,6}" free="890350|908160|892255|898002|898880|899960|899948|87739|85517|491289" /> <!-- Cyprus: 4-6 digits (not confirmed), known premium codes listed, plus EU --> <shortcode country="cy" pattern="\\d{4,6}" premium="7510" free="116\\d{3}" /> @@ -104,6 +104,12 @@ <!-- Denmark: see http://iprs.webspacecommerce.com/Denmark-Premium-Rate-Numbers --> <shortcode country="dk" pattern="\\d{4,5}" premium="1\\d{3}" free="116\\d{3}|4665" /> + <!-- Dominican Republic: 1-6 digits (standard system default, not country specific) --> + <shortcode country="do" pattern="\\d{1,6}" free="912892" /> + + <!-- Ecuador: 1-6 digits (standard system default, not country specific) --> + <shortcode country="ec" pattern="\\d{1,6}" free="466453" /> + <!-- Estonia: short codes 3-5 digits starting with 1, plus premium 7 digit numbers starting with 90, plus EU. http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht --> <shortcode country="ee" pattern="1\\d{2,4}" premium="90\\d{5}|15330|1701[0-3]" free="116\\d{3}|95034" /> @@ -154,8 +160,8 @@ http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf --> <shortcode country="ie" pattern="\\d{5}" premium="5[3-9]\\d{3}" free="50\\d{3}|116\\d{3}" standard="5[12]\\d{3}" /> - <!-- Israel: 4 digits, known premium codes listed --> - <shortcode country="il" pattern="\\d{4}" premium="4422|4545" /> + <!-- Israel: 1-5 digits, known premium codes listed --> + <shortcode country="il" pattern="\\d{1,5}" premium="4422|4545" free="37477|6681" /> <!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU: https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf --> @@ -193,11 +199,14 @@ <shortcode country="mk" pattern="\\d{1,6}" free="129005|122" /> <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed --> - <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963|91101|45453" /> + <shortcode country="mx" pattern="\\d{4,6}" premium="53035|7766" free="26259|46645|50025|50052|5050|76551|88778|9963|91101|45453|550346" /> <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf --> <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288|66668" /> + <!-- Namibia: 1-5 digits (standard system default, not country specific) --> + <shortcode country="na" pattern="\\d{1,5}" free="40005" /> + <!-- The Netherlands, 4 digits, known premium codes listed, plus EU --> <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223|1662" /> diff --git a/core/tests/nfctests/OWNERS b/core/tests/nfctests/OWNERS deleted file mode 100644 index 34b095c7fda0..000000000000 --- a/core/tests/nfctests/OWNERS +++ /dev/null @@ -1 +0,0 @@ -include /core/java/android/nfc/OWNERS diff --git a/data/etc/OWNERS b/data/etc/OWNERS index ea23aba16d12..245f21658b7a 100644 --- a/data/etc/OWNERS +++ b/data/etc/OWNERS @@ -1,3 +1,5 @@ +include /PACKAGE_MANAGER_OWNERS + alanstokes@google.com cbrubaker@google.com hackbod@android.com @@ -6,11 +8,6 @@ jeffv@google.com jsharkey@android.com jsharkey@google.com lorenzo@google.com -svetoslavganov@android.com -svetoslavganov@google.com -toddke@android.com -toddke@google.com -patb@google.com yamasani@google.com per-file preinstalled-packages* = file:/MULTIUSER_OWNERS diff --git a/data/fonts/Android.bp b/data/fonts/Android.bp index 3dd9ba9db1d9..f403b4f5353a 100644 --- a/data/fonts/Android.bp +++ b/data/fonts/Android.bp @@ -57,3 +57,9 @@ prebuilt_etc { name: "font_fallback.xml", src: "font_fallback.xml", } + +///////////////////////////////// +// Move `fontchain_lint` to `core/tasks/fontchain_lint.mk`. +// Because `system.img` is a dependency of `fontchain_lint`, it cannot be +// converted to Android.bp for now. +// After system.img can be generated by Soong, then it can be converted to Android.bp. diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk deleted file mode 100644 index a322b829932b..000000000000 --- a/data/fonts/Android.mk +++ /dev/null @@ -1,45 +0,0 @@ -# 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. - -LOCAL_PATH := $(call my-dir) - -# Run sanity tests on fonts on checkbuild -checkbuild: fontchain_lint - -FONTCHAIN_LINTER := $(HOST_OUT_EXECUTABLES)/fontchain_linter -ifeq ($(MINIMAL_FONT_FOOTPRINT),true) -CHECK_EMOJI := false -else -CHECK_EMOJI := true -endif - -fontchain_lint_timestamp := $(call intermediates-dir-for,PACKAGING,fontchain_lint)/stamp - -.PHONY: fontchain_lint -fontchain_lint: $(fontchain_lint_timestamp) - -fontchain_lint_deps := \ - external/unicode/DerivedAge.txt \ - external/unicode/emoji-data.txt \ - external/unicode/emoji-sequences.txt \ - external/unicode/emoji-variation-sequences.txt \ - external/unicode/emoji-zwj-sequences.txt \ - external/unicode/additions/emoji-data.txt \ - external/unicode/additions/emoji-sequences.txt \ - external/unicode/additions/emoji-zwj-sequences.txt \ - -$(fontchain_lint_timestamp): $(FONTCHAIN_LINTER) $(TARGET_OUT)/etc/fonts.xml $(PRODUCT_OUT)/system.img $(fontchain_lint_deps) - @echo Running fontchain lint - $(FONTCHAIN_LINTER) $(TARGET_OUT) $(CHECK_EMOJI) external/unicode - touch $@ diff --git a/keystore/java/android/security/AndroidProtectedConfirmation.java b/keystore/java/android/security/AndroidProtectedConfirmation.java index dfe485ac8274..268e0a54053b 100644 --- a/keystore/java/android/security/AndroidProtectedConfirmation.java +++ b/keystore/java/android/security/AndroidProtectedConfirmation.java @@ -59,6 +59,10 @@ public class AndroidProtectedConfirmation { /** * Requests keystore call into the confirmationui HAL to display a prompt. + * @deprecated Android Protected Confirmation had a low adoption rate among Android device + * makers and developers alike. Given the lack of devices supporting the + * feature, it is deprecated. Developers can use auth-bound Keystore keys + * as a partial replacement. * * @param listener the binder to use for callbacks. * @param promptText the prompt to display. @@ -68,6 +72,7 @@ public class AndroidProtectedConfirmation { * @return one of the {@code CONFIRMATIONUI_*} constants, for * example {@code KeyStore.CONFIRMATIONUI_OK}. */ + @Deprecated public int presentConfirmationPrompt(IConfirmationCallback listener, String promptText, byte[] extraData, String locale, int uiOptionsAsFlags) { try { @@ -84,11 +89,16 @@ public class AndroidProtectedConfirmation { /** * Requests keystore call into the confirmationui HAL to cancel displaying a prompt. + * @deprecated Android Protected Confirmation had a low adoption rate among Android device + * makers and developers alike. Given the lack of devices supporting the + * feature, it is deprecated. Developers can use auth-bound Keystore keys + * as a partial replacement. * * @param listener the binder passed to the {@link #presentConfirmationPrompt} method. * @return one of the {@code CONFIRMATIONUI_*} constants, for * example {@code KeyStore.CONFIRMATIONUI_OK}. */ + @Deprecated public int cancelConfirmationPrompt(IConfirmationCallback listener) { try { getService().cancelPrompt(listener); @@ -103,9 +113,14 @@ public class AndroidProtectedConfirmation { /** * Requests keystore to check if the confirmationui HAL is available. + * @deprecated Android Protected Confirmation had a low adoption rate among Android device + * makers and developers alike. Given the lack of devices supporting the + * feature, it is deprecated. Developers can use auth-bound Keystore keys + * as a partial replacement. * * @return whether the confirmationUI HAL is available. */ + @Deprecated public boolean isConfirmationPromptSupported() { try { return getService().isSupported(); diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java index 9c05a3a768a0..83ddfc5cf1a1 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -109,13 +109,29 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } } + // For curve 25519, KeyMint uses the KM_ALGORITHM_EC constant, but in the Java layer we need + // to distinguish between Curve 25519 and other EC algorithms, so we use a different constant + // with a value that is outside the range of the enum used for KeyMint algorithms. + private static final int ALGORITHM_XDH = KeymasterDefs.KM_ALGORITHM_EC + 1200; + private static final int ALGORITHM_ED25519 = ALGORITHM_XDH + 1; + /** - * XDH represents Curve 25519 providers. + * XDH represents Curve 25519 agreement key provider. */ public static class XDH extends AndroidKeyStoreKeyPairGeneratorSpi { // XDH is treated as EC. public XDH() { - super(KeymasterDefs.KM_ALGORITHM_EC); + super(ALGORITHM_XDH); + } + } + + /** + * ED25519 represents Curve 25519 signing key provider. + */ + public static class ED25519 extends AndroidKeyStoreKeyPairGeneratorSpi { + // ED25519 is treated as EC. + public ED25519() { + super(ALGORITHM_ED25519); } } @@ -241,7 +257,9 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato KeyGenParameterSpec spec; boolean encryptionAtRestRequired = false; - int keymasterAlgorithm = mOriginalKeymasterAlgorithm; + int keymasterAlgorithm = (mOriginalKeymasterAlgorithm == ALGORITHM_XDH + || mOriginalKeymasterAlgorithm == ALGORITHM_ED25519) + ? KeymasterDefs.KM_ALGORITHM_EC : mOriginalKeymasterAlgorithm; if (params instanceof KeyGenParameterSpec) { spec = (KeyGenParameterSpec) params; } else if (params instanceof KeyPairGeneratorSpec) { @@ -610,6 +628,15 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato if (algSpecificSpec instanceof ECGenParameterSpec) { ECGenParameterSpec ecSpec = (ECGenParameterSpec) algSpecificSpec; mEcCurveName = ecSpec.getName(); + if (mOriginalKeymasterAlgorithm == ALGORITHM_XDH + && !mEcCurveName.equalsIgnoreCase("x25519")) { + throw new InvalidAlgorithmParameterException("XDH algorithm only supports" + + " x25519 curve."); + } else if (mOriginalKeymasterAlgorithm == ALGORITHM_ED25519 + && !mEcCurveName.equalsIgnoreCase("ed25519")) { + throw new InvalidAlgorithmParameterException("Ed25519 algorithm only" + + " supports ed25519 curve."); + } final Integer ecSpecKeySizeBits = SUPPORTED_EC_CURVE_NAME_TO_SIZE.get( mEcCurveName.toLowerCase(Locale.US)); if (ecSpecKeySizeBits == null) { diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java index 11278e84ceaa..d204f13d4d78 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java @@ -86,11 +86,14 @@ public class AndroidKeyStoreProvider extends Provider { put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$EC"); put("KeyPairGenerator.RSA", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA"); put("KeyPairGenerator.XDH", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$XDH"); + put("KeyPairGenerator.ED25519", PACKAGE_NAME + + ".AndroidKeyStoreKeyPairGeneratorSpi$ED25519"); // java.security.KeyFactory putKeyFactoryImpl("EC"); putKeyFactoryImpl("RSA"); putKeyFactoryImpl("XDH"); + putKeyFactoryImpl("ED25519"); // javax.crypto.KeyGenerator put("KeyGenerator.AES", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$AES"); diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index bb628469d73b..e0ccf17c9fb7 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -210,15 +210,6 @@ filegroup { path: "apex/java", } -java_api_contribution { - name: "framework-graphics-public-stubs", - api_surface: "public", - api_file: "api/current.txt", - visibility: [ - "//build/orchestrator/apis", - ], -} - // ------------------------ // APEX // ------------------------ diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 1dd22cf43c5c..a733d1772757 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -218,7 +218,7 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { * stencil buffer may be needed. Views that use a functor to draw will be forced onto a layer. */ void RenderNode::prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer) { - if (mDamageGenerationId == info.damageGenerationId) { + if (mDamageGenerationId == info.damageGenerationId && mDamageGenerationId != 0) { // We hit the same node a second time in the same tree. We don't know the minimal // damage rect anymore, so just push the biggest we can onto our parent's transform // We push directly onto parent in case we are clipped to bounds but have moved position. diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index 572635a9bd45..4d03bf189a84 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -263,7 +263,7 @@ private: DisplayList mDisplayList; DisplayList mStagingDisplayList; - int64_t mDamageGenerationId; + int64_t mDamageGenerationId = 0; friend class AnimatorManager; AnimatorManager mAnimatorManager; diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index b7c972083657..862ae8d7fcaf 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -17,6 +17,7 @@ package android.media; import android.Manifest; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -43,21 +44,25 @@ import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ReadOnlyBufferException; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME; /** MediaCodec class can be used to access low-level media codecs, i.e. encoder/decoder components. It is part of the Android low-level multimedia support infrastructure (normally used together @@ -1824,6 +1829,7 @@ final public class MediaCodec { private static final String EOS_AND_DECODE_ONLY_ERROR_MESSAGE = "An input buffer cannot have " + "both BUFFER_FLAG_END_OF_STREAM and BUFFER_FLAG_DECODE_ONLY flags"; private static final int CB_CRYPTO_ERROR = 6; + private static final int CB_LARGE_FRAME_OUTPUT_AVAILABLE = 7; private class EventHandler extends Handler { private MediaCodec mCodec; @@ -1945,6 +1951,39 @@ final public class MediaCodec { break; } + case CB_LARGE_FRAME_OUTPUT_AVAILABLE: + { + int index = msg.arg2; + ArrayDeque<BufferInfo> infos = (ArrayDeque<BufferInfo>)msg.obj; + synchronized(mBufferLock) { + switch (mBufferMode) { + case BUFFER_MODE_LEGACY: + validateOutputByteBuffersLocked(mCachedOutputBuffers, + index, infos); + break; + case BUFFER_MODE_BLOCK: + while (mOutputFrames.size() <= index) { + mOutputFrames.add(null); + } + OutputFrame frame = mOutputFrames.get(index); + if (frame == null) { + frame = new OutputFrame(index); + mOutputFrames.set(index, frame); + } + frame.setBufferInfos(infos); + frame.setAccessible(true); + break; + default: + throw new IllegalArgumentException( + "Unrecognized buffer mode: for large frame output"); + } + } + mCallback.onOutputBuffersAvailable( + mCodec, index, infos); + + break; + } + case CB_ERROR: { mCallback.onError(mCodec, (MediaCodec.CodecException) msg.obj); @@ -2836,11 +2875,72 @@ final public class MediaCodec { } } + /** + * Submit multiple access units to the codec along with multiple + * {@link MediaCodec.BufferInfo} describing the contents of the buffer. This method + * is supported only in asynchronous mode. While this method can be used for all codecs, + * it is meant for buffer batching, which is only supported by codecs that advertise + * FEATURE_MultipleFrames. Other codecs will not output large output buffers via + * onOutputBuffersAvailable, and instead will output single-access-unit output via + * onOutputBufferAvailable. + * <p> + * Output buffer size can be configured using the following MediaFormat keys. + * {@link MediaFormat#KEY_BUFFER_BATCH_MAX_OUTPUT_SIZE} and + * {@link MediaFormat#KEY_BUFFER_BATCH_THRESHOLD_OUTPUT_SIZE}. + * Details for each access unit present in the buffer should be described using + * {@link MediaCodec.BufferInfo}. Access units must be laid out contiguously (without any gaps) + * and in order. Multiple access units in the output if present, will be available in + * {@link Callback#onOutputBuffersAvailable} or {@link Callback#onOutputBufferAvailable} + * in case of single-access-unit output or when output does not contain any buffers, + * such as flags. + * <p> + * All other details for populating {@link MediaCodec.BufferInfo} is the same as described in + * {@link #queueInputBuffer}. + * + * @param index The index of a client-owned input buffer previously returned + * in a call to {@link #dequeueInputBuffer}. + * @param bufferInfos ArrayDeque of {@link MediaCodec.BufferInfo} that describes the + * contents in the buffer. The ArrayDeque and the BufferInfo objects provided + * can be recycled by the caller for re-use. + * @throws IllegalStateException if not in the Executing state or not in asynchronous mode. + * @throws MediaCodec.CodecException upon codec error. + * @throws IllegalArgumentException upon if bufferInfos is empty, contains null, or if the + * access units are not contiguous. + * @throws CryptoException if a crypto object has been specified in + * {@link #configure} + */ + @FlaggedApi(FLAG_LARGE_AUDIO_FRAME) + public final void queueInputBuffers( + int index, + @NonNull ArrayDeque<BufferInfo> bufferInfos) { + synchronized(mBufferLock) { + if (mBufferMode == BUFFER_MODE_BLOCK) { + throw new IncompatibleWithBlockModelException("queueInputBuffers() " + + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. " + + "Please use getQueueRequest() to queue buffers"); + } + invalidateByteBufferLocked(mCachedInputBuffers, index, true /* input */); + mDequeuedInputBuffers.remove(index); + } + try { + native_queueInputBuffers( + index, bufferInfos.toArray()); + } catch (CryptoException | IllegalStateException | IllegalArgumentException e) { + revalidateByteBuffer(mCachedInputBuffers, index, true /* input */); + throw e; + } + } + private native final void native_queueInputBuffer( int index, int offset, int size, long presentationTimeUs, int flags) throws CryptoException; + private native final void native_queueInputBuffers( + int index, + @NonNull Object[] infos) + throws CryptoException, CodecException; + public static final int CRYPTO_MODE_UNENCRYPTED = 0; public static final int CRYPTO_MODE_AES_CTR = 1; public static final int CRYPTO_MODE_AES_CBC = 2; @@ -3462,6 +3562,26 @@ final public class MediaCodec { } /** + * Sets MediaCodec.BufferInfo objects describing the access units + * contained in this queue request. Access units must be laid out + * contiguously without gaps and in order. + * + * @param infos Represents {@link MediaCodec.BufferInfo} objects to mark + * individual access-unit boundaries and the timestamps associated with it. + * The buffer is expected to contain the data in a continuous manner. + * @return this object + */ + @FlaggedApi(FLAG_LARGE_AUDIO_FRAME) + public @NonNull QueueRequest setBufferInfos(@NonNull ArrayDeque<BufferInfo> infos) { + if (!isAccessible()) { + throw new IllegalStateException("The request is stale"); + } + mBufferInfos.clear(); + mBufferInfos.addAll(infos); + return this; + } + + /** * Add an integer parameter. * See {@link MediaFormat} for an exhaustive list of supported keys with * values of type int, that can also be set with {@link MediaFormat#setInteger}. @@ -3577,10 +3697,18 @@ final public class MediaCodec { throw new IllegalStateException("No block is set"); } setAccessible(false); + if (mBufferInfos.isEmpty()) { + BufferInfo info = new BufferInfo(); + info.size = mSize; + info.offset = mOffset; + info.presentationTimeUs = mPresentationTimeUs; + info.flags = mFlags; + mBufferInfos.add(info); + } if (mLinearBlock != null) { mCodec.native_queueLinearBlock( - mIndex, mLinearBlock, mOffset, mSize, mCryptoInfo, - mPresentationTimeUs, mFlags, + mIndex, mLinearBlock, mCryptoInfo, + mBufferInfos.toArray(), mTuningKeys, mTuningValues); } else if (mHardwareBuffer != null) { mCodec.native_queueHardwareBuffer( @@ -3598,6 +3726,7 @@ final public class MediaCodec { mHardwareBuffer = null; mPresentationTimeUs = 0; mFlags = 0; + mBufferInfos.clear(); mTuningKeys.clear(); mTuningValues.clear(); return this; @@ -3621,6 +3750,7 @@ final public class MediaCodec { private HardwareBuffer mHardwareBuffer = null; private long mPresentationTimeUs = 0; private @BufferFlag int mFlags = 0; + private final ArrayDeque<BufferInfo> mBufferInfos = new ArrayDeque<>(); private final ArrayList<String> mTuningKeys = new ArrayList<>(); private final ArrayList<Object> mTuningValues = new ArrayList<>(); @@ -3630,11 +3760,8 @@ final public class MediaCodec { private native void native_queueLinearBlock( int index, @NonNull LinearBlock block, - int offset, - int size, @Nullable CryptoInfo cryptoInfo, - long presentationTimeUs, - int flags, + @NonNull Object[] bufferInfos, @NonNull ArrayList<String> keys, @NonNull ArrayList<Object> values); @@ -4048,6 +4175,27 @@ final public class MediaCodec { } } + private void validateOutputByteBuffersLocked( + @Nullable ByteBuffer[] buffers, int index, @NonNull ArrayDeque<BufferInfo> infoDeque) { + Optional<BufferInfo> minInfo = infoDeque.stream().min( + (info1, info2) -> Integer.compare(info1.offset, info2.offset)); + Optional<BufferInfo> maxInfo = infoDeque.stream().max( + (info1, info2) -> Integer.compare(info1.offset, info2.offset)); + if (buffers == null) { + if (index >= 0) { + mValidOutputIndices.set(index); + } + } else if (index >= 0 && index < buffers.length) { + ByteBuffer buffer = buffers[index]; + if (buffer != null && minInfo.isPresent() && maxInfo.isPresent()) { + buffer.setAccessible(true); + buffer.limit(maxInfo.get().offset + maxInfo.get().size); + buffer.position(minInfo.get().offset); + } + } + + } + private void validateOutputByteBufferLocked( @Nullable ByteBuffer[] buffers, int index, @NonNull BufferInfo info) { if (buffers == null) { @@ -4405,6 +4553,22 @@ final public class MediaCodec { return mFlags; } + /* + * Returns the BufferInfos associated with this OutputFrame. These BufferInfos + * describes the access units present in the OutputFrame. Access units are laid + * out contiguously without gaps and in order. + */ + @FlaggedApi(FLAG_LARGE_AUDIO_FRAME) + public @NonNull ArrayDeque<BufferInfo> getBufferInfos() { + if (mBufferInfos.isEmpty()) { + // single BufferInfo could be present. + BufferInfo bufferInfo = new BufferInfo(); + bufferInfo.set(0, 0, mPresentationTimeUs, mFlags); + mBufferInfos.add(bufferInfo); + } + return mBufferInfos; + } + /** * Returns a read-only {@link MediaFormat} for this frame. The returned * object is valid only until the client calls {@link MediaCodec#releaseOutputBuffer}. @@ -4430,6 +4594,7 @@ final public class MediaCodec { mLinearBlock = null; mHardwareBuffer = null; mFormat = null; + mBufferInfos.clear(); mChangedKeys.clear(); mKeySet.clear(); mLoaded = false; @@ -4448,6 +4613,11 @@ final public class MediaCodec { mFlags = info.flags; } + void setBufferInfos(ArrayDeque<BufferInfo> infos) { + mBufferInfos.clear(); + mBufferInfos.addAll(infos); + } + boolean isLoaded() { return mLoaded; } @@ -4462,6 +4632,7 @@ final public class MediaCodec { private long mPresentationTimeUs = 0; private @BufferFlag int mFlags = 0; private MediaFormat mFormat = null; + private final ArrayDeque<BufferInfo> mBufferInfos = new ArrayDeque<>(); private final ArrayList<String> mChangedKeys = new ArrayList<>(); private final Set<String> mKeySet = new HashSet<>(); private boolean mAccessible = false; @@ -5170,6 +5341,32 @@ final public class MediaCodec { @NonNull MediaCodec codec, int index, @NonNull BufferInfo info); /** + * Called when multiple access-units are available in the output. + * + * @param codec The MediaCodec object. + * @param index The index of the available output buffer. + * @param infos Infos describing the available output buffer {@link MediaCodec.BufferInfo}. + * Access units present in the output buffer are laid out contiguously + * without gaps and in order. + */ + @FlaggedApi(FLAG_LARGE_AUDIO_FRAME) + public void onOutputBuffersAvailable( + @NonNull MediaCodec codec, int index, @NonNull ArrayDeque<BufferInfo> infos) { + /* + * This callback returns multiple BufferInfos when codecs are configured to operate on + * large audio frame. Since at this point, we have a single large buffer, returning + * each BufferInfo using + * {@link Callback#onOutputBufferAvailable onOutputBufferAvailable} may cause the + * index to be released to the codec using {@link MediaCodec#releaseOutputBuffer} + * before all BuffersInfos can be returned to the client. + * Hence this callback is required to be implemented or else an exception is thrown. + */ + throw new IllegalStateException( + "Client must override onOutputBuffersAvailable when codec is " + + "configured to operate with multiple access units"); + } + + /** * Called when the MediaCodec encountered an error * * @param codec The MediaCodec object. diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index ef90bf993437..8cdd59e51ffe 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -163,6 +163,13 @@ static struct { static struct { jclass clazz; jmethodID ctorId; + jmethodID sizeId; + jmethodID addId; +} gArrayDequeInfo; + +static struct { + jclass clazz; + jmethodID ctorId; jmethodID setInternalStateId; jfieldID contextId; jfieldID validId; @@ -200,8 +207,14 @@ struct fields_t { jfieldID queueRequestIndexID; jfieldID outputFrameLinearBlockID; jfieldID outputFrameHardwareBufferID; + jfieldID outputFramebufferInfosID; jfieldID outputFrameChangedKeysID; jfieldID outputFrameFormatID; + jfieldID bufferInfoFlags; + jfieldID bufferInfoOffset; + jfieldID bufferInfoSize; + jfieldID bufferInfoPresentationTimeUs; + }; static fields_t gFields; @@ -412,6 +425,22 @@ status_t JMediaCodec::queueInputBuffer( index, offset, size, timeUs, flags, errorDetailMsg); } +status_t JMediaCodec::queueInputBuffers( + size_t index, + size_t offset, + size_t size, + const sp<RefBase> &infos, + AString *errorDetailMsg) { + + sp<BufferInfosWrapper> auInfo((BufferInfosWrapper *)infos.get()); + return mCodec->queueInputBuffers( + index, + offset, + size, + auInfo, + errorDetailMsg); +} + status_t JMediaCodec::queueSecureInputBuffer( size_t index, size_t offset, @@ -430,10 +459,11 @@ status_t JMediaCodec::queueSecureInputBuffer( } status_t JMediaCodec::queueBuffer( - size_t index, const std::shared_ptr<C2Buffer> &buffer, int64_t timeUs, - uint32_t flags, const sp<AMessage> &tunings, AString *errorDetailMsg) { + size_t index, const std::shared_ptr<C2Buffer> &buffer, + const sp<RefBase> &infos, const sp<AMessage> &tunings, AString *errorDetailMsg) { + sp<BufferInfosWrapper> auInfo((BufferInfosWrapper *)infos.get()); return mCodec->queueBuffer( - index, buffer, timeUs, flags, tunings, errorDetailMsg); + index, buffer, auInfo, tunings, errorDetailMsg); } status_t JMediaCodec::queueEncryptedLinearBlock( @@ -446,13 +476,13 @@ status_t JMediaCodec::queueEncryptedLinearBlock( const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, - int64_t presentationTimeUs, - uint32_t flags, + const sp<RefBase> &infos, const sp<AMessage> &tunings, AString *errorDetailMsg) { + sp<BufferInfosWrapper> auInfo((BufferInfosWrapper *)infos.get()); return mCodec->queueEncryptedBuffer( index, buffer, offset, subSamples, numSubSamples, key, iv, mode, pattern, - presentationTimeUs, flags, tunings, errorDetailMsg); + auInfo, tunings, errorDetailMsg); } status_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { @@ -722,6 +752,42 @@ status_t JMediaCodec::getImage( return OK; } +void maybeSetBufferInfos(JNIEnv *env, jobject &frame, const sp<BufferInfosWrapper> &bufInfos) { + if (!bufInfos) { + return; + } + std::vector<AccessUnitInfo> &infos = bufInfos.get()->value; + if (infos.empty()) { + return; + } + ScopedLocalRef<jobject> dequeObj{env, env->NewObject( + gArrayDequeInfo.clazz, gArrayDequeInfo.ctorId)}; + jint offset = 0; + std::vector<jobject> jObjectInfos; + for (int i = 0 ; i < infos.size(); i++) { + jobject bufferInfo = env->NewObject( + gBufferInfo.clazz, gBufferInfo.ctorId); + if (bufferInfo != NULL) { + env->CallVoidMethod(bufferInfo, gBufferInfo.setId, + offset, + (jint)(infos)[i].mSize, + (infos)[i].mTimestamp, + (infos)[i].mFlags); + (void)env->CallBooleanMethod( + dequeObj.get(), gArrayDequeInfo.addId, bufferInfo); + offset += (infos)[i].mSize; + jObjectInfos.push_back(bufferInfo); + } + } + env->SetObjectField( + frame, + gFields.outputFramebufferInfosID, + dequeObj.get()); + for (int i = 0; i < jObjectInfos.size(); i++) { + env->DeleteLocalRef(jObjectInfos[i]); + } +} + status_t JMediaCodec::getOutputFrame( JNIEnv *env, jobject frame, size_t index) const { sp<MediaCodecBuffer> buffer; @@ -732,6 +798,11 @@ status_t JMediaCodec::getOutputFrame( } if (buffer->size() > 0) { + sp<RefBase> obj; + sp<BufferInfosWrapper> bufInfos; + if (buffer->meta()->findObject("accessUnitInfo", &obj)) { + bufInfos = std::move(((decltype(bufInfos.get()))obj.get())); + } std::shared_ptr<C2Buffer> c2Buffer = buffer->asC2Buffer(); if (c2Buffer) { switch (c2Buffer->data().type()) { @@ -747,6 +818,7 @@ status_t JMediaCodec::getOutputFrame( (jlong)context.release(), true); env->SetObjectField(frame, gFields.outputFrameLinearBlockID, linearBlock.get()); + maybeSetBufferInfos(env, frame, bufInfos); break; } case C2BufferData::GRAPHIC: { @@ -787,6 +859,7 @@ status_t JMediaCodec::getOutputFrame( (jlong)context.release(), true); env->SetObjectField(frame, gFields.outputFrameLinearBlockID, linearBlock.get()); + maybeSetBufferInfos(env, frame, bufInfos); } else { // No-op. } @@ -1250,6 +1323,7 @@ static jthrowable createCryptoException(JNIEnv *env, status_t err, void JMediaCodec::handleCallback(const sp<AMessage> &msg) { int32_t arg1, arg2 = 0; jobject obj = NULL; + std::vector<jobject> jObjectInfos; CHECK(msg->findInt32("callbackID", &arg1)); JNIEnv *env = AndroidRuntime::getJNIEnv(); @@ -1287,6 +1361,35 @@ void JMediaCodec::handleCallback(const sp<AMessage> &msg) { break; } + case MediaCodec::CB_LARGE_FRAME_OUTPUT_AVAILABLE: + { + sp<RefBase> spobj = nullptr; + CHECK(msg->findInt32("index", &arg2)); + CHECK(msg->findObject("accessUnitInfo", &spobj)); + if (spobj != nullptr) { + sp<BufferInfosWrapper> bufferInfoParamsWrapper { + (BufferInfosWrapper *)spobj.get()}; + std::vector<AccessUnitInfo> &bufferInfoParams = + bufferInfoParamsWrapper.get()->value; + obj = env->NewObject(gArrayDequeInfo.clazz, gArrayDequeInfo.ctorId); + jint offset = 0; + for (int i = 0 ; i < bufferInfoParams.size(); i++) { + jobject bufferInfo = env->NewObject(gBufferInfo.clazz, gBufferInfo.ctorId); + if (bufferInfo != NULL) { + env->CallVoidMethod(bufferInfo, gBufferInfo.setId, + offset, + (jint)(bufferInfoParams)[i].mSize, + (bufferInfoParams)[i].mTimestamp, + (bufferInfoParams)[i].mFlags); + (void)env->CallBooleanMethod(obj, gArrayDequeInfo.addId, bufferInfo); + offset += (bufferInfoParams)[i].mSize; + jObjectInfos.push_back(bufferInfo); + } + } + } + break; + } + case MediaCodec::CB_CRYPTO_ERROR: { int32_t err, actionCode; @@ -1346,6 +1449,9 @@ void JMediaCodec::handleCallback(const sp<AMessage> &msg) { arg2, obj); + for (int i = 0; i < jObjectInfos.size(); i++) { + env->DeleteLocalRef(jObjectInfos[i]); + } env->DeleteLocalRef(obj); } @@ -1913,6 +2019,103 @@ static void android_media_MediaCodec_queueInputBuffer( codec->getExceptionMessage(errorDetailMsg.c_str()).c_str()); } +static status_t extractInfosFromObject( + JNIEnv * const env, + jint * const initialOffset, + jint * const totalSize, + std::vector<AccessUnitInfo> * const infos, + const jobjectArray &objArray, + AString * const errorDetailMsg) { + if (totalSize == nullptr + || initialOffset == nullptr + || infos == nullptr) { + if (errorDetailMsg) { + *errorDetailMsg = "Error: Null arguments provided for extracting Access unit info"; + } + return BAD_VALUE; + } + const jsize numEntries = env->GetArrayLength(objArray); + if (numEntries <= 0) { + if (errorDetailMsg) { + *errorDetailMsg = "Error: No BufferInfo found while queuing for large frame input"; + } + return BAD_VALUE; + } + *initialOffset = 0; + *totalSize = 0; + for (jsize i = 0; i < numEntries; i++) { + jobject param = env->GetObjectArrayElement(objArray, i); + if (param == NULL) { + if (errorDetailMsg) { + *errorDetailMsg = "Error: Queuing a null BufferInfo"; + } + return BAD_VALUE; + } + size_t offset = static_cast<size_t>(env->GetIntField(param, gFields.bufferInfoOffset)); + size_t size = static_cast<size_t>(env->GetIntField(param, gFields.bufferInfoSize)); + uint32_t flags = static_cast<uint32_t>(env->GetIntField(param, gFields.bufferInfoFlags)); + if (flags == 0 && size == 0) { + if (errorDetailMsg) { + *errorDetailMsg = "Error: Queuing an empty BufferInfo"; + } + return BAD_VALUE; + } + if (i == 0) { + *initialOffset = offset; + } + if (CC_UNLIKELY((offset > UINT32_MAX) + || ((long)(offset + size) > UINT32_MAX) + || ((offset - *initialOffset) != *totalSize))) { + if (errorDetailMsg) { + *errorDetailMsg = "Error: offset/size in BufferInfo"; + } + return BAD_VALUE; + } + infos->emplace_back( + flags, + size, + env->GetLongField(param, gFields.bufferInfoPresentationTimeUs)); + *totalSize += size; + } + return OK; +} + +static void android_media_MediaCodec_queueInputBuffers( + JNIEnv *env, + jobject thiz, + jint index, + jobjectArray objArray) { + ALOGV("android_media_MediaCodec_queueInputBuffers"); + sp<JMediaCodec> codec = getMediaCodec(env, thiz); + if (codec == NULL || codec->initCheck() != OK || objArray == NULL) { + throwExceptionAsNecessary(env, INVALID_OPERATION, codec); + return; + } + sp<BufferInfosWrapper> infoObj = + new BufferInfosWrapper{decltype(infoObj->value)()}; + AString errorDetailMsg; + jint initialOffset = 0; + jint totalSize = 0; + status_t err = extractInfosFromObject( + env, + &initialOffset, + &totalSize, + &infoObj->value, + objArray, + &errorDetailMsg); + if (err == OK) { + err = codec->queueInputBuffers( + index, + initialOffset, + totalSize, + infoObj, + &errorDetailMsg); + } + throwExceptionAsNecessary( + env, err, ACTION_CODE_FATAL, + codec->getExceptionMessage(errorDetailMsg.c_str()).c_str()); +} + struct NativeCryptoInfo { NativeCryptoInfo(JNIEnv *env, jobject cryptoInfoObj) : mEnv{env}, @@ -2559,8 +2762,7 @@ static void extractBufferFromContext( static void android_media_MediaCodec_native_queueLinearBlock( JNIEnv *env, jobject thiz, jint index, jobject bufferObj, - jint offset, jint size, jobject cryptoInfoObj, - jlong presentationTimeUs, jint flags, jobject keys, jobject values) { + jobject cryptoInfoObj, jobjectArray objArray, jobject keys, jobject values) { ALOGV("android_media_MediaCodec_native_queueLinearBlock"); sp<JMediaCodec> codec = getMediaCodec(env, thiz); @@ -2578,7 +2780,24 @@ static void android_media_MediaCodec_native_queueLinearBlock( "error occurred while converting tunings from Java to native"); return; } - + jint totalSize; + jint initialOffset; + std::vector<AccessUnitInfo> infoVec; + AString errorDetailMsg; + err = extractInfosFromObject(env, + &initialOffset, + &totalSize, + &infoVec, + objArray, + &errorDetailMsg); + if (err != OK) { + throwExceptionAsNecessary( + env, INVALID_OPERATION, ACTION_CODE_FATAL, + codec->getExceptionMessage(errorDetailMsg.c_str()).c_str()); + return; + } + sp<BufferInfosWrapper> infos = + new BufferInfosWrapper{std::move(infoVec)}; std::shared_ptr<C2Buffer> buffer; sp<hardware::HidlMemory> memory; ScopedLocalRef<jobject> lock{env, env->GetObjectField(bufferObj, gLinearBlockInfo.lockId)}; @@ -2587,10 +2806,10 @@ static void android_media_MediaCodec_native_queueLinearBlock( JMediaCodecLinearBlock *context = (JMediaCodecLinearBlock *)env->GetLongField(bufferObj, gLinearBlockInfo.contextId); if (codec->hasCryptoOrDescrambler()) { - extractMemoryFromContext(context, offset, size, &memory); - offset += context->mHidlMemoryOffset; + extractMemoryFromContext(context, initialOffset, totalSize, &memory); + initialOffset += context->mHidlMemoryOffset; } else { - extractBufferFromContext(context, offset, size, &buffer); + extractBufferFromContext(context, initialOffset, totalSize, &buffer); } } env->MonitorExit(lock.get()); @@ -2601,7 +2820,6 @@ static void android_media_MediaCodec_native_queueLinearBlock( return; } - AString errorDetailMsg; if (codec->hasCryptoOrDescrambler()) { if (!memory) { // It means there was an unexpected failure in extractMemoryFromContext above @@ -2615,7 +2833,7 @@ static void android_media_MediaCodec_native_queueLinearBlock( return; } auto cryptoInfo = - cryptoInfoObj ? NativeCryptoInfo{env, cryptoInfoObj} : NativeCryptoInfo{size}; + cryptoInfoObj ? NativeCryptoInfo{env, cryptoInfoObj} : NativeCryptoInfo{totalSize}; if (env->ExceptionCheck()) { // Creation of cryptoInfo failed. Let the exception bubble up. return; @@ -2623,13 +2841,12 @@ static void android_media_MediaCodec_native_queueLinearBlock( err = codec->queueEncryptedLinearBlock( index, memory, - offset, + initialOffset, cryptoInfo.mSubSamples, cryptoInfo.mNumSubSamples, (const uint8_t *)cryptoInfo.mKey, (const uint8_t *)cryptoInfo.mIv, cryptoInfo.mMode, cryptoInfo.mPattern, - presentationTimeUs, - flags, + infos, tunings, &errorDetailMsg); ALOGI_IF(err != OK, "queueEncryptedLinearBlock returned err = %d", err); @@ -2646,7 +2863,7 @@ static void android_media_MediaCodec_native_queueLinearBlock( return; } err = codec->queueBuffer( - index, buffer, presentationTimeUs, flags, tunings, &errorDetailMsg); + index, buffer, infos, tunings, &errorDetailMsg); } throwExceptionAsNecessary( env, err, ACTION_CODE_FATAL, @@ -2704,8 +2921,11 @@ static void android_media_MediaCodec_native_queueHardwareBuffer( std::shared_ptr<C2Buffer> buffer = C2Buffer::CreateGraphicBuffer(block->share( block->crop(), C2Fence{})); AString errorDetailMsg; + sp<BufferInfosWrapper> infos = + new BufferInfosWrapper{decltype(infos->value)()}; + infos->value.emplace_back(flags, 0 /*not used*/, presentationTimeUs); err = codec->queueBuffer( - index, buffer, presentationTimeUs, flags, tunings, &errorDetailMsg); + index, buffer, infos, tunings, &errorDetailMsg); throwExceptionAsNecessary( env, err, ACTION_CODE_FATAL, codec->getExceptionMessage(errorDetailMsg.c_str()).c_str()); @@ -3214,6 +3434,10 @@ static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { env->GetFieldID(clazz.get(), "mLinearBlock", "Landroid/media/MediaCodec$LinearBlock;"); CHECK(gFields.outputFrameLinearBlockID != NULL); + gFields.outputFramebufferInfosID = + env->GetFieldID(clazz.get(), "mBufferInfos", "Ljava/util/ArrayDeque;"); + CHECK(gFields.outputFramebufferInfosID != NULL); + gFields.outputFrameHardwareBufferID = env->GetFieldID(clazz.get(), "mHardwareBuffer", "Landroid/hardware/HardwareBuffer;"); CHECK(gFields.outputFrameHardwareBufferID != NULL); @@ -3401,6 +3625,19 @@ static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { gArrayListInfo.addId = env->GetMethodID(clazz.get(), "add", "(Ljava/lang/Object;)Z"); CHECK(gArrayListInfo.addId != NULL); + clazz.reset(env->FindClass("java/util/ArrayDeque")); + CHECK(clazz.get() != NULL); + gArrayDequeInfo.clazz = (jclass)env->NewGlobalRef(clazz.get()); + + gArrayDequeInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V"); + CHECK(gArrayDequeInfo.ctorId != NULL); + + gArrayDequeInfo.sizeId = env->GetMethodID(clazz.get(), "size", "()I"); + CHECK(gArrayDequeInfo.sizeId != NULL); + + gArrayDequeInfo.addId = env->GetMethodID(clazz.get(), "add", "(Ljava/lang/Object;)Z"); + CHECK(gArrayDequeInfo.addId != NULL); + clazz.reset(env->FindClass("android/media/MediaCodec$LinearBlock")); CHECK(clazz.get() != NULL); @@ -3444,6 +3681,12 @@ static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { gBufferInfo.setId = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); CHECK(gBufferInfo.setId != NULL); + + gFields.bufferInfoSize = env->GetFieldID(clazz.get(), "size", "I"); + gFields.bufferInfoFlags = env->GetFieldID(clazz.get(), "flags", "I"); + gFields.bufferInfoOffset = env->GetFieldID(clazz.get(), "offset", "I"); + gFields.bufferInfoPresentationTimeUs = + env->GetFieldID(clazz.get(), "presentationTimeUs", "J"); } static void android_media_MediaCodec_native_setup( @@ -3701,6 +3944,9 @@ static const JNINativeMethod gMethods[] = { { "native_queueInputBuffer", "(IIIJI)V", (void *)android_media_MediaCodec_queueInputBuffer }, + { "native_queueInputBuffers", "(I[Ljava/lang/Object;)V", + (void *)android_media_MediaCodec_queueInputBuffers }, + { "native_queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V", (void *)android_media_MediaCodec_queueSecureInputBuffer }, @@ -3711,8 +3957,8 @@ static const JNINativeMethod gMethods[] = { { "native_closeMediaImage", "(J)V", (void *)android_media_MediaCodec_closeMediaImage }, { "native_queueLinearBlock", - "(ILandroid/media/MediaCodec$LinearBlock;IILandroid/media/MediaCodec$CryptoInfo;JI" - "Ljava/util/ArrayList;Ljava/util/ArrayList;)V", + "(ILandroid/media/MediaCodec$LinearBlock;Landroid/media/MediaCodec$CryptoInfo;" + "[Ljava/lang/Object;Ljava/util/ArrayList;Ljava/util/ArrayList;)V", (void *)android_media_MediaCodec_native_queueLinearBlock }, { "native_queueHardwareBuffer", diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h index fbaf64fda572..02708efdea3a 100644 --- a/media/jni/android_media_MediaCodec.h +++ b/media/jni/android_media_MediaCodec.h @@ -35,6 +35,7 @@ class C2Buffer; namespace android { struct ABuffer; +struct AccessUnitInfo; struct ALooper; struct AMessage; struct AString; @@ -93,6 +94,13 @@ struct JMediaCodec : public AHandler { size_t offset, size_t size, int64_t timeUs, uint32_t flags, AString *errorDetailMsg); + status_t queueInputBuffers( + size_t index, + size_t offset, + size_t size, + const sp<RefBase> &auInfo, + AString *errorDetailMsg = NULL); + status_t queueSecureInputBuffer( size_t index, size_t offset, @@ -108,7 +116,7 @@ struct JMediaCodec : public AHandler { status_t queueBuffer( size_t index, const std::shared_ptr<C2Buffer> &buffer, - int64_t timeUs, uint32_t flags, const sp<AMessage> &tunings, + const sp<RefBase> &infos, const sp<AMessage> &tunings, AString *errorDetailMsg); status_t queueEncryptedLinearBlock( @@ -121,8 +129,7 @@ struct JMediaCodec : public AHandler { const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, - int64_t presentationTimeUs, - uint32_t flags, + const sp<RefBase> &infos, const sp<AMessage> &tunings, AString *errorDetailMsg); diff --git a/media/jni/soundpool/SoundDecoder.cpp b/media/jni/soundpool/SoundDecoder.cpp index 5ed10b0d785f..ae576342c6cc 100644 --- a/media/jni/soundpool/SoundDecoder.cpp +++ b/media/jni/soundpool/SoundDecoder.cpp @@ -29,14 +29,15 @@ static constexpr size_t kMaxQueueSize = 128; // before the SoundDecoder thread closes. static constexpr int32_t kWaitTimeBeforeCloseMs = 1000; -SoundDecoder::SoundDecoder(SoundManager* soundManager, size_t threads) +SoundDecoder::SoundDecoder(SoundManager* soundManager, size_t threads, int32_t threadPriority) : mSoundManager(soundManager) { ALOGV("%s(%p, %zu)", __func__, soundManager, threads); // ThreadPool is created, but we don't launch any threads. mThreadPool = std::make_unique<ThreadPool>( std::min(threads, (size_t)std::thread::hardware_concurrency()), - "SoundDecoder_"); + "SoundDecoder_", + threadPriority); } SoundDecoder::~SoundDecoder() diff --git a/media/jni/soundpool/SoundDecoder.h b/media/jni/soundpool/SoundDecoder.h index 7b62114483cf..3f44a0d977e1 100644 --- a/media/jni/soundpool/SoundDecoder.h +++ b/media/jni/soundpool/SoundDecoder.h @@ -28,7 +28,7 @@ namespace android::soundpool { */ class SoundDecoder { public: - SoundDecoder(SoundManager* soundManager, size_t threads); + SoundDecoder(SoundManager* soundManager, size_t threads, int32_t threadPriority); ~SoundDecoder(); void loadSound(int32_t soundID) NO_THREAD_SAFETY_ANALYSIS; // uses unique_lock void quit(); diff --git a/media/jni/soundpool/SoundManager.cpp b/media/jni/soundpool/SoundManager.cpp index 5b16174eef2b..fa35813391a6 100644 --- a/media/jni/soundpool/SoundManager.cpp +++ b/media/jni/soundpool/SoundManager.cpp @@ -29,7 +29,7 @@ namespace android::soundpool { static const size_t kDecoderThreads = std::thread::hardware_concurrency() >= 4 ? 2 : 1; SoundManager::SoundManager() - : mDecoder{std::make_unique<SoundDecoder>(this, kDecoderThreads)} + : mDecoder{std::make_unique<SoundDecoder>(this, kDecoderThreads, ANDROID_PRIORITY_NORMAL)} { ALOGV("%s()", __func__); } diff --git a/media/jni/soundpool/StreamManager.cpp b/media/jni/soundpool/StreamManager.cpp index 52060f1e6209..e11ccbc0448b 100644 --- a/media/jni/soundpool/StreamManager.cpp +++ b/media/jni/soundpool/StreamManager.cpp @@ -35,10 +35,9 @@ static constexpr int32_t kMaxStreams = 32; // In R, we change this to true, as it is the correct way per SoundPool documentation. static constexpr bool kStealActiveStream_OldestFirst = true; -// kPlayOnCallingThread = true prior to R. // Changing to false means calls to play() are almost instantaneous instead of taking around // ~10ms to launch the AudioTrack. It is perhaps 100x faster. -static constexpr bool kPlayOnCallingThread = true; +static constexpr bool kPlayOnCallingThread = false; // Amount of time for a StreamManager thread to wait before closing. static constexpr int64_t kWaitTimeBeforeCloseNs = 9 * NANOS_PER_SECOND; @@ -127,7 +126,8 @@ StreamManager::StreamManager( mThreadPool = std::make_unique<ThreadPool>( std::min((size_t)streams, // do not make more threads than streams to play std::min(threads, (size_t)std::thread::hardware_concurrency())), - "SoundPool_"); + "SoundPool_", + ANDROID_PRIORITY_AUDIO); } #pragma clang diagnostic pop diff --git a/media/jni/soundpool/StreamManager.h b/media/jni/soundpool/StreamManager.h index adbab4b0f9d9..a4cb28663bda 100644 --- a/media/jni/soundpool/StreamManager.h +++ b/media/jni/soundpool/StreamManager.h @@ -46,9 +46,9 @@ namespace android::soundpool { */ class JavaThread { public: - JavaThread(std::function<void()> f, const char *name) + JavaThread(std::function<void()> f, const char *name, int32_t threadPriority) : mF{std::move(f)} { - createThreadEtc(staticFunction, this, name); + createThreadEtc(staticFunction, this, name, threadPriority); } JavaThread(JavaThread &&) = delete; // uses "this" ptr, not moveable. @@ -109,9 +109,11 @@ private: */ class ThreadPool { public: - ThreadPool(size_t maxThreadCount, std::string name) + ThreadPool(size_t maxThreadCount, std::string name, + int32_t threadPriority = ANDROID_PRIORITY_NORMAL) : mMaxThreadCount(maxThreadCount) - , mName{std::move(name)} { } + , mName{std::move(name)} + , mThreadPriority(threadPriority) {} ~ThreadPool() { quit(); } @@ -159,7 +161,8 @@ public: const int32_t id = mNextThreadId; mThreads.emplace_back(std::make_unique<JavaThread>( [this, id, mf = std::move(f)] { mf(id); --mActiveThreadCount; }, - (mName + std::to_string(id)).c_str())); + (mName + std::to_string(id)).c_str(), + mThreadPriority)); ++mActiveThreadCount; return id; } @@ -180,6 +183,7 @@ public: private: const size_t mMaxThreadCount; const std::string mName; + const int32_t mThreadPriority; std::atomic_size_t mActiveThreadCount = 0; diff --git a/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java b/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java index 70202463a79e..c18a2de44573 100644 --- a/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java +++ b/media/tests/EffectsTest/src/com/android/effectstest/EffectsTest.java @@ -41,7 +41,7 @@ public class EffectsTest extends Activity { public EffectsTest() { - Log.d(TAG, "contructor"); + Log.d(TAG, "constructor"); } @Override diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp index 10c570b30d7a..8ea46329af58 100644 --- a/native/graphics/jni/Android.bp +++ b/native/graphics/jni/Android.bp @@ -72,6 +72,9 @@ cc_library_shared { ], }, }, + stubs: { + symbol_file: "libjnigraphics.map.txt", + }, } // The headers module is in frameworks/native/Android.bp. @@ -93,15 +96,18 @@ cc_defaults { ], static_libs: ["libarect"], fuzz_config: { - cc: ["dichenzhang@google.com","scroggo@google.com"], + cc: [ + "dichenzhang@google.com", + "scroggo@google.com", + ], asan_options: [ "detect_odr_violation=1", ], hwasan_options: [ - // Image decoders may attempt to allocate a large amount of memory - // (especially if the encoded image is large). This doesn't - // necessarily mean there is a bug. Set allocator_may_return_null=1 - // for hwasan so the fuzzer can continue running. + // Image decoders may attempt to allocate a large amount of memory + // (especially if the encoded image is large). This doesn't + // necessarily mean there is a bug. Set allocator_may_return_null=1 + // for hwasan so the fuzzer can continue running. "allocator_may_return_null = 1", ], }, diff --git a/nfc-extras/Android.bp b/nfc-extras/Android.bp index cb9ac6fd1d33..1f187e8eab74 100644 --- a/nfc-extras/Android.bp +++ b/nfc-extras/Android.bp @@ -23,9 +23,13 @@ package { default_applicable_licenses: ["frameworks_base_license"], } +// TODO(b/303286040): Deprecate this API surface since this is no longer supported (see ag/443092) java_sdk_library { name: "com.android.nfc_extras", srcs: ["java/**/*.java"], + libs: [ + "framework-nfc.impl" + ], api_packages: ["com.android.nfc_extras"], dist_group: "android", } diff --git a/nfc/Android.bp b/nfc/Android.bp index bf9f47ceb0a7..2090d3397dfe 100644 --- a/nfc/Android.bp +++ b/nfc/Android.bp @@ -10,7 +10,15 @@ package { filegroup { name: "framework-nfc-non-updatable-sources", path: "java", - srcs: [], + srcs: [ + "java/android/nfc/NfcServiceManager.java", + "java/android/nfc/cardemulation/ApduServiceInfo.aidl", + "java/android/nfc/cardemulation/ApduServiceInfo.java", + "java/android/nfc/cardemulation/NfcFServiceInfo.aidl", + "java/android/nfc/cardemulation/NfcFServiceInfo.java", + "java/android/nfc/cardemulation/AidGroup.aidl", + "java/android/nfc/cardemulation/AidGroup.java", + ], } filegroup { @@ -30,10 +38,21 @@ java_sdk_library { libs: [ "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage ], + static_libs: [ + "android.nfc.flags-aconfig-java", + ], srcs: [ ":framework-nfc-updatable-sources", + ":framework-nfc-javastream-protos", ], - defaults: ["framework-non-updatable-unbundled-defaults"], + defaults: ["framework-module-defaults"], + sdk_version: "module_current", + min_sdk_version: "34", // should be 35 (making it 34 for compiling for `-next`) + installable: true, + optimize: { + enabled: false, + }, + hostdex: true, // for hiddenapi check permitted_packages: [ "android.nfc", "com.android.nfc", @@ -41,11 +60,18 @@ java_sdk_library { hidden_api_packages: [ "com.android.nfc", ], - aidl: { - include_dirs: [ - // TODO (b/303286040): Remove these when we change to |framework-module-defaults| - "frameworks/base/nfc/java", - "frameworks/base/core/java", - ], + impl_library_visibility: [ + "//frameworks/base:__subpackages__", + "//cts/tests/tests/nfc", + "//packages/apps/Nfc:__subpackages__", + ], + jarjar_rules: ":nfc-jarjar-rules", + lint: { + strict_updatability_linting: true, }, } + +filegroup { + name: "nfc-jarjar-rules", + srcs: ["jarjar-rules.txt"], +} diff --git a/nfc/api/current.txt b/nfc/api/current.txt index d802177e249b..91e460324289 100644 --- a/nfc/api/current.txt +++ b/nfc/api/current.txt @@ -1 +1,439 @@ // Signature format: 2.0 +package android.nfc { + + public final class AvailableNfcAntenna implements android.os.Parcelable { + ctor public AvailableNfcAntenna(int, int); + method public int describeContents(); + method public int getLocationX(); + method public int getLocationY(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.nfc.AvailableNfcAntenna> CREATOR; + } + + public class FormatException extends java.lang.Exception { + ctor public FormatException(); + ctor public FormatException(String); + ctor public FormatException(String, Throwable); + } + + public final class NdefMessage implements android.os.Parcelable { + ctor public NdefMessage(byte[]) throws android.nfc.FormatException; + ctor public NdefMessage(android.nfc.NdefRecord, android.nfc.NdefRecord...); + ctor public NdefMessage(android.nfc.NdefRecord[]); + method public int describeContents(); + method public int getByteArrayLength(); + method public android.nfc.NdefRecord[] getRecords(); + method public byte[] toByteArray(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefMessage> CREATOR; + } + + public final class NdefRecord implements android.os.Parcelable { + ctor public NdefRecord(short, byte[], byte[], byte[]); + ctor @Deprecated public NdefRecord(byte[]) throws android.nfc.FormatException; + method public static android.nfc.NdefRecord createApplicationRecord(String); + method public static android.nfc.NdefRecord createExternal(String, String, byte[]); + method public static android.nfc.NdefRecord createMime(String, byte[]); + method public static android.nfc.NdefRecord createTextRecord(String, String); + method public static android.nfc.NdefRecord createUri(android.net.Uri); + method public static android.nfc.NdefRecord createUri(String); + method public int describeContents(); + method public byte[] getId(); + method public byte[] getPayload(); + method public short getTnf(); + method public byte[] getType(); + method @Deprecated public byte[] toByteArray(); + method public String toMimeType(); + method public android.net.Uri toUri(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefRecord> CREATOR; + field public static final byte[] RTD_ALTERNATIVE_CARRIER; + field public static final byte[] RTD_HANDOVER_CARRIER; + field public static final byte[] RTD_HANDOVER_REQUEST; + field public static final byte[] RTD_HANDOVER_SELECT; + field public static final byte[] RTD_SMART_POSTER; + field public static final byte[] RTD_TEXT; + field public static final byte[] RTD_URI; + field public static final short TNF_ABSOLUTE_URI = 3; // 0x3 + field public static final short TNF_EMPTY = 0; // 0x0 + field public static final short TNF_EXTERNAL_TYPE = 4; // 0x4 + field public static final short TNF_MIME_MEDIA = 2; // 0x2 + field public static final short TNF_UNCHANGED = 6; // 0x6 + field public static final short TNF_UNKNOWN = 5; // 0x5 + field public static final short TNF_WELL_KNOWN = 1; // 0x1 + } + + public final class NfcAdapter { + method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean allowTransaction(); + method public void disableForegroundDispatch(android.app.Activity); + method public void disableReaderMode(android.app.Activity); + method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean disallowTransaction(); + method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]); + method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle); + method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context); + method @Nullable public android.nfc.NfcAntennaInfo getNfcAntennaInfo(); + method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler); + method public boolean isEnabled(); + method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean isObserveModeSupported(); + method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionEnabled(); + method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionSupported(); + method public boolean isSecureNfcEnabled(); + method public boolean isSecureNfcSupported(); + method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void resetDiscoveryTechnology(@NonNull android.app.Activity); + method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void setDiscoveryTechnology(@NonNull android.app.Activity, int, int); + field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED"; + field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED"; + field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED"; + field public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED"; + field public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED"; + field @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT) public static final String ACTION_TRANSACTION_DETECTED = "android.nfc.action.TRANSACTION_DETECTED"; + field public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE"; + field public static final String EXTRA_AID = "android.nfc.extra.AID"; + field public static final String EXTRA_DATA = "android.nfc.extra.DATA"; + field public static final String EXTRA_ID = "android.nfc.extra.ID"; + field public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES"; + field public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON = "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON"; + field public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence"; + field public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME"; + field public static final String EXTRA_TAG = "android.nfc.extra.TAG"; + field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_DISABLE = 0; // 0x0 + field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_KEEP = -1; // 0xffffffff + field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_A = 1; // 0x1 + field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_B = 2; // 0x2 + field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_F = 4; // 0x4 + field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_DISABLE = 0; // 0x0 + field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_KEEP = -1; // 0xffffffff + field public static final int FLAG_READER_NFC_A = 1; // 0x1 + field public static final int FLAG_READER_NFC_B = 2; // 0x2 + field public static final int FLAG_READER_NFC_BARCODE = 16; // 0x10 + field public static final int FLAG_READER_NFC_F = 4; // 0x4 + field public static final int FLAG_READER_NFC_V = 8; // 0x8 + field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100 + field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80 + field public static final int PREFERRED_PAYMENT_CHANGED = 2; // 0x2 + field public static final int PREFERRED_PAYMENT_LOADED = 1; // 0x1 + field public static final int PREFERRED_PAYMENT_UPDATED = 3; // 0x3 + field public static final int STATE_OFF = 1; // 0x1 + field public static final int STATE_ON = 3; // 0x3 + field public static final int STATE_TURNING_OFF = 4; // 0x4 + field public static final int STATE_TURNING_ON = 2; // 0x2 + } + + @Deprecated public static interface NfcAdapter.CreateBeamUrisCallback { + method @Deprecated public android.net.Uri[] createBeamUris(android.nfc.NfcEvent); + } + + @Deprecated public static interface NfcAdapter.CreateNdefMessageCallback { + method @Deprecated public android.nfc.NdefMessage createNdefMessage(android.nfc.NfcEvent); + } + + @Deprecated public static interface NfcAdapter.OnNdefPushCompleteCallback { + method @Deprecated public void onNdefPushComplete(android.nfc.NfcEvent); + } + + public static interface NfcAdapter.OnTagRemovedListener { + method public void onTagRemoved(); + } + + public static interface NfcAdapter.ReaderCallback { + method public void onTagDiscovered(android.nfc.Tag); + } + + public final class NfcAntennaInfo implements android.os.Parcelable { + ctor public NfcAntennaInfo(int, int, boolean, @NonNull java.util.List<android.nfc.AvailableNfcAntenna>); + method public int describeContents(); + method @NonNull public java.util.List<android.nfc.AvailableNfcAntenna> getAvailableNfcAntennas(); + method public int getDeviceHeight(); + method public int getDeviceWidth(); + method public boolean isDeviceFoldable(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NfcAntennaInfo> CREATOR; + } + + public final class NfcEvent { + field public final android.nfc.NfcAdapter nfcAdapter; + field public final int peerLlcpMajorVersion; + field public final int peerLlcpMinorVersion; + } + + public final class NfcManager { + method public android.nfc.NfcAdapter getDefaultAdapter(); + } + + public final class Tag implements android.os.Parcelable { + method public int describeContents(); + method public byte[] getId(); + method public String[] getTechList(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.nfc.Tag> CREATOR; + } + + public class TagLostException extends java.io.IOException { + ctor public TagLostException(); + ctor public TagLostException(String); + } + +} + +package android.nfc.cardemulation { + + public final class CardEmulation { + method public boolean categoryAllowsForegroundPreference(String); + method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService(); + method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String); + method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService(); + method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter); + method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService(); + method public int getSelectionModeForCategory(String); + method public boolean isDefaultServiceForAid(android.content.ComponentName, String); + method public boolean isDefaultServiceForCategory(android.content.ComponentName, String); + method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>); + method public boolean removeAidsForService(android.content.ComponentName, String); + method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean setOffHostForService(@NonNull android.content.ComponentName, @NonNull String); + method public boolean setPreferredService(android.app.Activity, android.content.ComponentName); + method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setServiceObserveModeDefault(@NonNull android.content.ComponentName, boolean); + method public boolean supportsAidPrefixRegistration(); + method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName); + method public boolean unsetPreferredService(android.app.Activity); + field public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT"; + field public static final String CATEGORY_OTHER = "other"; + field public static final String CATEGORY_PAYMENT = "payment"; + field public static final String EXTRA_CATEGORY = "category"; + field public static final String EXTRA_SERVICE_COMPONENT = "component"; + field public static final int SELECTION_MODE_ALWAYS_ASK = 1; // 0x1 + field public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2; // 0x2 + field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0 + } + + public abstract class HostApduService extends android.app.Service { + ctor public HostApduService(); + method public final void notifyUnhandled(); + method public final android.os.IBinder onBind(android.content.Intent); + method public abstract void onDeactivated(int); + method public abstract byte[] processCommandApdu(byte[], android.os.Bundle); + method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.os.Bundle>); + method public final void sendResponseApdu(byte[]); + field public static final int DEACTIVATION_DESELECTED = 1; // 0x1 + field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String POLLING_LOOP_DATA_KEY = "android.nfc.cardemulation.DATA"; + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String POLLING_LOOP_GAIN_KEY = "android.nfc.cardemulation.GAIN"; + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String POLLING_LOOP_TIMESTAMP_KEY = "android.nfc.cardemulation.TIMESTAMP"; + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_A = 65; // 0x0041 'A' + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_B = 66; // 0x0042 'B' + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_F = 70; // 0x0046 'F' + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String POLLING_LOOP_TYPE_KEY = "android.nfc.cardemulation.TYPE"; + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_OFF = 88; // 0x0058 'X' + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_ON = 79; // 0x004f 'O' + field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_UNKNOWN = 85; // 0x0055 'U' + field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_APDU_SERVICE"; + field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service"; + } + + public abstract class HostNfcFService extends android.app.Service { + ctor public HostNfcFService(); + method public final android.os.IBinder onBind(android.content.Intent); + method public abstract void onDeactivated(int); + method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle); + method public final void sendResponsePacket(byte[]); + field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 + field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE"; + field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service"; + } + + public final class NfcFCardEmulation { + method public boolean disableService(android.app.Activity) throws java.lang.RuntimeException; + method public boolean enableService(android.app.Activity, android.content.ComponentName) throws java.lang.RuntimeException; + method public static android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter); + method public String getNfcid2ForService(android.content.ComponentName) throws java.lang.RuntimeException; + method public String getSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException; + method public boolean registerSystemCodeForService(android.content.ComponentName, String) throws java.lang.RuntimeException; + method public boolean setNfcid2ForService(android.content.ComponentName, String) throws java.lang.RuntimeException; + method public boolean unregisterSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException; + } + + public abstract class OffHostApduService extends android.app.Service { + ctor public OffHostApduService(); + field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"; + field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service"; + } + +} + +package android.nfc.tech { + + public final class IsoDep implements android.nfc.tech.TagTechnology { + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public static android.nfc.tech.IsoDep get(android.nfc.Tag); + method public byte[] getHiLayerResponse(); + method public byte[] getHistoricalBytes(); + method public int getMaxTransceiveLength(); + method public android.nfc.Tag getTag(); + method public int getTimeout(); + method public boolean isConnected(); + method public boolean isExtendedLengthApduSupported(); + method public void setTimeout(int); + method public byte[] transceive(byte[]) throws java.io.IOException; + } + + public final class MifareClassic implements android.nfc.tech.TagTechnology { + method public boolean authenticateSectorWithKeyA(int, byte[]) throws java.io.IOException; + method public boolean authenticateSectorWithKeyB(int, byte[]) throws java.io.IOException; + method public int blockToSector(int); + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public void decrement(int, int) throws java.io.IOException; + method public static android.nfc.tech.MifareClassic get(android.nfc.Tag); + method public int getBlockCount(); + method public int getBlockCountInSector(int); + method public int getMaxTransceiveLength(); + method public int getSectorCount(); + method public int getSize(); + method public android.nfc.Tag getTag(); + method public int getTimeout(); + method public int getType(); + method public void increment(int, int) throws java.io.IOException; + method public boolean isConnected(); + method public byte[] readBlock(int) throws java.io.IOException; + method public void restore(int) throws java.io.IOException; + method public int sectorToBlock(int); + method public void setTimeout(int); + method public byte[] transceive(byte[]) throws java.io.IOException; + method public void transfer(int) throws java.io.IOException; + method public void writeBlock(int, byte[]) throws java.io.IOException; + field public static final int BLOCK_SIZE = 16; // 0x10 + field public static final byte[] KEY_DEFAULT; + field public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY; + field public static final byte[] KEY_NFC_FORUM; + field public static final int SIZE_1K = 1024; // 0x400 + field public static final int SIZE_2K = 2048; // 0x800 + field public static final int SIZE_4K = 4096; // 0x1000 + field public static final int SIZE_MINI = 320; // 0x140 + field public static final int TYPE_CLASSIC = 0; // 0x0 + field public static final int TYPE_PLUS = 1; // 0x1 + field public static final int TYPE_PRO = 2; // 0x2 + field public static final int TYPE_UNKNOWN = -1; // 0xffffffff + } + + public final class MifareUltralight implements android.nfc.tech.TagTechnology { + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public static android.nfc.tech.MifareUltralight get(android.nfc.Tag); + method public int getMaxTransceiveLength(); + method public android.nfc.Tag getTag(); + method public int getTimeout(); + method public int getType(); + method public boolean isConnected(); + method public byte[] readPages(int) throws java.io.IOException; + method public void setTimeout(int); + method public byte[] transceive(byte[]) throws java.io.IOException; + method public void writePage(int, byte[]) throws java.io.IOException; + field public static final int PAGE_SIZE = 4; // 0x4 + field public static final int TYPE_ULTRALIGHT = 1; // 0x1 + field public static final int TYPE_ULTRALIGHT_C = 2; // 0x2 + field public static final int TYPE_UNKNOWN = -1; // 0xffffffff + } + + public final class Ndef implements android.nfc.tech.TagTechnology { + method public boolean canMakeReadOnly(); + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public static android.nfc.tech.Ndef get(android.nfc.Tag); + method public android.nfc.NdefMessage getCachedNdefMessage(); + method public int getMaxSize(); + method public android.nfc.NdefMessage getNdefMessage() throws android.nfc.FormatException, java.io.IOException; + method public android.nfc.Tag getTag(); + method public String getType(); + method public boolean isConnected(); + method public boolean isWritable(); + method public boolean makeReadOnly() throws java.io.IOException; + method public void writeNdefMessage(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException; + field public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic"; + field public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1"; + field public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2"; + field public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3"; + field public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4"; + } + + public final class NdefFormatable implements android.nfc.tech.TagTechnology { + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public void format(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException; + method public void formatReadOnly(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException; + method public static android.nfc.tech.NdefFormatable get(android.nfc.Tag); + method public android.nfc.Tag getTag(); + method public boolean isConnected(); + } + + public final class NfcA implements android.nfc.tech.TagTechnology { + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public static android.nfc.tech.NfcA get(android.nfc.Tag); + method public byte[] getAtqa(); + method public int getMaxTransceiveLength(); + method public short getSak(); + method public android.nfc.Tag getTag(); + method public int getTimeout(); + method public boolean isConnected(); + method public void setTimeout(int); + method public byte[] transceive(byte[]) throws java.io.IOException; + } + + public final class NfcB implements android.nfc.tech.TagTechnology { + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public static android.nfc.tech.NfcB get(android.nfc.Tag); + method public byte[] getApplicationData(); + method public int getMaxTransceiveLength(); + method public byte[] getProtocolInfo(); + method public android.nfc.Tag getTag(); + method public boolean isConnected(); + method public byte[] transceive(byte[]) throws java.io.IOException; + } + + public final class NfcBarcode implements android.nfc.tech.TagTechnology { + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public static android.nfc.tech.NfcBarcode get(android.nfc.Tag); + method public byte[] getBarcode(); + method public android.nfc.Tag getTag(); + method public int getType(); + method public boolean isConnected(); + field public static final int TYPE_KOVIO = 1; // 0x1 + field public static final int TYPE_UNKNOWN = -1; // 0xffffffff + } + + public final class NfcF implements android.nfc.tech.TagTechnology { + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public static android.nfc.tech.NfcF get(android.nfc.Tag); + method public byte[] getManufacturer(); + method public int getMaxTransceiveLength(); + method public byte[] getSystemCode(); + method public android.nfc.Tag getTag(); + method public int getTimeout(); + method public boolean isConnected(); + method public void setTimeout(int); + method public byte[] transceive(byte[]) throws java.io.IOException; + } + + public final class NfcV implements android.nfc.tech.TagTechnology { + method public void close() throws java.io.IOException; + method public void connect() throws java.io.IOException; + method public static android.nfc.tech.NfcV get(android.nfc.Tag); + method public byte getDsfId(); + method public int getMaxTransceiveLength(); + method public byte getResponseFlags(); + method public android.nfc.Tag getTag(); + method public boolean isConnected(); + method public byte[] transceive(byte[]) throws java.io.IOException; + } + + public interface TagTechnology extends java.io.Closeable { + method public void connect() throws java.io.IOException; + method public android.nfc.Tag getTag(); + method public boolean isConnected(); + } + +} + diff --git a/nfc/api/lint-baseline.txt b/nfc/api/lint-baseline.txt new file mode 100644 index 000000000000..ef9aab6e7641 --- /dev/null +++ b/nfc/api/lint-baseline.txt @@ -0,0 +1,95 @@ +// Baseline format: 1.0 +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED: + Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED: + Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED: + Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior + + +MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent): + Missing nullability on method `onBind` return +MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent) parameter #0: + Missing nullability on parameter `intent` in method `onBind` + + +RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity): + Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]): + Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String): + Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String): + Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String): + Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.nfc.tech.IsoDep#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]): + Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]): + Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int): + Method 'decrement' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int): + Method 'increment' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int): + Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#restore(int): + Method 'restore' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#transfer(int): + Method 'transfer' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]): + Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int): + Method 'readPages' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]): + Method 'writePage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#getNdefMessage(): + Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#isWritable(): + Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#makeReadOnly(): + Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage): + Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage): + Method 'format' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage): + Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcA#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcA#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcF#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcF#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.TagTechnology#close(): + Method 'close' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.TagTechnology#connect(): + Method 'connect' documentation mentions permissions without declaring @RequiresPermission diff --git a/nfc/api/module-lib-current.txt b/nfc/api/module-lib-current.txt index d802177e249b..5ebe91111ec0 100644 --- a/nfc/api/module-lib-current.txt +++ b/nfc/api/module-lib-current.txt @@ -1 +1,10 @@ // Signature format: 2.0 +package android.nfc { + + public class NfcFrameworkInitializer { + method public static void registerServiceWrappers(); + method public static void setNfcServiceManager(@NonNull android.nfc.NfcServiceManager); + } + +} + diff --git a/nfc/api/module-lib-lint-baseline.txt b/nfc/api/module-lib-lint-baseline.txt new file mode 100644 index 000000000000..f7f8ee3ddda5 --- /dev/null +++ b/nfc/api/module-lib-lint-baseline.txt @@ -0,0 +1,93 @@ +// Baseline format: 1.0 +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED: + Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED: + Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC: + Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @BroadcastBehavior +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED: + Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior + +RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity): + Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]): + Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String): + Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String): + Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String): + Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.nfc.tech.IsoDep#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]): + Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]): + Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int): + Method 'decrement' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int): + Method 'increment' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int): + Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#restore(int): + Method 'restore' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#transfer(int): + Method 'transfer' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]): + Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int): + Method 'readPages' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]): + Method 'writePage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#getNdefMessage(): + Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#isWritable(): + Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#makeReadOnly(): + Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage): + Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage): + Method 'format' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage): + Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcA#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcA#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcF#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcF#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.TagTechnology#close(): + Method 'close' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.TagTechnology#connect(): + Method 'connect' documentation mentions permissions without declaring @RequiresPermission + +SdkConstant: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC: + Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) diff --git a/nfc/api/removed.txt b/nfc/api/removed.txt index d802177e249b..fb82b5ddbb21 100644 --- a/nfc/api/removed.txt +++ b/nfc/api/removed.txt @@ -1 +1,17 @@ // Signature format: 2.0 +package android.nfc { + + public final class NfcAdapter { + method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void disableForegroundNdefPush(android.app.Activity); + method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage); + method @Deprecated @android.compat.annotation.UnsupportedAppUsage public boolean invokeBeam(android.app.Activity); + method @Deprecated @android.compat.annotation.UnsupportedAppUsage public boolean isNdefPushEnabled(); + method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setBeamPushUris(android.net.Uri[], android.app.Activity); + method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity); + method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...); + method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...); + method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...); + } + +} + diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt index d802177e249b..d5b3c7df59d4 100644 --- a/nfc/api/system-current.txt +++ b/nfc/api/system-current.txt @@ -1 +1,45 @@ // Signature format: 2.0 +package android.nfc { + + public final class NfcAdapter { + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean addNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler, String[]); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(boolean); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable(); + method @FlaggedApi("android.nfc.enable_nfc_reader_option") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableReaderOption(boolean); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean); + method @FlaggedApi("android.nfc.enable_nfc_mainline") public int getAdapterState(); + method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int); + method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn(); + method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported(); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagIntentAppPreferenceSupported(); + method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler); + method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean); + method @FlaggedApi("android.nfc.enable_nfc_mainline") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setReaderMode(boolean); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean); + method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener); + field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC = "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC"; + field public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff + field public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0; // 0x0 + field public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2; // 0xfffffffe + } + + public static interface NfcAdapter.ControllerAlwaysOnListener { + method public void onControllerAlwaysOnChanged(boolean); + } + + public static interface NfcAdapter.NfcUnlockHandler { + method public boolean onUnlockAttempted(android.nfc.Tag); + } + +} + +package android.nfc.cardemulation { + + public final class CardEmulation { + method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int); + } + +} + diff --git a/nfc/api/system-lint-baseline.txt b/nfc/api/system-lint-baseline.txt new file mode 100644 index 000000000000..761c8e63df81 --- /dev/null +++ b/nfc/api/system-lint-baseline.txt @@ -0,0 +1,105 @@ +// Baseline format: 1.0 +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED: + Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED: + Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC: + Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @BroadcastBehavior +BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED: + Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior + + +MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent): + Missing nullability on method `onBind` return +MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent) parameter #0: + Missing nullability on parameter `intent` in method `onBind` + + +RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity): + Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]): + Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String): + Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String): + Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String): + Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission +RequiresPermission: android.nfc.tech.IsoDep#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]): + Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]): + Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int): + Method 'decrement' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int): + Method 'increment' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int): + Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#restore(int): + Method 'restore' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#transfer(int): + Method 'transfer' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]): + Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int): + Method 'readPages' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]): + Method 'writePage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#getNdefMessage(): + Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#isWritable(): + Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#makeReadOnly(): + Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage): + Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage): + Method 'format' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage): + Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcA#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcA#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcF#getTimeout(): + Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcF#setTimeout(int): + Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]): + Method 'transceive' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.TagTechnology#close(): + Method 'close' documentation mentions permissions without declaring @RequiresPermission +RequiresPermission: android.nfc.tech.TagTechnology#connect(): + Method 'connect' documentation mentions permissions without declaring @RequiresPermission + +SamShouldBeLast: android.nfc.NfcAdapter#enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle): + SAM-compatible parameters (such as parameter 2, "callback", in android.nfc.NfcAdapter.enableReaderMode) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions +SamShouldBeLast: android.nfc.NfcAdapter#ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler): + SAM-compatible parameters (such as parameter 3, "tagRemovedListener", in android.nfc.NfcAdapter.ignore) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions + +SdkConstant: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC: + Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) diff --git a/nfc/api/system-removed.txt b/nfc/api/system-removed.txt index d802177e249b..c6eaa57b6b06 100644 --- a/nfc/api/system-removed.txt +++ b/nfc/api/system-removed.txt @@ -1 +1,12 @@ // Signature format: 2.0 +package android.nfc { + + public final class NfcAdapter { + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush(); + method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush(); + method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int); + field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1 + } + +} + diff --git a/nfc/jarjar-rules.txt b/nfc/jarjar-rules.txt new file mode 100644 index 000000000000..4cd652d6af7f --- /dev/null +++ b/nfc/jarjar-rules.txt @@ -0,0 +1,38 @@ +# Used by framework-nfc for proto debug dumping +rule android.app.PendingIntentProto* com.android.nfc.x.@0 +rule android.content.ComponentNameProto* com.android.nfc.x.@0 +rule android.content.IntentProto* com.android.nfc.x.@0 +rule android.content.IntentFilterProto* com.android.nfc.x.@0 +rule android.content.AuthorityEntryProto* com.android.nfc.x.@0 +rule android.nfc.cardemulation.AidGroupProto* com.android.nfc.x.@0 +rule android.nfc.cardemulation.ApduServiceInfoProto* com.android.nfc.x.@0 +rule android.nfc.cardemulation.NfcFServiceInfoProto* com.android.nfc.x.@0 +rule android.nfc.NdefMessageProto* com.android.nfc.x.@0 +rule android.nfc.NdefRecordProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.CardEmulationManagerProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.RegisteredServicesCacheProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.RegisteredNfcFServicesCacheProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.PreferredServicesProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.EnabledNfcFServicesProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.RegisteredAidCacheProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.AidRoutingManagerProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.RegisteredT3tIdentifiersCacheProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.SystemCodeRoutingManagerProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.HostEmulationManagerProto* com.android.nfc.x.@0 +rule com.android.nfc.cardemulation.HostNfcFEmulationManagerProto* com.android.nfc.x.@0 +rule com.android.nfc.NfcServiceDumpProto* com.android.nfc.x.@0 +rule com.android.nfc.DiscoveryParamsProto* com.android.nfc.x.@0 +rule com.android.nfc.NfcDispatcherProto* com.android.nfc.x.@0 +rule android.os.PersistableBundleProto* com.android.nfc.x.@0 + +# Used by framework-nfc for reading trunk stable flags +rule android.nfc.FakeFeatureFlagsImpl* com.android.nfc.x.@0 +rule android.nfc.FeatureFlags* com.android.nfc.x.@0 +rule android.nfc.Flags* com.android.nfc.x.@0 +rule android.permission.flags.** com.android.nfc.x.@0 + +# Used by framework-nfc for misc utilities +rule android.os.PatternMatcher* com.android.nfc.x.@0 + +rule com.android.incident.Privacy* com.android.nfc.x.@0 +rule com.android.incident.PrivacyFlags* com.android.nfc.x.@0 diff --git a/core/java/android/nfc/ApduList.aidl b/nfc/java/android/nfc/ApduList.aidl index f6236b2bfb3b..f6236b2bfb3b 100644 --- a/core/java/android/nfc/ApduList.aidl +++ b/nfc/java/android/nfc/ApduList.aidl diff --git a/core/java/android/nfc/ApduList.java b/nfc/java/android/nfc/ApduList.java index 027141d99c30..027141d99c30 100644 --- a/core/java/android/nfc/ApduList.java +++ b/nfc/java/android/nfc/ApduList.java diff --git a/core/java/android/nfc/AvailableNfcAntenna.aidl b/nfc/java/android/nfc/AvailableNfcAntenna.aidl index 9d06e2d7d5eb..9d06e2d7d5eb 100644 --- a/core/java/android/nfc/AvailableNfcAntenna.aidl +++ b/nfc/java/android/nfc/AvailableNfcAntenna.aidl diff --git a/core/java/android/nfc/AvailableNfcAntenna.java b/nfc/java/android/nfc/AvailableNfcAntenna.java index 6e6512a04971..6e6512a04971 100644 --- a/core/java/android/nfc/AvailableNfcAntenna.java +++ b/nfc/java/android/nfc/AvailableNfcAntenna.java diff --git a/core/java/android/nfc/Constants.java b/nfc/java/android/nfc/Constants.java index f76833063605..f76833063605 100644 --- a/core/java/android/nfc/Constants.java +++ b/nfc/java/android/nfc/Constants.java diff --git a/core/java/android/nfc/ErrorCodes.java b/nfc/java/android/nfc/ErrorCodes.java index d2c81cd27d90..d2c81cd27d90 100644 --- a/core/java/android/nfc/ErrorCodes.java +++ b/nfc/java/android/nfc/ErrorCodes.java diff --git a/core/java/android/nfc/FormatException.java b/nfc/java/android/nfc/FormatException.java index a57de1e0e21a..a57de1e0e21a 100644 --- a/core/java/android/nfc/FormatException.java +++ b/nfc/java/android/nfc/FormatException.java diff --git a/core/java/android/nfc/IAppCallback.aidl b/nfc/java/android/nfc/IAppCallback.aidl index b06bf06d5197..b06bf06d5197 100644 --- a/core/java/android/nfc/IAppCallback.aidl +++ b/nfc/java/android/nfc/IAppCallback.aidl diff --git a/core/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl index 85879ac56194..85879ac56194 100644 --- a/core/java/android/nfc/INfcAdapter.aidl +++ b/nfc/java/android/nfc/INfcAdapter.aidl diff --git a/core/java/android/nfc/INfcAdapterExtras.aidl b/nfc/java/android/nfc/INfcAdapterExtras.aidl index cde57c58ca1f..cde57c58ca1f 100644 --- a/core/java/android/nfc/INfcAdapterExtras.aidl +++ b/nfc/java/android/nfc/INfcAdapterExtras.aidl diff --git a/core/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl index f4b46046bc3e..f4b46046bc3e 100644 --- a/core/java/android/nfc/INfcCardEmulation.aidl +++ b/nfc/java/android/nfc/INfcCardEmulation.aidl diff --git a/core/java/android/nfc/INfcControllerAlwaysOnListener.aidl b/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl index 1bb7680d2fed..1bb7680d2fed 100644 --- a/core/java/android/nfc/INfcControllerAlwaysOnListener.aidl +++ b/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl diff --git a/core/java/android/nfc/INfcDta.aidl b/nfc/java/android/nfc/INfcDta.aidl index 4cc59271362b..4cc59271362b 100644 --- a/core/java/android/nfc/INfcDta.aidl +++ b/nfc/java/android/nfc/INfcDta.aidl diff --git a/core/java/android/nfc/INfcFCardEmulation.aidl b/nfc/java/android/nfc/INfcFCardEmulation.aidl index 124bfac4f0d0..124bfac4f0d0 100644 --- a/core/java/android/nfc/INfcFCardEmulation.aidl +++ b/nfc/java/android/nfc/INfcFCardEmulation.aidl diff --git a/core/java/android/nfc/INfcTag.aidl b/nfc/java/android/nfc/INfcTag.aidl index 170df71385bb..170df71385bb 100644 --- a/core/java/android/nfc/INfcTag.aidl +++ b/nfc/java/android/nfc/INfcTag.aidl diff --git a/core/java/android/nfc/INfcUnlockHandler.aidl b/nfc/java/android/nfc/INfcUnlockHandler.aidl index e1cace987dc3..e1cace987dc3 100644 --- a/core/java/android/nfc/INfcUnlockHandler.aidl +++ b/nfc/java/android/nfc/INfcUnlockHandler.aidl diff --git a/core/java/android/nfc/ITagRemovedCallback.aidl b/nfc/java/android/nfc/ITagRemovedCallback.aidl index 2a06ff314b22..2a06ff314b22 100644 --- a/core/java/android/nfc/ITagRemovedCallback.aidl +++ b/nfc/java/android/nfc/ITagRemovedCallback.aidl diff --git a/core/java/android/nfc/NdefMessage.aidl b/nfc/java/android/nfc/NdefMessage.aidl index 378b9d05b385..378b9d05b385 100644 --- a/core/java/android/nfc/NdefMessage.aidl +++ b/nfc/java/android/nfc/NdefMessage.aidl diff --git a/core/java/android/nfc/NdefMessage.java b/nfc/java/android/nfc/NdefMessage.java index 553f6c01b016..553f6c01b016 100644 --- a/core/java/android/nfc/NdefMessage.java +++ b/nfc/java/android/nfc/NdefMessage.java diff --git a/core/java/android/nfc/NdefRecord.aidl b/nfc/java/android/nfc/NdefRecord.aidl index 10f89d0936e4..10f89d0936e4 100644 --- a/core/java/android/nfc/NdefRecord.aidl +++ b/nfc/java/android/nfc/NdefRecord.aidl diff --git a/core/java/android/nfc/NdefRecord.java b/nfc/java/android/nfc/NdefRecord.java index 7bf4355d5b35..7bf4355d5b35 100644 --- a/core/java/android/nfc/NdefRecord.java +++ b/nfc/java/android/nfc/NdefRecord.java diff --git a/core/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java index f03fc0af86b3..f03fc0af86b3 100644 --- a/core/java/android/nfc/NfcActivityManager.java +++ b/nfc/java/android/nfc/NfcActivityManager.java diff --git a/core/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java index 979855e5e25c..979855e5e25c 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/nfc/java/android/nfc/NfcAdapter.java diff --git a/core/java/android/nfc/NfcAntennaInfo.aidl b/nfc/java/android/nfc/NfcAntennaInfo.aidl index d5e79fc37282..d5e79fc37282 100644 --- a/core/java/android/nfc/NfcAntennaInfo.aidl +++ b/nfc/java/android/nfc/NfcAntennaInfo.aidl diff --git a/core/java/android/nfc/NfcAntennaInfo.java b/nfc/java/android/nfc/NfcAntennaInfo.java index b002ca21e8e3..b002ca21e8e3 100644 --- a/core/java/android/nfc/NfcAntennaInfo.java +++ b/nfc/java/android/nfc/NfcAntennaInfo.java diff --git a/core/java/android/nfc/NfcControllerAlwaysOnListener.java b/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java index 6ae58fd38cbe..6ae58fd38cbe 100644 --- a/core/java/android/nfc/NfcControllerAlwaysOnListener.java +++ b/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java diff --git a/core/java/android/nfc/NfcEvent.java b/nfc/java/android/nfc/NfcEvent.java index aff4f52f2bab..aff4f52f2bab 100644 --- a/core/java/android/nfc/NfcEvent.java +++ b/nfc/java/android/nfc/NfcEvent.java diff --git a/core/java/android/nfc/NfcFrameworkInitializer.java b/nfc/java/android/nfc/NfcFrameworkInitializer.java index 1ab8a1ebd72c..1ab8a1ebd72c 100644 --- a/core/java/android/nfc/NfcFrameworkInitializer.java +++ b/nfc/java/android/nfc/NfcFrameworkInitializer.java diff --git a/core/java/android/nfc/NfcManager.java b/nfc/java/android/nfc/NfcManager.java index 644e3122774b..644e3122774b 100644 --- a/core/java/android/nfc/NfcManager.java +++ b/nfc/java/android/nfc/NfcManager.java diff --git a/core/java/android/nfc/NfcServiceManager.java b/nfc/java/android/nfc/NfcServiceManager.java index 5582f1154cad..5582f1154cad 100644 --- a/core/java/android/nfc/NfcServiceManager.java +++ b/nfc/java/android/nfc/NfcServiceManager.java diff --git a/core/java/android/nfc/Tag.aidl b/nfc/java/android/nfc/Tag.aidl index 312261ebe76d..312261ebe76d 100644 --- a/core/java/android/nfc/Tag.aidl +++ b/nfc/java/android/nfc/Tag.aidl diff --git a/core/java/android/nfc/Tag.java b/nfc/java/android/nfc/Tag.java index 500038f14d9d..500038f14d9d 100644 --- a/core/java/android/nfc/Tag.java +++ b/nfc/java/android/nfc/Tag.java diff --git a/core/java/android/nfc/TagLostException.java b/nfc/java/android/nfc/TagLostException.java index 1981d7c0c6e0..1981d7c0c6e0 100644 --- a/core/java/android/nfc/TagLostException.java +++ b/nfc/java/android/nfc/TagLostException.java diff --git a/core/java/android/nfc/TechListParcel.aidl b/nfc/java/android/nfc/TechListParcel.aidl index 92e646f220f0..92e646f220f0 100644 --- a/core/java/android/nfc/TechListParcel.aidl +++ b/nfc/java/android/nfc/TechListParcel.aidl diff --git a/core/java/android/nfc/TechListParcel.java b/nfc/java/android/nfc/TechListParcel.java index 9f01559bd344..9f01559bd344 100644 --- a/core/java/android/nfc/TechListParcel.java +++ b/nfc/java/android/nfc/TechListParcel.java diff --git a/core/java/android/nfc/TransceiveResult.aidl b/nfc/java/android/nfc/TransceiveResult.aidl index 98f92ee03eef..98f92ee03eef 100644 --- a/core/java/android/nfc/TransceiveResult.aidl +++ b/nfc/java/android/nfc/TransceiveResult.aidl diff --git a/core/java/android/nfc/TransceiveResult.java b/nfc/java/android/nfc/TransceiveResult.java index 7992094e6ba1..7992094e6ba1 100644 --- a/core/java/android/nfc/TransceiveResult.java +++ b/nfc/java/android/nfc/TransceiveResult.java diff --git a/core/java/android/nfc/cardemulation/AidGroup.aidl b/nfc/java/android/nfc/cardemulation/AidGroup.aidl index 56d6fa559677..56d6fa559677 100644 --- a/core/java/android/nfc/cardemulation/AidGroup.aidl +++ b/nfc/java/android/nfc/cardemulation/AidGroup.aidl diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/nfc/java/android/nfc/cardemulation/AidGroup.java index ae3e333051d7..ae3e333051d7 100644 --- a/core/java/android/nfc/cardemulation/AidGroup.java +++ b/nfc/java/android/nfc/cardemulation/AidGroup.java diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.aidl b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.aidl index a62fdd6a6c5c..a62fdd6a6c5c 100644 --- a/core/java/android/nfc/cardemulation/ApduServiceInfo.aidl +++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.aidl diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java index 41dee3ab035c..41dee3ab035c 100644 --- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java +++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java index ad86d70db967..ad86d70db967 100644 --- a/core/java/android/nfc/cardemulation/CardEmulation.java +++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java index 7cd2533a7dbf..7cd2533a7dbf 100644 --- a/core/java/android/nfc/cardemulation/HostApduService.java +++ b/nfc/java/android/nfc/cardemulation/HostApduService.java diff --git a/core/java/android/nfc/cardemulation/HostNfcFService.java b/nfc/java/android/nfc/cardemulation/HostNfcFService.java index 65b5ca77de62..65b5ca77de62 100644 --- a/core/java/android/nfc/cardemulation/HostNfcFService.java +++ b/nfc/java/android/nfc/cardemulation/HostNfcFService.java diff --git a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java b/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java index 48bbf5b61052..48bbf5b61052 100644 --- a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java +++ b/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java diff --git a/core/java/android/nfc/cardemulation/NfcFServiceInfo.aidl b/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.aidl index 56b98ebd90fa..56b98ebd90fa 100644 --- a/core/java/android/nfc/cardemulation/NfcFServiceInfo.aidl +++ b/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.aidl diff --git a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java b/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.java index 33bc16978721..33bc16978721 100644 --- a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java +++ b/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.java diff --git a/core/java/android/nfc/OWNERS b/nfc/java/android/nfc/cardemulation/OWNERS index 35e9713f5715..35e9713f5715 100644 --- a/core/java/android/nfc/OWNERS +++ b/nfc/java/android/nfc/cardemulation/OWNERS diff --git a/core/java/android/nfc/cardemulation/OffHostApduService.java b/nfc/java/android/nfc/cardemulation/OffHostApduService.java index 2286e8476d94..2286e8476d94 100644 --- a/core/java/android/nfc/cardemulation/OffHostApduService.java +++ b/nfc/java/android/nfc/cardemulation/OffHostApduService.java diff --git a/core/java/android/nfc/cardemulation/Utils.java b/nfc/java/android/nfc/cardemulation/Utils.java index 202e1cfb48f6..202e1cfb48f6 100644 --- a/core/java/android/nfc/cardemulation/Utils.java +++ b/nfc/java/android/nfc/cardemulation/Utils.java diff --git a/core/java/android/nfc/dta/NfcDta.java b/nfc/java/android/nfc/dta/NfcDta.java index 88016623434d..88016623434d 100644 --- a/core/java/android/nfc/dta/NfcDta.java +++ b/nfc/java/android/nfc/dta/NfcDta.java diff --git a/core/java/android/nfc/cardemulation/OWNERS b/nfc/java/android/nfc/dta/OWNERS index 35e9713f5715..35e9713f5715 100644 --- a/core/java/android/nfc/cardemulation/OWNERS +++ b/nfc/java/android/nfc/dta/OWNERS diff --git a/core/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig index 11be905c41ca..11be905c41ca 100644 --- a/core/java/android/nfc/flags.aconfig +++ b/nfc/java/android/nfc/flags.aconfig diff --git a/core/java/android/nfc/package.html b/nfc/java/android/nfc/package.html index 55c1d1650aa9..55c1d1650aa9 100644 --- a/core/java/android/nfc/package.html +++ b/nfc/java/android/nfc/package.html diff --git a/core/java/android/nfc/tech/BasicTagTechnology.java b/nfc/java/android/nfc/tech/BasicTagTechnology.java index ae468fead7a2..ae468fead7a2 100644 --- a/core/java/android/nfc/tech/BasicTagTechnology.java +++ b/nfc/java/android/nfc/tech/BasicTagTechnology.java diff --git a/core/java/android/nfc/tech/IsoDep.java b/nfc/java/android/nfc/tech/IsoDep.java index 0ba0c5a8d13b..0ba0c5a8d13b 100644 --- a/core/java/android/nfc/tech/IsoDep.java +++ b/nfc/java/android/nfc/tech/IsoDep.java diff --git a/core/java/android/nfc/tech/MifareClassic.java b/nfc/java/android/nfc/tech/MifareClassic.java index 26f54e692289..26f54e692289 100644 --- a/core/java/android/nfc/tech/MifareClassic.java +++ b/nfc/java/android/nfc/tech/MifareClassic.java diff --git a/core/java/android/nfc/tech/MifareUltralight.java b/nfc/java/android/nfc/tech/MifareUltralight.java index c0416a39ba76..c0416a39ba76 100644 --- a/core/java/android/nfc/tech/MifareUltralight.java +++ b/nfc/java/android/nfc/tech/MifareUltralight.java diff --git a/core/java/android/nfc/tech/Ndef.java b/nfc/java/android/nfc/tech/Ndef.java index 7d83f157a314..7d83f157a314 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/nfc/java/android/nfc/tech/Ndef.java diff --git a/core/java/android/nfc/tech/NdefFormatable.java b/nfc/java/android/nfc/tech/NdefFormatable.java index 2240fe7f7d3b..2240fe7f7d3b 100644 --- a/core/java/android/nfc/tech/NdefFormatable.java +++ b/nfc/java/android/nfc/tech/NdefFormatable.java diff --git a/core/java/android/nfc/tech/NfcA.java b/nfc/java/android/nfc/tech/NfcA.java index 7e6648361670..7e6648361670 100644 --- a/core/java/android/nfc/tech/NfcA.java +++ b/nfc/java/android/nfc/tech/NfcA.java diff --git a/core/java/android/nfc/tech/NfcB.java b/nfc/java/android/nfc/tech/NfcB.java index 3ebd47f610c0..3ebd47f610c0 100644 --- a/core/java/android/nfc/tech/NfcB.java +++ b/nfc/java/android/nfc/tech/NfcB.java diff --git a/core/java/android/nfc/tech/NfcBarcode.java b/nfc/java/android/nfc/tech/NfcBarcode.java index 421ba7827cb1..421ba7827cb1 100644 --- a/core/java/android/nfc/tech/NfcBarcode.java +++ b/nfc/java/android/nfc/tech/NfcBarcode.java diff --git a/core/java/android/nfc/tech/NfcF.java b/nfc/java/android/nfc/tech/NfcF.java index 2ccd38875f07..2ccd38875f07 100644 --- a/core/java/android/nfc/tech/NfcF.java +++ b/nfc/java/android/nfc/tech/NfcF.java diff --git a/core/java/android/nfc/tech/NfcV.java b/nfc/java/android/nfc/tech/NfcV.java index 186c63bf07fd..186c63bf07fd 100644 --- a/core/java/android/nfc/tech/NfcV.java +++ b/nfc/java/android/nfc/tech/NfcV.java diff --git a/core/java/android/nfc/dta/OWNERS b/nfc/java/android/nfc/tech/OWNERS index 35e9713f5715..35e9713f5715 100644 --- a/core/java/android/nfc/dta/OWNERS +++ b/nfc/java/android/nfc/tech/OWNERS diff --git a/core/java/android/nfc/tech/TagTechnology.java b/nfc/java/android/nfc/tech/TagTechnology.java index 839fe429b338..839fe429b338 100644 --- a/core/java/android/nfc/tech/TagTechnology.java +++ b/nfc/java/android/nfc/tech/TagTechnology.java diff --git a/core/java/android/nfc/tech/package.html b/nfc/java/android/nfc/tech/package.html index a99828f90c5b..a99828f90c5b 100644 --- a/core/java/android/nfc/tech/package.html +++ b/nfc/java/android/nfc/tech/package.html diff --git a/core/tests/nfctests/Android.bp b/nfc/tests/Android.bp index f81be494ad18..62566ee89fb8 100644 --- a/core/tests/nfctests/Android.bp +++ b/nfc/tests/Android.bp @@ -30,6 +30,7 @@ android_test { "truth", ], libs: [ + "framework-nfc.impl", "android.test.runner", ], srcs: ["src/**/*.java"], diff --git a/core/tests/nfctests/AndroidManifest.xml b/nfc/tests/AndroidManifest.xml index 99e2c34c656b..99e2c34c656b 100644 --- a/core/tests/nfctests/AndroidManifest.xml +++ b/nfc/tests/AndroidManifest.xml diff --git a/core/tests/nfctests/AndroidTest.xml b/nfc/tests/AndroidTest.xml index 490d6f5df197..490d6f5df197 100644 --- a/core/tests/nfctests/AndroidTest.xml +++ b/nfc/tests/AndroidTest.xml diff --git a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java index 48f4288d401e..48f4288d401e 100644 --- a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java +++ b/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java diff --git a/core/tests/nfctests/src/android/nfc/TechListParcelTest.java b/nfc/tests/src/android/nfc/TechListParcelTest.java index a12bbbc6884b..a12bbbc6884b 100644 --- a/core/tests/nfctests/src/android/nfc/TechListParcelTest.java +++ b/nfc/tests/src/android/nfc/TechListParcelTest.java diff --git a/opengl/java/android/opengl/EGLExt.java b/opengl/java/android/opengl/EGLExt.java index 1570e0e22f50..31104a0d0a08 100644 --- a/opengl/java/android/opengl/EGLExt.java +++ b/opengl/java/android/opengl/EGLExt.java @@ -46,14 +46,6 @@ public class EGLExt { _nativeClassInit(); } - // C function EGLBoolean eglPresentationTimeANDROID ( EGLDisplay dpy, EGLSurface sur, EGLnsecsANDROID time ) - - public static native boolean eglPresentationTimeANDROID( - EGLDisplay dpy, - EGLSurface sur, - long time - ); - /** * Retrieves the SyncFence for an EGLSync created with EGL_SYNC_NATIVE_FENCE_ANDROID * @@ -83,4 +75,13 @@ public class EGLExt { } private static native int eglDupNativeFenceFDANDROIDImpl(EGLDisplay display, EGLSync sync); + + // C function EGLBoolean eglPresentationTimeANDROID ( EGLDisplay dpy, EGLSurface sur, EGLnsecsANDROID time ) + + public static native boolean eglPresentationTimeANDROID( + EGLDisplay dpy, + EGLSurface sur, + long time + ); + } diff --git a/packages/CrashRecovery/aconfig/flags.aconfig b/packages/CrashRecovery/aconfig/flags.aconfig new file mode 100644 index 000000000000..563626634068 --- /dev/null +++ b/packages/CrashRecovery/aconfig/flags.aconfig @@ -0,0 +1,9 @@ +package: "android.crashrecovery.flags" + +flag { + name: "recoverability_detection" + namespace: "package_watchdog" + description: "Feature flag for recoverability detection" + bug: "310236690" + is_fixed_read_only: true +}
\ No newline at end of file diff --git a/packages/CrashRecovery/services/Android.bp b/packages/CrashRecovery/services/Android.bp index 27ddff93247e..63e6c5083376 100644 --- a/packages/CrashRecovery/services/Android.bp +++ b/packages/CrashRecovery/services/Android.bp @@ -3,7 +3,15 @@ filegroup { srcs: [ "java/**/*.java", "java/**/*.aidl", + ":statslog-crashrecovery-java-gen", ], - path: "java", visibility: ["//frameworks/base:__subpackages__"], } + +genrule { + name: "statslog-crashrecovery-java-gen", + tools: ["stats-log-api-gen"], + cmd: "$(location stats-log-api-gen) --java $(out) --module crashrecovery " + + "--javaPackage com.android.server.crashrecovery.proto --javaClass CrashRecoveryStatsLog --worksource", + out: ["com/android/server/crashrecovery/proto/CrashRecoveryStatsLog.java"], +} diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java index eb65b2a9eedd..dffe4e239ec9 100644 --- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java +++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java @@ -46,11 +46,11 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.FrameworkStatsLog; import com.android.server.PackageWatchdog.FailureReasons; import com.android.server.PackageWatchdog.PackageHealthObserver; import com.android.server.PackageWatchdog.PackageHealthObserverImpact; import com.android.server.am.SettingsToPropertiesMapper; +import com.android.server.crashrecovery.proto.CrashRecoveryStatsLog; import java.io.File; import java.util.ArrayList; @@ -382,7 +382,15 @@ public class RescueParty { private static void executeRescueLevelInternal(Context context, int level, @Nullable String failedPackage) throws Exception { - FrameworkStatsLog.write(FrameworkStatsLog.RESCUE_PARTY_RESET_REPORTED, level); + + if (level <= LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS) { + // Disabling flag resets on master branch for trunk stable launch. + // TODO(b/287618292): Re-enable them after the trunk stable is launched and we + // figured out a way to reset flags without interfering with trunk development. + return; + } + + CrashRecoveryStatsLog.write(CrashRecoveryStatsLog.RESCUE_PARTY_RESET_REPORTED, level); // Try our best to reset all settings possible, and once finished // rethrow any exception that we encountered Exception res = null; diff --git a/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java index 2007079ea5ca..50322f09640f 100644 --- a/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java +++ b/packages/CrashRecovery/services/java/com/android/server/rollback/RollbackPackageHealthObserver.java @@ -39,13 +39,13 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.Preconditions; import com.android.server.PackageWatchdog; import com.android.server.PackageWatchdog.FailureReasons; import com.android.server.PackageWatchdog.PackageHealthObserver; import com.android.server.PackageWatchdog.PackageHealthObserverImpact; import com.android.server.SystemConfig; +import com.android.server.crashrecovery.proto.CrashRecoveryStatsLog; import com.android.server.pm.ApexManager; import java.io.BufferedReader; @@ -418,7 +418,7 @@ final class RollbackPackageHealthObserver implements PackageHealthObserver { final VersionedPackage logPackage = logPackageTemp; WatchdogRollbackLogger.logEvent(logPackage, - FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE, + CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE, reasonToLog, failedPackageToLog); Consumer<Intent> onResult = result -> { @@ -430,19 +430,19 @@ final class RollbackPackageHealthObserver implements PackageHealthObserver { int rollbackId = rollback.getRollbackId(); saveStagedRollbackId(rollbackId, logPackage); WatchdogRollbackLogger.logEvent(logPackage, - FrameworkStatsLog + CrashRecoveryStatsLog .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED, reasonToLog, failedPackageToLog); } else { WatchdogRollbackLogger.logEvent(logPackage, - FrameworkStatsLog + CrashRecoveryStatsLog .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS, reasonToLog, failedPackageToLog); } } else { WatchdogRollbackLogger.logEvent(logPackage, - FrameworkStatsLog + CrashRecoveryStatsLog .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE, reasonToLog, failedPackageToLog); } diff --git a/packages/CrashRecovery/services/java/com/android/server/rollback/WatchdogRollbackLogger.java b/packages/CrashRecovery/services/java/com/android/server/rollback/WatchdogRollbackLogger.java index f9ef994a523a..898c5439a293 100644 --- a/packages/CrashRecovery/services/java/com/android/server/rollback/WatchdogRollbackLogger.java +++ b/packages/CrashRecovery/services/java/com/android/server/rollback/WatchdogRollbackLogger.java @@ -16,16 +16,16 @@ package com.android.server.rollback; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_CRASH; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_NOT_RESPONDING; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_EXPLICIT_HEALTH_CHECK; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH_DURING_BOOT; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE; -import static com.android.internal.util.FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_CRASH; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_NOT_RESPONDING; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_EXPLICIT_HEALTH_CHECK; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH_DURING_BOOT; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE; +import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS; import android.annotation.NonNull; import android.annotation.Nullable; @@ -42,8 +42,8 @@ import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.FrameworkStatsLog; import com.android.server.PackageWatchdog; +import com.android.server.crashrecovery.proto.CrashRecoveryStatsLog; import java.util.List; import java.util.Set; @@ -197,8 +197,8 @@ public final class WatchdogRollbackLogger { + " rollbackReason: " + rollbackReasonToString(rollbackReason) + " failedPackageName: " + failingPackageName); if (logPackage != null) { - FrameworkStatsLog.write( - FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED, + CrashRecoveryStatsLog.write( + CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED, type, logPackage.getPackageName(), logPackage.getVersionCode(), @@ -208,8 +208,8 @@ public final class WatchdogRollbackLogger { } else { // In the case that the log package is null, still log an empty string as an // indication that retrieving the logging parent failed. - FrameworkStatsLog.write( - FrameworkStatsLog.WATCHDOG_ROLLBACK_OCCURRED, + CrashRecoveryStatsLog.write( + CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED, type, "", 0, diff --git a/packages/CtsShim/OWNERS b/packages/CtsShim/OWNERS index 94197715150d..f5741a01e68c 100644 --- a/packages/CtsShim/OWNERS +++ b/packages/CtsShim/OWNERS @@ -1,3 +1,2 @@ -ioffe@google.com -toddke@google.com -patb@google.com
\ No newline at end of file +include /PACKAGE_MANAGER_OWNERS +ioffe@google.com
\ No newline at end of file diff --git a/packages/PackageInstaller/OWNERS b/packages/PackageInstaller/OWNERS index 27368705c6b0..acbdff889f56 100644 --- a/packages/PackageInstaller/OWNERS +++ b/packages/PackageInstaller/OWNERS @@ -1,5 +1,4 @@ -svetoslavganov@google.com +# Bug component: 1002434 include /PACKAGE_MANAGER_OWNERS -# For automotive related changes -rogerxue@google.com +sumedhsen@google.com
\ No newline at end of file diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/MoreOptions.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/MoreOptions.kt index 84fea158175f..d92a863e53bd 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/MoreOptions.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/MoreOptions.kt @@ -35,8 +35,8 @@ import androidx.compose.ui.res.stringResource /** * Scope for the children of [MoreOptionsAction]. */ -interface MoreOptionsScope { - fun dismiss() +abstract class MoreOptionsScope { + abstract fun dismiss() @Composable fun MenuItem(text: String, enabled: Boolean = true, onClick: () -> Unit) { @@ -60,7 +60,7 @@ fun MoreOptionsAction( val onDismiss = { expanded = false } DropdownMenu(expanded = expanded, onDismissRequest = onDismiss) { val moreOptionsScope = remember(this) { - object : MoreOptionsScope { + object : MoreOptionsScope() { override fun dismiss() { onDismiss() } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppRepository.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppRepository.kt index 1a7d8968f232..1859c9b57cb9 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppRepository.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppRepository.kt @@ -37,6 +37,7 @@ fun rememberAppRepository(): AppRepository = rememberContext(::AppRepositoryImpl interface AppRepository { fun loadLabel(app: ApplicationInfo): String + @Suppress("ABSTRACT_COMPOSABLE_DEFAULT_PARAMETER_VALUE") @Composable fun produceLabel(app: ApplicationInfo, isClonedAppPage: Boolean = false): State<String> { val context = LocalContext.current diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt index 983284cbabb7..2ccf323de2a3 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt @@ -130,7 +130,7 @@ class RestrictedMenuItemTest { } private fun setContent(restrictions: Restrictions) { - val fakeMoreOptionsScope = object : MoreOptionsScope { + val fakeMoreOptionsScope = object : MoreOptionsScope() { override fun dismiss() {} } composeTestRule.setContent { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java index c6d147108611..edf951737a16 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -33,7 +33,7 @@ import com.android.systemui.R; public abstract class KeyguardAbsKeyInputView extends KeyguardInputView { protected View mEcaView; - // To avoid accidental lockout due to events while the device in in the pocket, ignore + // To avoid accidental lockout due to events while the device in the pocket, ignore // any passwords with length less than or equal to this length. protected static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3; private KeyDownListener mKeyDownListener; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java index bc12aeebd84c..ce03072e2f0b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java @@ -132,7 +132,7 @@ public interface KeyguardViewController { boolean shouldSubtleWindowAnimationsForUnlock(); /** - * Starts the animation before we dismiss Keyguard, i.e. an disappearing animation on the + * Starts the animation before we dismiss Keyguard, i.e. a disappearing animation on the * security view of the bouncer. * * @param finishRunnable the runnable to be run after the animation finished, or {@code null} if diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java index 9b83b75cec22..ee3706a3ba62 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java @@ -80,7 +80,7 @@ public class KeyguardIndication { } /** - * Click listener for messsage. + * Click listener for message. */ public @Nullable View.OnClickListener getClickListener() { return mOnClickListener; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 1ae5d0a1a39d..c38501123f1c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -437,7 +437,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, /** * Whether a hide is pending and we are just waiting for #startKeyguardExitAnimation to be * called. - * */ + */ private boolean mHiding; /** diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index da9235f0e257..5b068949c9b1 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -16,7 +16,6 @@ package com.android.server.autofill; -import static android.Manifest.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS; import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES; import static android.service.autofill.AutofillService.EXTRA_FILL_RESPONSE; import static android.service.autofill.Dataset.PICK_REASON_NO_PCC; @@ -109,8 +108,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.graphics.Bitmap; import android.graphics.Rect; @@ -1528,6 +1525,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return; } + if (mSessionFlags.mShowingSaveUi) { + // Even though the session has not yet been destroyed at this point, after the + // saveUi gets closed, the session will be destroyed and AutofillManager will reset + // its state. Processing the fill request will result in a great chance of corrupt + // state in Autofill. + Slog.w(TAG, "Call to Session#onFillRequestSuccess() rejected - session: " + + id + " is showing saveUi"); + mFillResponseEventLogger.maybeSetResponseStatus(RESPONSE_STATUS_SESSION_DESTROYED); + mFillResponseEventLogger.logAndEndEvent(); + return; + } requestLog = mRequestLogs.get(requestId); if (requestLog != null) { diff --git a/services/contextualsearch/OWNERS b/services/contextualsearch/OWNERS new file mode 100644 index 000000000000..0c2612c9957b --- /dev/null +++ b/services/contextualsearch/OWNERS @@ -0,0 +1 @@ +include /core/java/android/service/contextualsearch/OWNERS diff --git a/services/core/Android.bp b/services/core/Android.bp index 21cfd242cf45..2dda76e06c56 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -190,6 +190,7 @@ java_library_static { "com.android.sysprop.watchdog", "ImmutabilityAnnotation", "securebox", + "net_flags_lib", ], javac_shard_size: 50, javacflags: [ diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index b9535d6afc6c..43ecec4105aa 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -1024,11 +1024,9 @@ public class AudioDeviceBroker { private void initAudioHalBluetoothState() { synchronized (mBluetoothAudioStateLock) { mBluetoothScoOnApplied = false; - AudioSystem.setParameters("BT_SCO=off"); mBluetoothA2dpSuspendedApplied = false; - AudioSystem.setParameters("A2dpSuspended=false"); mBluetoothLeSuspendedApplied = false; - AudioSystem.setParameters("LeAudioSuspended=false"); + reapplyAudioHalBluetoothState(); } } @@ -1091,6 +1089,34 @@ public class AudioDeviceBroker { } } + @GuardedBy("mBluetoothAudioStateLock") + private void reapplyAudioHalBluetoothState() { + if (AudioService.DEBUG_COMM_RTE) { + Log.v(TAG, "reapplyAudioHalBluetoothState() mBluetoothScoOnApplied: " + + mBluetoothScoOnApplied + ", mBluetoothA2dpSuspendedApplied: " + + mBluetoothA2dpSuspendedApplied + ", mBluetoothLeSuspendedApplied: " + + mBluetoothLeSuspendedApplied); + } + // Note: the order of parameters is important. + if (mBluetoothScoOnApplied) { + AudioSystem.setParameters("A2dpSuspended=true"); + AudioSystem.setParameters("LeAudioSuspended=true"); + AudioSystem.setParameters("BT_SCO=on"); + } else { + AudioSystem.setParameters("BT_SCO=off"); + if (mBluetoothA2dpSuspendedApplied) { + AudioSystem.setParameters("A2dpSuspended=true"); + } else { + AudioSystem.setParameters("A2dpSuspended=false"); + } + if (mBluetoothLeSuspendedApplied) { + AudioSystem.setParameters("LeAudioSuspended=true"); + } else { + AudioSystem.setParameters("LeAudioSuspended=false"); + } + } + } + /*package*/ void setBluetoothScoOn(boolean on, String eventSource) { if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "setBluetoothScoOn: " + on + " " + eventSource); @@ -1727,6 +1753,9 @@ public class AudioDeviceBroker { initRoutingStrategyIds(); updateActiveCommunicationDevice(); mDeviceInventory.onRestoreDevices(); + synchronized (mBluetoothAudioStateLock) { + reapplyAudioHalBluetoothState(); + } mBtHelper.onAudioServerDiedRestoreA2dp(); updateCommunicationRoute("MSG_RESTORE_DEVICES"); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index da38a3446e02..534197b382a0 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -717,7 +717,10 @@ public class HdmiCecMessageValidator { // Programmed int programedInfo = params[offset] & 0x0F; if (isValidProgrammedInfo(programedInfo)) { - if (programedInfo == 0x09 || programedInfo == 0x0B) { + offset = offset + 1; + // Duration Available (2 bytes) + if ((programedInfo == 0x09 || programedInfo == 0x0B) + && params.length - offset >= 2) { durationAvailable = true; } else { return true; @@ -727,16 +730,17 @@ public class HdmiCecMessageValidator { // Non programmed int nonProgramedErrorInfo = params[offset] & 0x0F; if (isValidNotProgrammedErrorInfo(nonProgramedErrorInfo)) { - if (nonProgramedErrorInfo == 0x0E) { + offset = offset + 1; + // Duration Available (2 bytes) + if (nonProgramedErrorInfo == 0x0E && params.length - offset >= 2) { durationAvailable = true; } else { return true; } } } - offset = offset + 1; // Duration Available (2 bytes) - if (durationAvailable && params.length - offset >= 2) { + if (durationAvailable) { return (isValidDurationHours(params[offset]) && isValidMinute(params[offset + 1])); } return false; diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index ad090829a2f6..c81ce26b6403 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -16,6 +16,7 @@ package com.android.server.locksettings; +import static android.security.Flags.reportPrimaryAuthAttempts; import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; import static android.Manifest.permission.MANAGE_BIOMETRIC; import static android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS; @@ -90,6 +91,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.IProgressListener; import android.os.Process; +import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; @@ -135,6 +137,7 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.internal.widget.ICheckCredentialProgressCallback; import com.android.internal.widget.ILockSettings; +import com.android.internal.widget.ILockSettingsStateListener; import com.android.internal.widget.IWeakEscrowTokenActivatedListener; import com.android.internal.widget.IWeakEscrowTokenRemovedListener; import com.android.internal.widget.LockPatternUtils; @@ -327,6 +330,9 @@ public class LockSettingsService extends ILockSettings.Stub { private HashMap<UserHandle, UserManager> mUserManagerCache = new HashMap<>(); + private final RemoteCallbackList<ILockSettingsStateListener> mLockSettingsStateListeners = + new RemoteCallbackList<>(); + // This class manages life cycle events for encrypted users on File Based Encryption (FBE) // devices. The most basic of these is to show/hide notifications about missing features until // the user unlocks the account and credential-encrypted storage is available. @@ -2342,9 +2348,37 @@ public class LockSettingsService extends ILockSettings.Stub { requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId); } } + if (reportPrimaryAuthAttempts()) { + final boolean success = + response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK; + notifyLockSettingsStateListeners(success, userId); + } return response; } + private void notifyLockSettingsStateListeners(boolean success, int userId) { + int i = mLockSettingsStateListeners.beginBroadcast(); + try { + while (i > 0) { + i--; + try { + if (success) { + mLockSettingsStateListeners.getBroadcastItem(i) + .onAuthenticationSucceeded(userId); + } else { + mLockSettingsStateListeners.getBroadcastItem(i) + .onAuthenticationFailed(userId); + } + } catch (RemoteException e) { + Slog.e(TAG, "Exception while notifying LockSettingsStateListener:" + + " success = " + success + ", userId = " + userId, e); + } + } + } finally { + mLockSettingsStateListeners.finishBroadcast(); + } + } + @Override public VerifyCredentialResponse verifyTiedProfileChallenge(LockscreenCredential credential, int userId, @LockPatternUtils.VerifyFlag int flags) { @@ -3662,6 +3696,18 @@ public class LockSettingsService extends ILockSettings.Stub { public void refreshStrongAuthTimeout(int userId) { mStrongAuth.refreshStrongAuthTimeout(userId); } + + @Override + public void registerLockSettingsStateListener( + @NonNull ILockSettingsStateListener listener) { + mLockSettingsStateListeners.register(listener); + } + + @Override + public void unregisterLockSettingsStateListener( + @NonNull ILockSettingsStateListener listener) { + mLockSettingsStateListeners.unregister(listener); + } } private class RebootEscrowCallbacks implements RebootEscrowManager.Callbacks { diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java index cc205d4a53bd..cc58f38db65a 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java @@ -1541,8 +1541,14 @@ class SyntheticPasswordManager { */ public @NonNull AuthenticationResult unlockTokenBasedProtector( IGateKeeperService gatekeeper, long protectorId, byte[] token, int userId) { - SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME, - protectorId, userId)); + byte[] data = loadState(SP_BLOB_NAME, protectorId, userId); + if (data == null) { + AuthenticationResult result = new AuthenticationResult(); + result.gkResponse = VerifyCredentialResponse.ERROR; + Slogf.w(TAG, "spblob not found for protector %016x, user %d", protectorId, userId); + return result; + } + SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(data); return unlockTokenBasedProtectorInternal(gatekeeper, protectorId, blob.mProtectorType, token, userId); } diff --git a/services/core/java/com/android/server/net/Android.bp b/services/core/java/com/android/server/net/Android.bp new file mode 100644 index 000000000000..71d8e6ba367e --- /dev/null +++ b/services/core/java/com/android/server/net/Android.bp @@ -0,0 +1,10 @@ +aconfig_declarations { + name: "net_flags", + package: "com.android.server.net", + srcs: ["*.aconfig"], +} + +java_aconfig_library { + name: "net_flags_lib", + aconfig_declarations: "net_flags", +} diff --git a/services/core/java/com/android/server/net/NetworkManagementService.java b/services/core/java/com/android/server/net/NetworkManagementService.java index 681d1a0ee10a..d25f52973085 100644 --- a/services/core/java/com/android/server/net/NetworkManagementService.java +++ b/services/core/java/com/android/server/net/NetworkManagementService.java @@ -17,6 +17,7 @@ package com.android.server.net; import static android.Manifest.permission.CONNECTIVITY_INTERNAL; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; @@ -27,6 +28,7 @@ import static android.net.INetd.FIREWALL_CHAIN_NONE; import static android.net.INetd.FIREWALL_DENYLIST; import static android.net.INetd.FIREWALL_RULE_ALLOW; import static android.net.INetd.FIREWALL_RULE_DENY; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_BACKGROUND; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; @@ -187,6 +189,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub { */ @GuardedBy("mRulesLock") private final SparseIntArray mUidFirewallLowPowerStandbyRules = new SparseIntArray(); + + /** + * Contains the per-UID firewall rules that are used when Background chain is enabled. + */ + @GuardedBy("mRulesLock") + private final SparseIntArray mUidFirewallBackgroundRules = new SparseIntArray(); + /** Set of states for the child firewall chains. True if the chain is active. */ @GuardedBy("mRulesLock") final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); @@ -449,13 +458,15 @@ public class NetworkManagementService extends INetworkManagementService.Stub { syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave "); syncFirewallChainLocked(FIREWALL_CHAIN_RESTRICTED, "restricted "); syncFirewallChainLocked(FIREWALL_CHAIN_LOW_POWER_STANDBY, "low power standby "); + syncFirewallChainLocked(FIREWALL_CHAIN_BACKGROUND, FIREWALL_CHAIN_NAME_BACKGROUND); final int[] chains = { FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE, FIREWALL_CHAIN_RESTRICTED, - FIREWALL_CHAIN_LOW_POWER_STANDBY + FIREWALL_CHAIN_LOW_POWER_STANDBY, + FIREWALL_CHAIN_BACKGROUND, }; for (int chain : chains) { @@ -1206,6 +1217,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { return FIREWALL_CHAIN_NAME_RESTRICTED; case FIREWALL_CHAIN_LOW_POWER_STANDBY: return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; + case FIREWALL_CHAIN_BACKGROUND: + return FIREWALL_CHAIN_NAME_BACKGROUND; default: throw new IllegalArgumentException("Bad child chain: " + chain); } @@ -1223,6 +1236,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { return FIREWALL_ALLOWLIST; case FIREWALL_CHAIN_LOW_POWER_STANDBY: return FIREWALL_ALLOWLIST; + case FIREWALL_CHAIN_BACKGROUND: + return FIREWALL_ALLOWLIST; default: return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST; } @@ -1343,6 +1358,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { return mUidFirewallRestrictedRules; case FIREWALL_CHAIN_LOW_POWER_STANDBY: return mUidFirewallLowPowerStandbyRules; + case FIREWALL_CHAIN_BACKGROUND: + return mUidFirewallBackgroundRules; case FIREWALL_CHAIN_NONE: return mUidFirewallRules; default: @@ -1395,6 +1412,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub { pw.println(getFirewallChainState(FIREWALL_CHAIN_LOW_POWER_STANDBY)); dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY, mUidFirewallLowPowerStandbyRules); + + pw.print("UID firewall background chain enabled: "); + pw.println(getFirewallChainState(FIREWALL_CHAIN_BACKGROUND)); + dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_BACKGROUND, mUidFirewallBackgroundRules); } pw.print("Firewall enabled: "); pw.println(mFirewallEnabled); @@ -1494,6 +1515,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub { if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of low power standby"); return true; } + if (getFirewallChainState(FIREWALL_CHAIN_BACKGROUND) + && mUidFirewallBackgroundRules.get(uid) != FIREWALL_RULE_ALLOW) { + if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because it is in background"); + return true; + } if (mUidRejectOnMetered.get(uid)) { if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data" + " in the background"); diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java index d7188c7f10c6..8e2d7780204a 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java +++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java @@ -16,6 +16,7 @@ package com.android.server.net; import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; @@ -24,6 +25,7 @@ import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; import static android.net.INetd.FIREWALL_RULE_ALLOW; import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_BACKGROUND; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; @@ -389,6 +391,8 @@ public class NetworkPolicyLogger { return FIREWALL_CHAIN_NAME_RESTRICTED; case FIREWALL_CHAIN_LOW_POWER_STANDBY: return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; + case FIREWALL_CHAIN_BACKGROUND: + return FIREWALL_CHAIN_NAME_BACKGROUND; default: return String.valueOf(chain); } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 52734a4ad3b0..b47458b88f40 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -47,6 +47,7 @@ import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_ADMIN_DISAB import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; +import static android.net.ConnectivityManager.BLOCKED_REASON_APP_BACKGROUND; import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY; import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE; @@ -54,6 +55,7 @@ import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.BLOCKED_REASON_RESTRICTED_MODE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; @@ -77,6 +79,7 @@ import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_USER_EXEMP import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND; import static android.net.NetworkPolicyManager.ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST; import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_NOT_IN_BACKGROUND; import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST; import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST; import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS; @@ -96,6 +99,7 @@ import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED; import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED; import static android.net.NetworkPolicyManager.allowedReasonsToString; import static android.net.NetworkPolicyManager.blockedReasonsToString; +import static android.net.NetworkPolicyManager.isProcStateAllowedNetworkWhileBackground; import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; import static android.net.NetworkPolicyManager.isProcStateAllowedWhileInLowPowerStandby; import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; @@ -201,12 +205,12 @@ import android.os.Message; import android.os.MessageQueue.IdleHandler; import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; +import android.os.PowerExemptionManager; import android.os.PowerExemptionManager.ReasonCode; import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerManagerInternal; import android.os.PowerSaveState; -import android.os.PowerWhitelistManager; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -242,6 +246,7 @@ import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.util.SparseLongArray; import android.util.SparseSetArray; +import android.util.TimeUtils; import android.util.Xml; import com.android.internal.R; @@ -457,6 +462,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { */ private static final int MSG_UIDS_BLOCKED_REASONS_CHANGED = 23; + /** + * Message to update background restriction rules for uids that should lose network access + * due to being in the background. + */ + private static final int MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS = 24; + private static final int UID_MSG_STATE_CHANGED = 100; private static final int UID_MSG_GONE = 101; @@ -475,7 +486,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private ConnectivityManager mConnManager; private PowerManagerInternal mPowerManagerInternal; - private PowerWhitelistManager mPowerWhitelistManager; + private PowerExemptionManager mPowerExemptionManager; @NonNull private final Dependencies mDeps; @@ -490,6 +501,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // Denotes the status of restrict background read from disk. private boolean mLoadedRestrictBackground; + /** + * Whether or not network for apps in proc-states greater than + * {@link NetworkPolicyManager#BACKGROUND_THRESHOLD_STATE} is always blocked. + */ + private boolean mBackgroundNetworkRestricted; + // See main javadoc for instructions on how to use these locks. final Object mUidRulesFirstLock = new Object(); final Object mNetworkPoliciesSecondLock = new Object(); @@ -514,6 +531,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private volatile boolean mNetworkManagerReady; + /** + * Delay after which a uid going into a process state greater than or equal to + * {@link NetworkPolicyManager#BACKGROUND_THRESHOLD_STATE} will lose network access. + * The delay is meant to prevent churn due to quick process-state changes. + * Note that there is no delay while granting network access. + */ + @VisibleForTesting + long mBackgroundRestrictionDelayMs = TimeUnit.SECONDS.toMillis(5); + /** Defined network policies. */ @GuardedBy("mNetworkPoliciesSecondLock") final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>(); @@ -545,6 +571,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray(); @GuardedBy("mUidRulesFirstLock") + final SparseIntArray mUidFirewallBackgroundRules = new SparseIntArray(); + @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidFirewallRestrictedModeRules = new SparseIntArray(); @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidFirewallLowPowerStandbyModeRules = new SparseIntArray(); @@ -624,6 +652,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private final SparseArray<UidBlockedState> mTmpUidBlockedState = new SparseArray<>(); + /** + * Stores a map of uids to the time their transition to background is considered complete. They + * will lose network access after this time. This is used to prevent churn in rules due to quick + * process-state transitions. + */ + @GuardedBy("mUidRulesFirstLock") + private final SparseLongArray mBackgroundTransitioningUids = new SparseLongArray(); + /** Map from network ID to last observed meteredness state */ @GuardedBy("mNetworkPoliciesSecondLock") private final SparseBooleanArray mNetworkMetered = new SparseBooleanArray(); @@ -823,7 +859,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mContext = Objects.requireNonNull(context, "missing context"); mActivityManager = Objects.requireNonNull(activityManager, "missing activityManager"); mNetworkManager = Objects.requireNonNull(networkManagement, "missing networkManagement"); - mPowerWhitelistManager = mContext.getSystemService(PowerWhitelistManager.class); + mPowerExemptionManager = mContext.getSystemService(PowerExemptionManager.class); mClock = Objects.requireNonNull(clock, "missing Clock"); mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class); @@ -859,15 +895,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private void updatePowerSaveAllowlistUL() { - int[] whitelist = mPowerWhitelistManager.getWhitelistedAppIds(/* includingIdle */ false); + int[] allowlist = mPowerExemptionManager.getAllowListedAppIds(/* includingIdle */ false); mPowerSaveWhitelistExceptIdleAppIds.clear(); - for (int uid : whitelist) { + for (int uid : allowlist) { mPowerSaveWhitelistExceptIdleAppIds.put(uid, true); } - whitelist = mPowerWhitelistManager.getWhitelistedAppIds(/* includingIdle */ true); + allowlist = mPowerExemptionManager.getAllowListedAppIds(/* includingIdle */ true); mPowerSaveWhitelistAppIds.clear(); - for (int uid : whitelist) { + for (int uid : allowlist) { mPowerSaveWhitelistAppIds.put(uid, true); } } @@ -1017,6 +1053,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { writePolicyAL(); } + // The flag is boot-stable. + mBackgroundNetworkRestricted = Flags.networkBlockedForTopSleepingAndAbove(); + if (mBackgroundNetworkRestricted) { + // Firewall rules and UidBlockedState will get updated in + // updateRulesForGlobalChangeAL below. + enableFirewallChainUL(FIREWALL_CHAIN_BACKGROUND, true); + } + setRestrictBackgroundUL(mLoadedRestrictBackground, "init_service"); updateRulesForGlobalChangeAL(false); updateNotificationsNL(); @@ -1027,17 +1071,22 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final int changes = ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_CAPABILITY; + + final int cutpoint = mBackgroundNetworkRestricted ? PROCESS_STATE_UNKNOWN + : NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE; + // TODO (b/319728914): Filter out the unnecessary changes when using no cutpoint. + mActivityManagerInternal.registerNetworkPolicyUidObserver(mUidObserver, changes, - NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android"); + cutpoint, "android"); mNetworkManager.registerObserver(mAlertObserver); } catch (RemoteException e) { // ignored; both services live in system_server } // listen for changes to power save allowlist - final IntentFilter whitelistFilter = new IntentFilter( + final IntentFilter allowlistFilter = new IntentFilter( PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED); - mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler); + mContext.registerReceiver(mPowerSaveAllowlistReceiver, allowlistFilter, null, mHandler); // watch for network interfaces to be claimed final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION); @@ -1188,12 +1237,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } - final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() { + private final BroadcastReceiver mPowerSaveAllowlistReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected synchronized (mUidRulesFirstLock) { updatePowerSaveAllowlistUL(); + if (mBackgroundNetworkRestricted) { + updateRulesForBackgroundChainUL(); + } updateRulesForRestrictPowerUL(); updateRulesForAppIdleUL(); } @@ -3901,6 +3953,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } fout.println(); + fout.println("Flags:"); + fout.println("Network blocked for TOP_SLEEPING and above: " + + mBackgroundNetworkRestricted); + + fout.println(); fout.println("mRestrictBackgroundLowPowerMode: " + mRestrictBackgroundLowPowerMode); fout.println("mRestrictBackgroundBeforeBsm: " + mRestrictBackgroundBeforeBsm); fout.println("mLoadedRestrictBackground: " + mLoadedRestrictBackground); @@ -4042,6 +4099,22 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } + size = mBackgroundTransitioningUids.size(); + if (size > 0) { + final long nowUptime = SystemClock.uptimeMillis(); + fout.println("Uids transitioning to background:"); + fout.increaseIndent(); + for (int i = 0; i < size; i++) { + fout.print("UID="); + fout.print(mBackgroundTransitioningUids.keyAt(i)); + fout.print(", "); + TimeUtils.formatDuration(mBackgroundTransitioningUids.valueAt(i), nowUptime, + fout); + fout.println(); + } + fout.decreaseIndent(); + } + final SparseBooleanArray knownUids = new SparseBooleanArray(); collectKeys(mUidState, knownUids); synchronized (mUidBlockedState) { @@ -4163,6 +4236,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return isProcStateAllowedWhileInLowPowerStandby(uidState); } + @GuardedBy("mUidRulesFirstLock") + private boolean isUidExemptFromBackgroundRestrictions(int uid) { + return mBackgroundTransitioningUids.indexOfKey(uid) >= 0 + || isProcStateAllowedNetworkWhileBackground(mUidState.get(uid)); + } + /** * Process state of UID changed; if needed, will trigger * {@link #updateRulesForDataUsageRestrictionsUL(int)} and @@ -4188,6 +4267,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // state changed, push updated rules mUidState.put(uid, newUidState); updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, newUidState); + + boolean updatePowerRestrictionRules = false; boolean allowedWhileIdleOrPowerSaveModeChanged = isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState) != isProcStateAllowedWhileIdleOrPowerSaveMode(newUidState); @@ -4199,19 +4280,44 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (mRestrictPower) { updateRuleForRestrictPowerUL(uid); } - updateRulesForPowerRestrictionsUL(uid, procState); + updatePowerRestrictionRules = true; + } + if (mBackgroundNetworkRestricted) { + final boolean wasAllowed = isProcStateAllowedNetworkWhileBackground( + oldUidState); + final boolean isAllowed = isProcStateAllowedNetworkWhileBackground(newUidState); + if (!wasAllowed && isAllowed) { + mBackgroundTransitioningUids.delete(uid); + updateRuleForBackgroundUL(uid); + updatePowerRestrictionRules = true; + } else if (wasAllowed && !isAllowed) { + final long completionTimeMs = SystemClock.uptimeMillis() + + mBackgroundRestrictionDelayMs; + if (mBackgroundTransitioningUids.indexOfKey(uid) < 0) { + // This is just a defensive check in case the upstream code ever makes + // multiple calls for the same process state change. + mBackgroundTransitioningUids.put(uid, completionTimeMs); + } + if (!mHandler.hasMessages(MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS)) { + // Many uids may be in this "transitioning" state at the same time, so + // using one message at a time to avoid congestion in the MessageQueue. + mHandler.sendEmptyMessageAtTime( + MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS, completionTimeMs); + } + } } if (mLowPowerStandbyActive) { boolean allowedInLpsChanged = isProcStateAllowedWhileInLowPowerStandby(oldUidState) != isProcStateAllowedWhileInLowPowerStandby(newUidState); if (allowedInLpsChanged) { - if (!allowedWhileIdleOrPowerSaveModeChanged) { - updateRulesForPowerRestrictionsUL(uid, procState); - } updateRuleForLowPowerStandbyUL(uid); + updatePowerRestrictionRules = true; } } + if (updatePowerRestrictionRules) { + updateRulesForPowerRestrictionsUL(uid, procState); + } return true; } } finally { @@ -4234,6 +4340,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (mRestrictPower) { updateRuleForRestrictPowerUL(uid); } + if (mBackgroundNetworkRestricted) { + // Uid is no longer running, there is no point in any grace period of network + // access during transitions to lower importance proc-states. + mBackgroundTransitioningUids.delete(uid); + updateRuleForBackgroundUL(uid); + } updateRulesForPowerRestrictionsUL(uid); if (mLowPowerStandbyActive) { updateRuleForLowPowerStandbyUL(uid); @@ -4441,11 +4553,41 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } + /** + * Updates the rules for apps allowlisted to use network while in the background. + */ + @GuardedBy("mUidRulesFirstLock") + private void updateRulesForBackgroundChainUL() { + Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForBackgroundChainUL"); + try { + final SparseIntArray uidRules = mUidFirewallBackgroundRules; + uidRules.clear(); + + final List<UserInfo> users = mUserManager.getUsers(); + for (int ui = users.size() - 1; ui >= 0; ui--) { + final UserInfo user = users.get(ui); + updateRulesForAllowlistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id); + updateRulesForAllowlistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id); + updateRulesForAllowlistedAppIds(uidRules, mPowerSaveWhitelistExceptIdleAppIds, + user.id); + } + for (int i = mUidState.size() - 1; i >= 0; i--) { + if (mBackgroundTransitioningUids.indexOfKey(mUidState.keyAt(i)) >= 0 + || isProcStateAllowedNetworkWhileBackground(mUidState.valueAt(i))) { + uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); + } + } + setUidFirewallRulesUL(FIREWALL_CHAIN_BACKGROUND, uidRules); + } finally { + Trace.traceEnd(TRACE_TAG_NETWORK); + } + } + private void updateRulesForAllowlistedAppIds(final SparseIntArray uidRules, - final SparseBooleanArray whitelistedAppIds, int userId) { - for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) { - if (whitelistedAppIds.valueAt(i)) { - final int appId = whitelistedAppIds.keyAt(i); + final SparseBooleanArray allowlistedAppIds, int userId) { + for (int i = allowlistedAppIds.size() - 1; i >= 0; --i) { + if (allowlistedAppIds.valueAt(i)) { + final int appId = allowlistedAppIds.keyAt(i); final int uid = UserHandle.getUid(userId, appId); uidRules.put(uid, FIREWALL_RULE_ALLOW); } @@ -4504,12 +4646,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private boolean isAllowlistedFromPowerSaveUL(int uid, boolean deviceIdleMode) { final int appId = UserHandle.getAppId(uid); - boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId) + boolean allowlisted = mPowerSaveTempWhitelistAppIds.get(appId) || mPowerSaveWhitelistAppIds.get(appId); if (!deviceIdleMode) { - isWhitelisted = isWhitelisted || isAllowlistedFromPowerSaveExceptIdleUL(uid); + allowlisted = allowlisted || isAllowlistedFromPowerSaveExceptIdleUL(uid); } - return isWhitelisted; + return allowlisted; } /** @@ -4598,6 +4740,38 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } /** + * Update firewall rule for a single uid whenever there are any interesting changes in the uid. + * Currently, it is called when: + * - The uid is added to or removed from power allowlists + * - The uid undergoes a process-state change + * - A package belonging to this uid is added + * - The uid is evicted from memory + */ + @GuardedBy("mUidRulesFirstLock") + void updateRuleForBackgroundUL(int uid) { + if (!isUidValidForAllowlistRulesUL(uid)) { + return; + } + + Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForBackgroundUL: " + uid); + try { + // The uid should be absent from mUidState and mBackgroundTransitioningUids if it is + // not running when this method is called. Then, the firewall state will depend on the + // allowlist alone. This is the desired behavior. + if (isAllowlistedFromPowerSaveUL(uid, false) + || isUidExemptFromBackgroundRestrictions(uid)) { + setUidFirewallRuleUL(FIREWALL_CHAIN_BACKGROUND, uid, FIREWALL_RULE_ALLOW); + if (LOGD) Log.d(TAG, "updateRuleForBackgroundUL ALLOW " + uid); + } else { + setUidFirewallRuleUL(FIREWALL_CHAIN_BACKGROUND, uid, FIREWALL_RULE_DEFAULT); + if (LOGD) Log.d(TAG, "updateRuleForBackgroundUL " + uid + " to DEFAULT"); + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_NETWORK); + } + } + + /** * Toggle the firewall standby chain and inform listeners if the uid rules have effectively * changed. */ @@ -4644,6 +4818,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { "updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-")); } try { + if (mBackgroundNetworkRestricted) { + updateRulesForBackgroundChainUL(); + } updateRulesForAppIdleUL(); updateRulesForRestrictPowerUL(); updateRulesForRestrictBackgroundUL(); @@ -4803,6 +4980,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN); updateRuleForDeviceIdleUL(uid); updateRuleForRestrictPowerUL(uid); + if (mBackgroundNetworkRestricted) { + updateRuleForBackgroundUL(uid); + } // Update internal rules. updateRulesForPowerRestrictionsUL(uid); } @@ -4940,6 +5120,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mUidFirewallStandbyRules.delete(uid); mUidFirewallDozableRules.delete(uid); mUidFirewallPowerSaveRules.delete(uid); + mUidFirewallBackgroundRules.delete(uid); + mBackgroundTransitioningUids.delete(uid); mPowerSaveWhitelistExceptIdleAppIds.delete(uid); mPowerSaveWhitelistAppIds.delete(uid); mPowerSaveTempWhitelistAppIds.delete(uid); @@ -4973,6 +5155,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { updateRuleForDeviceIdleUL(uid); updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN); updateRuleForRestrictPowerUL(uid); + if (mBackgroundNetworkRestricted) { + updateRuleForBackgroundUL(uid); + } // If the uid has the necessary permissions, then it should be added to the restricted mode // firewall allowlist. @@ -5157,7 +5342,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * Similar to above but ignores idle state if app standby is currently disabled by parole. * * @param uid the uid of the app to update rules for - * @param oldUidRules the current rules for the uid, in order to determine if there's a change * @param isUidIdle whether uid is idle or not */ @GuardedBy("mUidRulesFirstLock") @@ -5203,6 +5387,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { newBlockedReasons |= (mLowPowerStandbyActive ? BLOCKED_REASON_LOW_POWER_STANDBY : 0); newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0); newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE); + newBlockedReasons |= mBackgroundNetworkRestricted ? BLOCKED_REASON_APP_BACKGROUND : 0; newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0); newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0); @@ -5215,6 +5400,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS); newAllowedReasons |= (isAllowlistedFromLowPowerStandbyUL(uid)) ? ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST : 0; + newAllowedReasons |= (mBackgroundNetworkRestricted + && isUidExemptFromBackgroundRestrictions(uid)) + ? ALLOWED_REASON_NOT_IN_BACKGROUND : 0; uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons & BLOCKED_METERED_REASON_MASK) | newBlockedReasons; @@ -5236,7 +5424,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { oldEffectiveBlockedReasons = previousUidBlockedState.effectiveBlockedReasons; newEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons; - uidRules = oldEffectiveBlockedReasons == newEffectiveBlockedReasons + uidRules = (oldEffectiveBlockedReasons == newEffectiveBlockedReasons) ? RULE_NONE : uidBlockedState.deriveUidRules(); } @@ -5429,6 +5617,28 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mContext.sendBroadcastAsUser(intent, UserHandle.ALL); return true; } + case MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS: { + final long now = SystemClock.uptimeMillis(); + long nextCheckTime = Long.MAX_VALUE; + synchronized (mUidRulesFirstLock) { + for (int i = mBackgroundTransitioningUids.size() - 1; i >= 0; i--) { + final long completionTimeMs = mBackgroundTransitioningUids.valueAt(i); + if (completionTimeMs > now) { + nextCheckTime = Math.min(nextCheckTime, completionTimeMs); + continue; + } + final int uid = mBackgroundTransitioningUids.keyAt(i); + mBackgroundTransitioningUids.removeAt(i); + updateRuleForBackgroundUL(uid); + updateRulesForPowerRestrictionsUL(uid, false); + } + } + if (nextCheckTime < Long.MAX_VALUE) { + mHandler.sendEmptyMessageAtTime(MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS, + nextCheckTime); + } + return true; + } case MSG_POLICIES_CHANGED: { final int uid = msg.arg1; final int policy = msg.arg2; @@ -5840,6 +6050,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mUidFirewallRestrictedModeRules.put(uid, rule); } else if (chain == FIREWALL_CHAIN_LOW_POWER_STANDBY) { mUidFirewallLowPowerStandbyModeRules.put(uid, rule); + } else if (chain == FIREWALL_CHAIN_BACKGROUND) { + mUidFirewallBackgroundRules.put(uid, rule); } try { @@ -5896,6 +6108,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { FIREWALL_RULE_DEFAULT); mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_DEFAULT); + mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, uid, + FIREWALL_RULE_DEFAULT); mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false); mLogger.meteredAllowlistChanged(uid, false); mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false); @@ -6420,10 +6634,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER; effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE; effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY; + effectiveBlockedReasons &= ~BLOCKED_REASON_APP_BACKGROUND; } if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST) != 0) { effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER; effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY; + effectiveBlockedReasons &= ~BLOCKED_REASON_APP_BACKGROUND; } if ((allowedReasons & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS) != 0) { effectiveBlockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE; @@ -6434,19 +6650,24 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if ((allowedReasons & ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST) != 0) { effectiveBlockedReasons &= ~BLOCKED_REASON_LOW_POWER_STANDBY; } + if ((allowedReasons & ALLOWED_REASON_NOT_IN_BACKGROUND) != 0) { + effectiveBlockedReasons &= ~BLOCKED_REASON_APP_BACKGROUND; + } return effectiveBlockedReasons; } static int getAllowedReasonsForProcState(int procState) { - if (procState > NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE) { - return ALLOWED_REASON_NONE; - } else if (procState <= NetworkPolicyManager.TOP_THRESHOLD_STATE) { + if (procState <= NetworkPolicyManager.TOP_THRESHOLD_STATE) { return ALLOWED_REASON_TOP | ALLOWED_REASON_FOREGROUND - | ALLOWED_METERED_REASON_FOREGROUND; - } else { - return ALLOWED_REASON_FOREGROUND | ALLOWED_METERED_REASON_FOREGROUND; + | ALLOWED_METERED_REASON_FOREGROUND | ALLOWED_REASON_NOT_IN_BACKGROUND; + } else if (procState <= NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE) { + return ALLOWED_REASON_FOREGROUND | ALLOWED_METERED_REASON_FOREGROUND + | ALLOWED_REASON_NOT_IN_BACKGROUND; + } else if (procState < NetworkPolicyManager.BACKGROUND_THRESHOLD_STATE) { + return ALLOWED_REASON_NOT_IN_BACKGROUND; } + return ALLOWED_REASON_NONE; } @Override @@ -6471,6 +6692,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { BLOCKED_REASON_APP_STANDBY, BLOCKED_REASON_RESTRICTED_MODE, BLOCKED_REASON_LOW_POWER_STANDBY, + BLOCKED_REASON_APP_BACKGROUND, BLOCKED_METERED_REASON_DATA_SAVER, BLOCKED_METERED_REASON_USER_RESTRICTED, BLOCKED_METERED_REASON_ADMIN_DISABLED, @@ -6484,6 +6706,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST, ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS, ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST, + ALLOWED_REASON_NOT_IN_BACKGROUND, ALLOWED_METERED_REASON_USER_EXEMPTED, ALLOWED_METERED_REASON_SYSTEM, ALLOWED_METERED_REASON_FOREGROUND, @@ -6503,6 +6726,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return "RESTRICTED_MODE"; case BLOCKED_REASON_LOW_POWER_STANDBY: return "LOW_POWER_STANDBY"; + case BLOCKED_REASON_APP_BACKGROUND: + return "APP_BACKGROUND"; case BLOCKED_METERED_REASON_DATA_SAVER: return "DATA_SAVER"; case BLOCKED_METERED_REASON_USER_RESTRICTED: @@ -6533,6 +6758,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return "RESTRICTED_MODE_PERMISSIONS"; case ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST: return "LOW_POWER_STANDBY_ALLOWLIST"; + case ALLOWED_REASON_NOT_IN_BACKGROUND: + return "NOT_IN_BACKGROUND"; case ALLOWED_METERED_REASON_USER_EXEMPTED: return "METERED_USER_EXEMPTED"; case ALLOWED_METERED_REASON_SYSTEM: @@ -6600,7 +6827,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { int powerBlockedReasons = BLOCKED_REASON_APP_STANDBY | BLOCKED_REASON_DOZE | BLOCKED_REASON_BATTERY_SAVER - | BLOCKED_REASON_LOW_POWER_STANDBY; + | BLOCKED_REASON_LOW_POWER_STANDBY + | BLOCKED_REASON_APP_BACKGROUND; if ((effectiveBlockedReasons & powerBlockedReasons) != 0) { uidRule |= RULE_REJECT_ALL; } else if ((blockedReasons & powerBlockedReasons) != 0) { diff --git a/services/core/java/com/android/server/net/flags.aconfig b/services/core/java/com/android/server/net/flags.aconfig new file mode 100644 index 000000000000..419665a0a5ab --- /dev/null +++ b/services/core/java/com/android/server/net/flags.aconfig @@ -0,0 +1,8 @@ +package: "com.android.server.net" + +flag { + name: "network_blocked_for_top_sleeping_and_above" + namespace: "backstage_power" + description: "Block network access for apps in a low importance background state" + bug: "304347838" +} diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index e633ba6886d0..db040932b0cb 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -8237,19 +8237,26 @@ public class NotificationManagerService extends SystemService { } } + private PendingIntent getNotificationTimeoutPendingIntent(NotificationRecord record, + int flags) { + flags |= PendingIntent.FLAG_IMMUTABLE; + return PendingIntent.getBroadcast(getContext(), + REQUEST_CODE_TIMEOUT, + new Intent(ACTION_NOTIFICATION_TIMEOUT) + .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME) + .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT) + .appendPath(record.getKey()).build()) + .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) + .putExtra(EXTRA_KEY, record.getKey()), + flags); + } + @VisibleForTesting @GuardedBy("mNotificationLock") void scheduleTimeoutLocked(NotificationRecord record) { if (record.getNotification().getTimeoutAfter() > 0) { - final PendingIntent pi = PendingIntent.getBroadcast(getContext(), - REQUEST_CODE_TIMEOUT, - new Intent(ACTION_NOTIFICATION_TIMEOUT) - .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME) - .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT) - .appendPath(record.getKey()).build()) - .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) - .putExtra(EXTRA_KEY, record.getKey()), - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + final PendingIntent pi = getNotificationTimeoutPendingIntent( + record, PendingIntent.FLAG_UPDATE_CURRENT); mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + record.getNotification().getTimeoutAfter(), pi); } @@ -8257,6 +8264,16 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting @GuardedBy("mNotificationLock") + void cancelScheduledTimeoutLocked(NotificationRecord record) { + final PendingIntent pi = getNotificationTimeoutPendingIntent( + record, PendingIntent.FLAG_CANCEL_CURRENT); + if (pi != null) { + mAlarmManager.cancel(pi); + } + } + + @VisibleForTesting + @GuardedBy("mNotificationLock") /** * Determine whether this notification should attempt to make noise, vibrate, or flash the LED * @return buzzBeepBlink - bitfield (buzz ? 1 : 0) | (beep ? 2 : 0) | (blink ? 4 : 0) @@ -9249,21 +9266,7 @@ public class NotificationManagerService extends SystemService { int rank, int count, boolean wasPosted, String listenerName, @ElapsedRealtimeLong long cancellationElapsedTimeMs) { final String canceledKey = r.getKey(); - - // Get pending intent used to create alarm, use FLAG_NO_CREATE if PendingIntent - // does not already exist, then null will be returned. - final PendingIntent pi = PendingIntent.getBroadcast(getContext(), - REQUEST_CODE_TIMEOUT, - new Intent(ACTION_NOTIFICATION_TIMEOUT) - .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT) - .appendPath(r.getKey()).build()) - .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), - PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE); - - // Cancel alarm corresponding to pi. - if (pi != null) { - mAlarmManager.cancel(pi); - } + cancelScheduledTimeoutLocked(r); // Record caller. recordCallerLocked(r); diff --git a/services/core/java/com/android/server/pm/BACKGROUND_INSTALL_OWNERS b/services/core/java/com/android/server/pm/BACKGROUND_INSTALL_OWNERS new file mode 100644 index 000000000000..baa41a55c519 --- /dev/null +++ b/services/core/java/com/android/server/pm/BACKGROUND_INSTALL_OWNERS @@ -0,0 +1,2 @@ +georgechan@google.com +wenhaowang@google.com
\ No newline at end of file diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS index 84324f2524fc..c8bc56ce7dcd 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -51,3 +51,5 @@ per-file ShortcutRequestPinProcessor.java = omakoto@google.com, yamasani@google. per-file ShortcutService.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com per-file ShortcutUser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com +# background install control service +per-file BackgroundInstall* = file:BACKGROUND_INSTALL_OWNERS
\ No newline at end of file diff --git a/services/core/java/com/android/server/pm/verify/domain/OWNERS b/services/core/java/com/android/server/pm/verify/domain/OWNERS index c669112e0512..b451fe4b1077 100644 --- a/services/core/java/com/android/server/pm/verify/domain/OWNERS +++ b/services/core/java/com/android/server/pm/verify/domain/OWNERS @@ -1,5 +1,4 @@ # Bug component: 36137 +include /PACKAGE_MANAGER_OWNERS -chiuwinson@google.com -patb@google.com -toddke@google.com
\ No newline at end of file +wloh@google.com
\ No newline at end of file diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index 9d5173a8da09..69b70341af51 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -524,6 +524,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]"); synchronized (sRequestLock) { if (!setupOrClearBcb(true, command)) { + Slog.e(TAG, "rebootRecoveryWithCommand failed to setup BCB"); return; } diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java index 141d4dcf77d0..9ee9b149529e 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemShellCommand.java @@ -48,6 +48,8 @@ public class RecoverySystemShellCommand extends ShellCommand { return isLskfCaptured(); case "reboot-and-apply": return rebootAndApply(); + case "wipe": + return wipe(); default: return handleDefaultCommands(cmd); } @@ -58,6 +60,18 @@ public class RecoverySystemShellCommand extends ShellCommand { } } + private int wipe() throws RemoteException { + PrintWriter pw = getOutPrintWriter(); + String newFsType = getNextArg(); + String command = "--wipe_data"; + if (newFsType != null && !newFsType.isEmpty()) { + command += "\n--reformat_data=" + newFsType; + } + pw.println("Rebooting into recovery with " + command.replaceAll("\n", " ")); + mService.rebootRecoveryWithCommand(command); + return 0; + } + private int requestLskf() throws RemoteException { String packageName = getNextArgRequired(); boolean success = mService.requestLskf(packageName, null); @@ -104,5 +118,6 @@ public class RecoverySystemShellCommand extends ShellCommand { pw.println(" clear-lskf"); pw.println(" is-lskf-captured <package_name>"); pw.println(" reboot-and-apply <package_name> <reason>"); + pw.println(" wipe <new filesystem type ext4/f2fs>"); } } diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index 98482b8ec700..c5b379b724b2 100644 --- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -565,8 +565,8 @@ static jstring com_android_server_am_CachedAppOptimizer_getFreezerCheckPath(JNIE } static jboolean com_android_server_am_CachedAppOptimizer_isFreezerProfileValid(JNIEnv* env) { - int uid = getuid(); - int pid = getpid(); + uid_t uid = getuid(); + pid_t pid = getpid(); return isProfileValidForProcess("Frozen", uid, pid) && isProfileValidForProcess("Unfrozen", uid, pid); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 2c3f846e6785..b14d37df9892 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -71,6 +71,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_STATUS_BAR; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SUPPORT_MESSAGE; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES; +import static android.Manifest.permission.MANAGE_DEVICE_POLICY_THREAD_NETWORK; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_TIME; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER; @@ -482,6 +483,7 @@ import com.android.internal.widget.PasswordValidationError; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import com.android.net.module.util.ProxyUtils; +import com.android.net.thread.flags.Flags; import com.android.server.AlarmManagerInternal; import com.android.server.LocalManagerRegistry; import com.android.server.LocalServices; @@ -13834,6 +13836,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { UserManager.DISALLOW_SMS, new String[]{MANAGE_DEVICE_POLICY_SMS}); USER_RESTRICTION_PERMISSIONS.put( UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS, new String[]{MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS}); + if (Flags.threadUserRestrictionEnabled()) { + USER_RESTRICTION_PERMISSIONS.put( + UserManager.DISALLOW_THREAD_NETWORK, + new String[]{MANAGE_DEVICE_POLICY_THREAD_NETWORK}); + } USER_RESTRICTION_PERMISSIONS.put( UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO, new String[]{MANAGE_DEVICE_POLICY_NEARBY_COMMUNICATION}); USER_RESTRICTION_PERMISSIONS.put( diff --git a/services/incremental/OWNERS b/services/incremental/OWNERS index 7ebb962c8feb..c18a9e5b90c3 100644 --- a/services/incremental/OWNERS +++ b/services/incremental/OWNERS @@ -1,8 +1,4 @@ # Bug component: 554432 -include /services/core/java/com/android/server/pm/OWNERS +include /PACKAGE_MANAGER_OWNERS -alexbuy@google.com -schfan@google.com -toddke@google.com -zyy@google.com -patb@google.com +zyy@google.com
\ No newline at end of file diff --git a/services/profcollect/OWNERS b/services/profcollect/OWNERS index b380e39529e3..be9e61fa298b 100644 --- a/services/profcollect/OWNERS +++ b/services/profcollect/OWNERS @@ -1,3 +1 @@ -srhines@google.com -yabinc@google.com -yikong@google.com +include platform/prebuilts/clang/host/linux-x86:/OWNERS diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java index 582b712ec3fc..fb0fbe87dab3 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -62,7 +62,7 @@ public final class ProfcollectForwardingService extends SystemService { private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG); private static final String INTENT_UPLOAD_PROFILES = "com.android.server.profcollect.UPLOAD_PROFILES"; - private static final long BG_PROCESS_PERIOD = TimeUnit.HOURS.toMillis(4); // every 4 hours. + private static final long BG_PROCESS_INTERVAL = TimeUnit.HOURS.toMillis(4); // every 4 hours. private IProfCollectd mIProfcollect; private static ProfcollectForwardingService sSelfService; @@ -226,7 +226,7 @@ public final class ProfcollectForwardingService extends SystemService { js.schedule(new JobInfo.Builder(JOB_IDLE_PROCESS, JOB_SERVICE_NAME) .setRequiresDeviceIdle(true) .setRequiresCharging(true) - .setPeriodic(BG_PROCESS_PERIOD) + .setPeriodic(BG_PROCESS_INTERVAL) .setPriority(JobInfo.PRIORITY_MIN) .build()); } diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index 27fd8a66fff1..5cce1c2f6234 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -68,6 +68,7 @@ android_test { "coretests-aidl", "securebox", "flag-junit", + "net_flags_lib", ], libs: [ diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java index 5a62d92e8e12..5081198f0058 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java @@ -16,6 +16,8 @@ package com.android.server.locksettings; +import static android.security.Flags.FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS; + import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; @@ -30,25 +32,30 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.PropertyInvalidatedCache; +import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; +import android.platform.test.flag.junit.SetFlagsRule; import android.service.gatekeeper.GateKeeperResponse; import android.text.TextUtils; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.widget.ILockSettingsStateListener; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.VerifyCredentialResponse; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -59,6 +66,7 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(AndroidJUnit4.class) public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Before public void setUp() { @@ -399,6 +407,60 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { } @Test + public void testVerifyCredential_notifyLockSettingsStateListeners_whenGoodPassword() + throws Exception { + mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS); + final LockscreenCredential password = newPassword("password"); + setCredential(PRIMARY_USER_ID, password); + final ILockSettingsStateListener listener = mockLockSettingsStateListener(); + mLocalService.registerLockSettingsStateListener(listener); + + assertEquals(VerifyCredentialResponse.RESPONSE_OK, + mService.verifyCredential(password, PRIMARY_USER_ID, 0 /* flags */) + .getResponseCode()); + + verify(listener).onAuthenticationSucceeded(PRIMARY_USER_ID); + } + + @Test + public void testVerifyCredential_notifyLockSettingsStateListeners_whenBadPassword() + throws Exception { + mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS); + final LockscreenCredential password = newPassword("password"); + setCredential(PRIMARY_USER_ID, password); + final LockscreenCredential badPassword = newPassword("badPassword"); + final ILockSettingsStateListener listener = mockLockSettingsStateListener(); + mLocalService.registerLockSettingsStateListener(listener); + + assertEquals(VerifyCredentialResponse.RESPONSE_ERROR, + mService.verifyCredential(badPassword, PRIMARY_USER_ID, 0 /* flags */) + .getResponseCode()); + + verify(listener).onAuthenticationFailed(PRIMARY_USER_ID); + } + + @Test + public void testLockSettingsStateListener_registeredThenUnregistered() throws Exception { + mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS); + final LockscreenCredential password = newPassword("password"); + setCredential(PRIMARY_USER_ID, password); + final LockscreenCredential badPassword = newPassword("badPassword"); + final ILockSettingsStateListener listener = mockLockSettingsStateListener(); + + mLocalService.registerLockSettingsStateListener(listener); + assertEquals(VerifyCredentialResponse.RESPONSE_OK, + mService.verifyCredential(password, PRIMARY_USER_ID, 0 /* flags */) + .getResponseCode()); + verify(listener).onAuthenticationSucceeded(PRIMARY_USER_ID); + + mLocalService.unregisterLockSettingsStateListener(listener); + assertEquals(VerifyCredentialResponse.RESPONSE_ERROR, + mService.verifyCredential(badPassword, PRIMARY_USER_ID, 0 /* flags */) + .getResponseCode()); + verify(listener, never()).onAuthenticationFailed(PRIMARY_USER_ID); + } + + @Test public void testSetCredentialNotPossibleInSecureFrpModeDuringSuw() { setUserSetupComplete(false); setSecureFrpMode(true); @@ -537,4 +599,12 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { assertNotEquals(0, mGateKeeperService.getSecureUserId(userId)); } } + + private ILockSettingsStateListener mockLockSettingsStateListener() { + ILockSettingsStateListener listener = mock(ILockSettingsStateListener.Stub.class); + IBinder binder = mock(IBinder.class); + when(binder.isBinderAlive()).thenReturn(true); + when(listener.asBinder()).thenReturn(binder); + return listener; + } } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java index eca19c8e8c4d..2da2f50447c7 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java @@ -506,6 +506,14 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { } @Test + public void testUnlockUserWithTokenWithBadHandleReturnsFalse() { + final long badTokenHandle = 123456789; + final byte[] token = "some-high-entropy-secure-token".getBytes(); + mService.initializeSyntheticPassword(PRIMARY_USER_ID); + assertFalse(mLocalService.unlockUserWithToken(badTokenHandle, token, PRIMARY_USER_ID)); + } + + @Test public void testGetHashFactorPrimaryUser() throws RemoteException { LockscreenCredential password = newPassword("password"); initSpAndSetCredential(PRIMARY_USER_ID, password); diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java index 13dc12032e7d..d6d2b6d9abd2 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java @@ -16,6 +16,7 @@ package com.android.server.net; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; @@ -327,12 +328,20 @@ public class NetworkManagementServiceTest { isRestrictedForLowPowerStandby.put(INetd.FIREWALL_RULE_DENY, true); expected.put(FIREWALL_CHAIN_LOW_POWER_STANDBY, isRestrictedForLowPowerStandby); + // Background chain + final ArrayMap<Integer, Boolean> isRestrictedInBackground = new ArrayMap<>(); + isRestrictedInBackground.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true); + isRestrictedInBackground.put(INetd.FIREWALL_RULE_ALLOW, false); + isRestrictedInBackground.put(INetd.FIREWALL_RULE_DENY, true); + expected.put(FIREWALL_CHAIN_BACKGROUND, isRestrictedInBackground); + final int[] chains = { FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_POWERSAVE, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_RESTRICTED, - FIREWALL_CHAIN_LOW_POWER_STANDBY + FIREWALL_CHAIN_LOW_POWER_STANDBY, + FIREWALL_CHAIN_BACKGROUND }; final int[] states = { INetd.FIREWALL_RULE_ALLOW, diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index 2a764526a436..4451cae8db42 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -26,12 +26,14 @@ import static android.app.ActivityManager.PROCESS_STATE_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; +import static android.net.ConnectivityManager.BLOCKED_REASON_APP_BACKGROUND; import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY; import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE; import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; import static android.net.ConnectivityManager.TYPE_MOBILE; @@ -48,8 +50,13 @@ import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM; import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND; import static android.net.NetworkPolicyManager.ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST; import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_NOT_IN_BACKGROUND; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS; import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM; import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP; +import static android.net.NetworkPolicyManager.BACKGROUND_THRESHOLD_STATE; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.POLICY_NONE; @@ -64,6 +71,7 @@ import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkTemplate.MATCH_CARRIER; import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.MATCH_WIFI; +import static android.os.PowerExemptionManager.REASON_OTHER; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED; import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT; @@ -146,6 +154,8 @@ import android.os.Build; import android.os.Handler; import android.os.INetworkManagementService; import android.os.PersistableBundle; +import android.os.PowerExemptionManager; +import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.RemoteException; @@ -153,6 +163,9 @@ import android.os.SimpleClock; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -169,6 +182,7 @@ import android.util.Pair; import android.util.Range; import android.util.RecurrenceRule; import android.util.SparseArray; +import android.util.SparseIntArray; import androidx.test.InstrumentationRegistry; import androidx.test.filters.FlakyTest; @@ -243,6 +257,9 @@ import java.util.stream.Collectors; public class NetworkPolicyManagerServiceTest { private static final String TAG = "NetworkPolicyManagerServiceTest"; + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + private static final long TEST_START = 1194220800000L; private static final String TEST_IFACE = "test0"; private static final String TEST_WIFI_NETWORK_KEY = "TestWifiNetworkKey"; @@ -285,6 +302,7 @@ public class NetworkPolicyManagerServiceTest { private @Mock TelephonyManager mTelephonyManager; private @Mock UserManager mUserManager; private @Mock NetworkStatsManager mStatsManager; + private @Mock PowerExemptionManager mPowerExemptionManager; private TestDependencies mDeps; private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor = @@ -302,6 +320,7 @@ public class NetworkPolicyManagerServiceTest { private NetworkPolicyManagerService mService; private final ArraySet<BroadcastReceiver> mRegisteredReceivers = new ArraySet<>(); + private BroadcastReceiver mPowerAllowlistReceiver; /** * In some of the tests while initializing NetworkPolicyManagerService, @@ -446,6 +465,7 @@ public class NetworkPolicyManagerServiceTest { @Before public void callSystemReady() throws Exception { MockitoAnnotations.initMocks(this); + when(mPowerExemptionManager.getAllowListedAppIds(anyBoolean())).thenReturn(new int[0]); final Context context = InstrumentationRegistry.getContext(); @@ -482,6 +502,8 @@ public class NetworkPolicyManagerServiceTest { return mUserManager; case Context.NETWORK_STATS_SERVICE: return mStatsManager; + case Context.POWER_EXEMPTION_SERVICE: + return mPowerExemptionManager; default: return super.getSystemService(name); } @@ -495,6 +517,9 @@ public class NetworkPolicyManagerServiceTest { @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { + if (filter.hasAction(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED)) { + mPowerAllowlistReceiver = receiver; + } mRegisteredReceivers.add(receiver); return super.registerReceiver(receiver, filter, broadcastPermission, scheduler); } @@ -2066,6 +2091,12 @@ public class NetworkPolicyManagerServiceTest { expectHasUseRestrictedNetworksPermission(UID_A, true); expectHasUseRestrictedNetworksPermission(UID_B, false); + // Set low enough proc-states to ensure these uids are allowed in the background chain. + // To maintain clean separation between separate firewall chains, the tests could + // check for the specific blockedReasons in the uidBlockedState. + callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE - 1, 21); + callAndWaitOnUidStateChanged(UID_B, BACKGROUND_THRESHOLD_STATE - 1, 21); + Map<Integer, Integer> firewallUidRules = new ArrayMap<>(); doAnswer(arg -> { int[] uids = arg.getArgument(1); @@ -2113,7 +2144,111 @@ public class NetworkPolicyManagerServiceTest { } @Test + @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) + public void testBackgroundChainEnabled() throws Exception { + verify(mNetworkManager).setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, true); + } + + + @Test + @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) + public void testBackgroundChainOnProcStateChange() throws Exception { + // initialization calls setFirewallChainEnabled, so we want to reset the invocations. + clearInvocations(mNetworkManager); + + mService.mBackgroundRestrictionDelayMs = 500; // To avoid waiting too long in tests. + + // The app will be blocked when there is no prior proc-state. + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + + int procStateSeq = 23; + callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE - 1, procStateSeq++); + + verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A, + FIREWALL_RULE_ALLOW); + assertFalse(mService.isUidNetworkingBlocked(UID_A, false)); + + callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE + 1, procStateSeq++); + + // The app should be blocked after a delay. Posting a message just after the delay and + // waiting for it to complete to ensure that the blocking code has executed. + waitForDelayedMessageOnHandler(mService.mBackgroundRestrictionDelayMs + 1); + + verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A, + FIREWALL_RULE_DEFAULT); + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) + public void testBackgroundChainOnAllowlistChange() throws Exception { + // initialization calls setFirewallChainEnabled, so we want to reset the invocations. + clearInvocations(mNetworkManager); + + // The apps will be blocked when there is no prior proc-state. + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + assertTrue(mService.isUidNetworkingBlocked(UID_B, false)); + + final int procStateSeq = 29; + callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE + 1, procStateSeq); + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + + when(mPowerExemptionManager.getAllowListedAppIds(anyBoolean())) + .thenReturn(new int[]{APP_ID_A, APP_ID_B}); + final SparseIntArray firewallUidRules = new SparseIntArray(); + doAnswer(arg -> { + final int[] uids = arg.getArgument(1); + final int[] rules = arg.getArgument(2); + assertTrue(uids.length == rules.length); + + for (int i = 0; i < uids.length; ++i) { + firewallUidRules.put(uids[i], rules[i]); + } + return null; + }).when(mNetworkManager).setFirewallUidRules(eq(FIREWALL_CHAIN_BACKGROUND), + any(int[].class), any(int[].class)); + + mPowerAllowlistReceiver.onReceive(mServiceContext, null); + + assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_A, -1)); + assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_B, -1)); + + assertFalse(mService.isUidNetworkingBlocked(UID_A, false)); + assertFalse(mService.isUidNetworkingBlocked(UID_B, false)); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) + public void testBackgroundChainOnTempAllowlistChange() throws Exception { + // initialization calls setFirewallChainEnabled, so we want to reset the invocations. + clearInvocations(mNetworkManager); + + // The app will be blocked as is no prior proc-state. + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + + final int procStateSeq = 19; + callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE + 1, procStateSeq); + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + + final NetworkPolicyManagerInternal internal = LocalServices.getService( + NetworkPolicyManagerInternal.class); + + internal.onTempPowerSaveWhitelistChange(APP_ID_A, true, REASON_OTHER, "testing"); + + verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A, + FIREWALL_RULE_ALLOW); + assertFalse(mService.isUidNetworkingBlocked(UID_A, false)); + + internal.onTempPowerSaveWhitelistChange(APP_ID_A, false, REASON_OTHER, "testing"); + + verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A, + FIREWALL_RULE_DEFAULT); + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + } + + @Test public void testLowPowerStandbyAllowlist() throws Exception { + // Chain background is also enabled but these procstates are important enough to be exempt. callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 0); callAndWaitOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0); callAndWaitOnUidStateChanged(UID_C, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0); @@ -2200,7 +2335,21 @@ public class NetworkPolicyManagerServiceTest { ALLOWED_REASON_TOP), BLOCKED_REASON_NONE); effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY, ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST), BLOCKED_REASON_NONE); - // TODO: test more combinations of blocked reasons. + + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND, + ALLOWED_REASON_NOT_IN_BACKGROUND), BLOCKED_REASON_NONE); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND + | BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_NOT_IN_BACKGROUND), + BLOCKED_REASON_BATTERY_SAVER); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND + | BLOCKED_REASON_DOZE, ALLOWED_REASON_NOT_IN_BACKGROUND), + BLOCKED_REASON_DOZE); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND, + ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS), BLOCKED_REASON_APP_BACKGROUND); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND, + ALLOWED_REASON_POWER_SAVE_ALLOWLIST), BLOCKED_REASON_NONE); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND, + ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST), BLOCKED_REASON_NONE); for (Map.Entry<Pair<Integer, Integer>, Integer> test : effectiveBlockedReasons.entrySet()) { final int expectedEffectiveBlockedReasons = test.getValue(); @@ -2529,7 +2678,6 @@ public class NetworkPolicyManagerServiceTest { private FutureIntent mRestrictBackgroundChanged; private void postMsgAndWaitForCompletion() throws InterruptedException { - final Handler handler = mService.getHandlerForTesting(); final CountDownLatch latch = new CountDownLatch(1); mService.getHandlerForTesting().post(latch::countDown); if (!latch.await(5, TimeUnit.SECONDS)) { @@ -2537,6 +2685,14 @@ public class NetworkPolicyManagerServiceTest { } } + private void waitForDelayedMessageOnHandler(long delayMs) throws InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + mService.getHandlerForTesting().postDelayed(latch::countDown, delayMs); + if (!latch.await(delayMs + 5_000, TimeUnit.MILLISECONDS)) { + fail("Timed out waiting for delayed msg to be handled"); + } + } + private void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage) throws InterruptedException { mService.setSubscriptionPlans(subId, plans, 0, callingPackage); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 6a6fa3f91a22..189dbdc07087 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1104,6 +1104,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mAlarmManager).setExactAndAllowWhileIdle(anyInt(), anyLong(), captor.capture()); assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME, captor.getValue().getIntent().getPackage()); + + mService.cancelScheduledTimeoutLocked(r); + verify(mAlarmManager).cancel(captor.capture()); + assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME, + captor.getValue().getIntent().getPackage()); } @Test diff --git a/tools/aapt/ApkBuilder.h b/tools/aapt/ApkBuilder.h index 5d3abc63519f..92764020b120 100644 --- a/tools/aapt/ApkBuilder.h +++ b/tools/aapt/ApkBuilder.h @@ -44,7 +44,7 @@ public: android::status_t createSplitForConfigs(const std::set<ConfigDescription>& configs); /** - * Adds a file to be written to the final APK. It's name must not collide + * Adds a file to be written to the final APK. Its name must not collide * with that of any files previously added. When a Split APK is being * generated, duplicates can exist as long as they are in different splits * (resources.arsc, AndroidManifest.xml). diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index 2f2ef92e72b4..66a05101c2a1 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -187,7 +187,7 @@ void usage(void) " be loaded alongside the base APK at runtime.\n" " --feature-of\n" " Builds a split APK that is a feature of the apk specified here. Resources\n" - " in the base APK can be referenced from the the feature APK.\n" + " in the base APK can be referenced from the feature APK.\n" " --feature-after\n" " An app can have multiple Feature Split APKs which must be totally ordered.\n" " If --feature-of is specified, this flag specifies which Feature Split APK\n" diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index 40cba3ed316f..bca77978c502 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -236,3 +236,39 @@ genrule { ], }, } + +cc_genrule { + name: "aapt2_results", + srcs: [ + ":aapt2_tests", + "integration-tests/CompileTest/**/*", + "integration-tests/CommandTests/**/*", + "integration-tests/ConvertTest/**/*", + "integration-tests/DumpTest/**/*", + ], + host_supported: true, + device_supported: false, + target: { + windows: { + compile_multilib: "64", + }, + }, + out: ["result.xml"], + cmd: "mkdir -p $(genDir)/integration-tests/CompileTest/ && " + + "cp $(locations integration-tests/CompileTest/**/*) $(genDir)/integration-tests/CompileTest/ && " + + "mkdir -p $(genDir)/integration-tests/CommandTests/ && " + + "cp $(locations integration-tests/CommandTests/**/*) $(genDir)/integration-tests/CompileTest/ && " + + "mkdir -p $(genDir)/integration-tests/ConvertTest/ && " + + "cp $(locations integration-tests/ConvertTest/**/*) $(genDir)/integration-tests/ConvertTest/ && " + + "mkdir -p $(genDir)/integration-tests/DumpTest/ && " + + "cp $(locations integration-tests/DumpTest/**/*) $(genDir)/integration-tests/DumpTest/ && " + + "cp $(locations :aapt2_tests) $(genDir)/ && " + + "$(genDir)/aapt2_tests " + + "--gtest_output=xml:$(out) " + + ">/dev/null 2>&1 ; true", +} + +phony_rule { + name: "aapt2_run_host_unit_tests", + phony_deps: ["aapt2_results"], +} diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk index 34a1b112d880..15ae2baa73df 100644 --- a/tools/aapt2/Android.mk +++ b/tools/aapt2/Android.mk @@ -1,22 +1,4 @@ -LOCAL_PATH := $(call my-dir) - include $(CLEAR_VARS) - -aapt2_results := $(call intermediates-dir-for,PACKAGING,aapt2_run_host_unit_tests)/result.xml - -# Target for running host unit tests on post/pre-submit. -.PHONY: aapt2_run_host_unit_tests -aapt2_run_host_unit_tests: $(aapt2_results) - -$(call dist-for-goals,aapt2_run_host_unit_tests,$(aapt2_results):gtest/aapt2_host_unit_tests_result.xml) - -# Always run the tests again, even if they haven't changed -$(aapt2_results): .KATI_IMPLICIT_OUTPUTS := $(aapt2_results)-nocache -$(aapt2_results): $(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests - -$(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests --gtest_output=xml:$@ > /dev/null 2>&1 - +aapt2_results := ./out/soong/.intermediates/frameworks/base/tools/aapt2/aapt2_results $(call declare-1p-target,$(aapt2_results)) - aapt2_results := - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index cf4dd79e3d96..c739d7732d7f 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -56,6 +56,7 @@ #include "java/JavaClassGenerator.h" #include "java/ManifestClassGenerator.h" #include "java/ProguardRules.h" +#include "link/FeatureFlagsFilter.h" #include "link/Linkers.h" #include "link/ManifestFixer.h" #include "link/NoDefaultResourceRemover.h" @@ -1986,6 +1987,21 @@ class Linker { context_->SetNameManglerPolicy(NameManglerPolicy{context_->GetCompilationPackage()}); context_->SetSplitNameDependencies(app_info_.split_name_dependencies); + std::unique_ptr<xml::XmlResource> pre_flags_filter_manifest_xml = manifest_xml->Clone(); + + FeatureFlagsFilterOptions flags_filter_options; + if (context_->GetMinSdkVersion() > SDK_UPSIDE_DOWN_CAKE) { + // For API version > U, PackageManager will dynamically read the flag values and disable + // manifest elements accordingly when parsing the manifest. + // For API version <= U, we remove disabled elements from the manifest with the filter. + flags_filter_options.remove_disabled_elements = false; + flags_filter_options.flags_must_have_value = false; + } + FeatureFlagsFilter flags_filter(options_.feature_flag_values, flags_filter_options); + if (!flags_filter.Consume(context_, manifest_xml.get())) { + return 1; + } + // Override the package ID when it is "android". if (context_->GetCompilationPackage() == "android") { context_->SetPackageId(kAndroidPackageId); @@ -2282,7 +2298,12 @@ class Linker { } if (options_.generate_java_class_path) { - if (!WriteManifestJavaFile(manifest_xml.get())) { + // The FeatureFlagsFilter may remove <permission> and <permission-group> elements that + // generate constants in the Manifest Java file. While we want those permissions and + // permission groups removed in the SDK (i.e., if a feature flag is disabled), the + // constants should still remain so that code referencing it (e.g., within a feature + // flag check) will still compile. Therefore we use the manifest XML before the filter. + if (!WriteManifestJavaFile(pre_flags_filter_manifest_xml.get())) { error = true; } } @@ -2530,7 +2551,7 @@ int LinkCommand::Action(const std::vector<std::string>& args) { } for (const std::string& arg : all_feature_flags_args) { - if (ParseFeatureFlagsParameter(arg, context.GetDiagnostics(), &options_.feature_flag_values)) { + if (!ParseFeatureFlagsParameter(arg, context.GetDiagnostics(), &options_.feature_flag_values)) { return 1; } } diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h index 26713fd92264..dc18b1ccda60 100644 --- a/tools/aapt2/cmd/Link.h +++ b/tools/aapt2/cmd/Link.h @@ -330,7 +330,11 @@ class LinkCommand : public Command { "should only be used together with the --static-lib flag.", &options_.merge_only); AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_); - AddOptionalFlagList("--feature-flags", "Placeholder, to be implemented.", &feature_flags_args_); + AddOptionalFlagList("--feature-flags", + "Specify the values of feature flags. The pairs in the argument\n" + "are separated by ',' and the name is separated from the value by '='.\n" + "Example: \"flag1=true,flag2=false,flag3=\" (flag3 has no given value).", + &feature_flags_args_); } int Action(const std::vector<std::string>& args) override; diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp index 725a1b86f616..10d0b1f3a2e6 100644 --- a/tools/aapt2/cmd/Link_test.cpp +++ b/tools/aapt2/cmd/Link_test.cpp @@ -16,11 +16,10 @@ #include "Link.h" -#include <android-base/file.h> - -#include "AppInfo.h" #include "Diagnostics.h" #include "LoadedApk.h" +#include "android-base/file.h" +#include "android-base/stringprintf.h" #include "test/Test.h" using testing::Eq; @@ -993,4 +992,221 @@ TEST_F(LinkTest, LocaleConfigWrongLocaleFormat) { ASSERT_FALSE(Link(link_args, &diag)); } +static void BuildSDKWithFeatureFlagAttr(const std::string& apk_path, const std::string& java_path, + CommandTestFixture* fixture, android::IDiagnostics* diag) { + const std::string android_values = + R"(<resources> + <staging-public-group type="attr" first-id="0x01fe0063"> + <public name="featureFlag" /> + </staging-public-group> + <attr name="featureFlag" format="string" /> + </resources>)"; + + SourceXML source_xml{.res_file_path = "/res/values/values.xml", .file_contents = android_values}; + BuildSDK({source_xml}, apk_path, java_path, fixture, diag); +} + +TEST_F(LinkTest, FeatureFlagDisabled_SdkAtMostUDC) { + StdErrDiagnostics diag; + const std::string android_apk = GetTestPath("android.apk"); + const std::string android_java = GetTestPath("android-java"); + BuildSDKWithFeatureFlagAttr(android_apk, android_java, this, &diag); + + const std::string manifest_contents = android::base::StringPrintf( + R"(<uses-sdk android:minSdkVersion="%d" />" + <permission android:name="FOO" android:featureFlag="flag" />)", + SDK_UPSIDE_DOWN_CAKE); + auto app_manifest = ManifestBuilder(this) + .SetPackageName("com.example.app") + .AddContents(manifest_contents) + .Build(); + + const std::string app_java = GetTestPath("app-java"); + auto app_link_args = LinkCommandBuilder(this) + .SetManifestFile(app_manifest) + .AddParameter("-I", android_apk) + .AddParameter("--java", app_java) + .AddParameter("--feature-flags", "flag=false"); + + const std::string app_apk = GetTestPath("app.apk"); + BuildApk({}, app_apk, std::move(app_link_args), this, &diag); + + // Permission element should be removed if flag is disabled + auto apk = LoadedApk::LoadApkFromPath(app_apk, &diag); + ASSERT_THAT(apk, NotNull()); + auto apk_manifest = apk->GetManifest(); + ASSERT_THAT(apk_manifest, NotNull()); + auto root = apk_manifest->root.get(); + ASSERT_THAT(root, NotNull()); + auto maybe_removed = root->FindChild({}, "permission"); + ASSERT_THAT(maybe_removed, IsNull()); + + // Code for the permission should be generated even if the element is removed + const std::string manifest_java = app_java + "/com/example/app/Manifest.java"; + std::string manifest_java_contents; + ASSERT_TRUE(android::base::ReadFileToString(manifest_java, &manifest_java_contents)); + EXPECT_THAT(manifest_java_contents, HasSubstr(" public static final String FOO=\"FOO\";")); +} + +TEST_F(LinkTest, FeatureFlagEnabled_SdkAtMostUDC) { + StdErrDiagnostics diag; + const std::string android_apk = GetTestPath("android.apk"); + const std::string android_java = GetTestPath("android-java"); + BuildSDKWithFeatureFlagAttr(android_apk, android_java, this, &diag); + + const std::string manifest_contents = android::base::StringPrintf( + R"(<uses-sdk android:minSdkVersion="%d" />" + <permission android:name="FOO" android:featureFlag="flag" />)", + SDK_UPSIDE_DOWN_CAKE); + auto app_manifest = ManifestBuilder(this) + .SetPackageName("com.example.app") + .AddContents(manifest_contents) + .Build(); + + auto app_link_args = LinkCommandBuilder(this) + .SetManifestFile(app_manifest) + .AddParameter("-I", android_apk) + .AddParameter("--feature-flags", "flag=true"); + + const std::string app_apk = GetTestPath("app.apk"); + BuildApk({}, app_apk, std::move(app_link_args), this, &diag); + + // Permission element should be kept if flag is enabled + auto apk = LoadedApk::LoadApkFromPath(app_apk, &diag); + ASSERT_THAT(apk, NotNull()); + auto apk_manifest = apk->GetManifest(); + ASSERT_THAT(apk_manifest, NotNull()); + auto root = apk_manifest->root.get(); + ASSERT_THAT(root, NotNull()); + auto maybe_removed = root->FindChild({}, "permission"); + ASSERT_THAT(maybe_removed, NotNull()); +} + +TEST_F(LinkTest, FeatureFlagWithNoValue_SdkAtMostUDC) { + StdErrDiagnostics diag; + const std::string android_apk = GetTestPath("android.apk"); + const std::string android_java = GetTestPath("android-java"); + BuildSDKWithFeatureFlagAttr(android_apk, android_java, this, &diag); + + const std::string manifest_contents = android::base::StringPrintf( + R"(<uses-sdk android:minSdkVersion="%d" />" + <permission android:name="FOO" android:featureFlag="flag" />)", + SDK_UPSIDE_DOWN_CAKE); + auto app_manifest = ManifestBuilder(this) + .SetPackageName("com.example.app") + .AddContents(manifest_contents) + .Build(); + + auto app_link_args = LinkCommandBuilder(this) + .SetManifestFile(app_manifest) + .AddParameter("-I", android_apk) + .AddParameter("--feature-flags", "flag="); + + // Flags must have values if <= UDC + const std::string app_apk = GetTestPath("app.apk"); + ASSERT_FALSE(Link(app_link_args.Build(app_apk), &diag)); +} + +TEST_F(LinkTest, FeatureFlagDisabled_SdkAfterUDC) { + StdErrDiagnostics diag; + const std::string android_apk = GetTestPath("android.apk"); + const std::string android_java = GetTestPath("android-java"); + BuildSDKWithFeatureFlagAttr(android_apk, android_java, this, &diag); + + const std::string manifest_contents = android::base::StringPrintf( + R"(<uses-sdk android:minSdkVersion="%d" />" + <permission android:name="FOO" android:featureFlag="flag" />)", + SDK_CUR_DEVELOPMENT); + auto app_manifest = ManifestBuilder(this) + .SetPackageName("com.example.app") + .AddContents(manifest_contents) + .Build(); + + auto app_link_args = LinkCommandBuilder(this) + .SetManifestFile(app_manifest) + .AddParameter("-I", android_apk) + .AddParameter("--feature-flags", "flag=false"); + + const std::string app_apk = GetTestPath("app.apk"); + BuildApk({}, app_apk, std::move(app_link_args), this, &diag); + + // Permission element should be kept if > UDC, regardless of flag value + auto apk = LoadedApk::LoadApkFromPath(app_apk, &diag); + ASSERT_THAT(apk, NotNull()); + auto apk_manifest = apk->GetManifest(); + ASSERT_THAT(apk_manifest, NotNull()); + auto root = apk_manifest->root.get(); + ASSERT_THAT(root, NotNull()); + auto maybe_removed = root->FindChild({}, "permission"); + ASSERT_THAT(maybe_removed, NotNull()); +} + +TEST_F(LinkTest, FeatureFlagEnabled_SdkAfterUDC) { + StdErrDiagnostics diag; + const std::string android_apk = GetTestPath("android.apk"); + const std::string android_java = GetTestPath("android-java"); + BuildSDKWithFeatureFlagAttr(android_apk, android_java, this, &diag); + + const std::string manifest_contents = android::base::StringPrintf( + R"(<uses-sdk android:minSdkVersion="%d" />" + <permission android:name="FOO" android:featureFlag="flag" />)", + SDK_CUR_DEVELOPMENT); + auto app_manifest = ManifestBuilder(this) + .SetPackageName("com.example.app") + .AddContents(manifest_contents) + .Build(); + + auto app_link_args = LinkCommandBuilder(this) + .SetManifestFile(app_manifest) + .AddParameter("-I", android_apk) + .AddParameter("--feature-flags", "flag=true"); + + const std::string app_apk = GetTestPath("app.apk"); + BuildApk({}, app_apk, std::move(app_link_args), this, &diag); + + // Permission element should be kept if > UDC, regardless of flag value + auto apk = LoadedApk::LoadApkFromPath(app_apk, &diag); + ASSERT_THAT(apk, NotNull()); + auto apk_manifest = apk->GetManifest(); + ASSERT_THAT(apk_manifest, NotNull()); + auto root = apk_manifest->root.get(); + ASSERT_THAT(root, NotNull()); + auto maybe_removed = root->FindChild({}, "permission"); + ASSERT_THAT(maybe_removed, NotNull()); +} + +TEST_F(LinkTest, FeatureFlagWithNoValue_SdkAfterUDC) { + StdErrDiagnostics diag; + const std::string android_apk = GetTestPath("android.apk"); + const std::string android_java = GetTestPath("android-java"); + BuildSDKWithFeatureFlagAttr(android_apk, android_java, this, &diag); + + const std::string manifest_contents = android::base::StringPrintf( + R"(<uses-sdk android:minSdkVersion="%d" />" + <permission android:name="FOO" android:featureFlag="flag" />)", + SDK_CUR_DEVELOPMENT); + auto app_manifest = ManifestBuilder(this) + .SetPackageName("com.example.app") + .AddContents(manifest_contents) + .Build(); + + auto app_link_args = LinkCommandBuilder(this) + .SetManifestFile(app_manifest) + .AddParameter("-I", android_apk) + .AddParameter("--feature-flags", "flag="); + + const std::string app_apk = GetTestPath("app.apk"); + BuildApk({}, app_apk, std::move(app_link_args), this, &diag); + + // Permission element should be kept if > UDC, regardless of flag value + auto apk = LoadedApk::LoadApkFromPath(app_apk, &diag); + ASSERT_THAT(apk, NotNull()); + auto apk_manifest = apk->GetManifest(); + ASSERT_THAT(apk_manifest, NotNull()); + auto root = apk_manifest->root.get(); + ASSERT_THAT(root, NotNull()); + auto maybe_removed = root->FindChild({}, "permission"); + ASSERT_THAT(maybe_removed, NotNull()); +} + } // namespace aapt diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp index 93c1b61f9a57..02e4beaed949 100644 --- a/tools/aapt2/util/Files.cpp +++ b/tools/aapt2/util/Files.cpp @@ -251,10 +251,13 @@ bool AppendArgsFromFile(StringPiece path, std::vector<std::string>* out_arglist, return false; } - for (StringPiece line : util::Tokenize(contents, ' ')) { + for (StringPiece line : util::Tokenize(contents, '\n')) { line = util::TrimWhitespace(line); - if (!line.empty()) { - out_arglist->emplace_back(line); + for (StringPiece arg : util::Tokenize(line, ' ')) { + arg = util::TrimWhitespace(arg); + if (!arg.empty()) { + out_arglist->emplace_back(arg); + } } } return true; @@ -270,10 +273,13 @@ bool AppendSetArgsFromFile(StringPiece path, std::unordered_set<std::string>* ou return false; } - for (StringPiece line : util::Tokenize(contents, ' ')) { + for (StringPiece line : util::Tokenize(contents, '\n')) { line = util::TrimWhitespace(line); - if (!line.empty()) { - out_argset->emplace(line); + for (StringPiece arg : util::Tokenize(line, ' ')) { + arg = util::TrimWhitespace(arg); + if (!arg.empty()) { + out_argset->emplace(arg); + } } } return true; diff --git a/tools/aapt2/util/Files_test.cpp b/tools/aapt2/util/Files_test.cpp index 6c380808c0df..618a3e0d86ae 100644 --- a/tools/aapt2/util/Files_test.cpp +++ b/tools/aapt2/util/Files_test.cpp @@ -25,6 +25,9 @@ using ::android::base::StringPrintf; +using ::testing::ElementsAre; +using ::testing::UnorderedElementsAre; + namespace aapt { namespace file { @@ -34,9 +37,11 @@ constexpr const char sTestDirSep = '\\'; constexpr const char sTestDirSep = '/'; #endif -class FilesTest : public ::testing::Test { +class FilesTest : public TestDirectoryFixture { public: void SetUp() override { + TestDirectoryFixture::SetUp(); + std::stringstream builder; builder << "hello" << sDirSep << "there"; expected_path_ = builder.str(); @@ -66,6 +71,42 @@ TEST_F(FilesTest, AppendPathWithLeadingOrTrailingSeparators) { EXPECT_EQ(expected_path_, base); } +TEST_F(FilesTest, AppendArgsFromFile) { + const std::string args_file = GetTestPath("args.txt"); + WriteFile(args_file, + " \n" + "arg1 arg2 arg3 \n" + " arg4 arg5"); + std::vector<std::string> args; + std::string error; + ASSERT_TRUE(AppendArgsFromFile(args_file, &args, &error)); + EXPECT_THAT(args, ElementsAre("arg1", "arg2", "arg3", "arg4", "arg5")); +} + +TEST_F(FilesTest, AppendArgsFromFile_InvalidFile) { + std::vector<std::string> args; + std::string error; + ASSERT_FALSE(AppendArgsFromFile(GetTestPath("not_found.txt"), &args, &error)); +} + +TEST_F(FilesTest, AppendSetArgsFromFile) { + const std::string args_file = GetTestPath("args.txt"); + WriteFile(args_file, + " \n" + "arg2 arg4 arg1 \n" + " arg5 arg3"); + std::unordered_set<std::string> args; + std::string error; + ASSERT_TRUE(AppendSetArgsFromFile(args_file, &args, &error)); + EXPECT_THAT(args, UnorderedElementsAre("arg1", "arg2", "arg3", "arg4", "arg5")); +} + +TEST_F(FilesTest, AppendSetArgsFromFile_InvalidFile) { + std::unordered_set<std::string> args; + std::string error; + ASSERT_FALSE(AppendSetArgsFromFile(GetTestPath("not_found.txt"), &args, &error)); +} + #ifdef _WIN32 TEST_F(FilesTest, WindowsMkdirsLongPath) { // Creating directory paths longer than the Windows maximum path length (260 charatcers) should |