summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp19
-rw-r--r--OWNERS3
-rw-r--r--PREUPLOAD_OWNERS2
-rw-r--r--api/ApiDocs.bp32
-rw-r--r--boot/preloaded-classes1
-rw-r--r--config/preloaded-classes1
-rw-r--r--core/api/current.txt13
-rw-r--r--core/api/module-lib-current.txt13
-rw-r--r--core/api/system-current.txt2
-rw-r--r--core/java/android/content/EventLogTags.logtags2
-rw-r--r--core/java/android/content/pm/PackageManager.java3
-rw-r--r--core/java/android/content/pm/SigningInfo.java16
-rw-r--r--core/java/android/content/pm/SigningInfoException.java4
-rw-r--r--core/java/android/net/EventLogTags.logtags2
-rw-r--r--core/java/android/os/EventLogTags.logtags2
-rw-r--r--core/java/android/os/OWNERS7
-rw-r--r--core/java/android/os/Parcel.java31
-rw-r--r--core/java/android/os/ServiceManagerNative.java3
-rw-r--r--core/java/android/speech/tts/EventLogTags.logtags2
-rw-r--r--core/java/android/text/TextUtils.java2
-rw-r--r--core/java/android/view/EventLogTags.logtags4
-rw-r--r--core/java/android/webkit/EventLogTags.logtags2
-rw-r--r--core/java/com/android/internal/app/EventLogTags.logtags2
-rw-r--r--core/java/com/android/internal/jank/EventLogTags.logtags2
-rw-r--r--core/java/com/android/internal/logging/EventLogTags.logtags2
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java2
-rw-r--r--core/java/org/chromium/arc/EventLogTags.logtags2
-rw-r--r--core/jni/android_os_SELinux.cpp18
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp2
-rw-r--r--core/res/Android.bp1
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--core/res/res/values/attrs.xml7
-rw-r--r--core/res/res/values/public-staging.xml2
-rw-r--r--core/tests/overlaytests/host/Android.bp18
-rw-r--r--media/jni/android_media_MediaCodec.cpp12
-rw-r--r--mms/java/android/telephony/MmsManager.java13
-rw-r--r--mms/java/com/android/internal/telephony/IMms.aidl12
-rw-r--r--nfc/Android.bp1
-rw-r--r--nfc/api/current.txt1
-rw-r--r--nfc/api/system-current.txt18
-rw-r--r--nfc/java/android/nfc/NfcOemExtension.java15
-rw-r--r--nfc/java/android/nfc/T4tNdefNfcee.java24
-rw-r--r--nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java127
-rw-r--r--nfc/java/android/nfc/cardemulation/ApduServiceInfo.java29
-rw-r--r--nfc/java/android/nfc/cardemulation/CardEmulation.java35
-rw-r--r--nfc/java/android/nfc/cardemulation/HostApduService.java2
-rw-r--r--nfc/lint-baseline.xml211
-rw-r--r--nfc/tests/Android.bp27
-rw-r--r--nfc/tests/AndroidManifest.xml2
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/EventLogTags.logtags2
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java1
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt42
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt120
-rw-r--r--packages/SystemUI/src/com/android/systemui/EventLogTags.logtags2
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/OWNERS3
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt197
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt55
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt60
-rwxr-xr-xravenwood/scripts/extract-last-soong-commands.py4
-rw-r--r--services/core/java/com/android/server/MmsServiceBroker.java67
-rw-r--r--services/core/java/com/android/server/PackageWatchdog.java47
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java51
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java61
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java10
-rw-r--r--services/core/java/com/android/server/policy/EventLogTags.logtags2
-rw-r--r--services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java11
-rw-r--r--services/core/java/com/android/server/wm/ContentRecorder.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java59
-rw-r--r--services/core/jni/com_android_server_am_CachedAppOptimizer.cpp4
-rw-r--r--services/java/com/android/server/SystemServer.java4
-rw-r--r--services/java/com/android/server/flags.aconfig8
-rw-r--r--services/tests/ondeviceintelligencetests/OWNERS4
-rw-r--r--services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java59
-rw-r--r--services/tests/servicestests/src/com/android/server/utils/OWNERS1
-rw-r--r--tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt128
-rw-r--r--tools/systemfeatures/tests/src/ArraySet.java34
-rw-r--r--tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java19
81 files changed, 983 insertions, 859 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index ed46cddc24e7..f69fd55beb3a 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -303,6 +303,7 @@ java_aconfig_library {
aconfig_declarations {
name: "android.security.flags-aconfig",
package: "android.security",
+ exportable: true,
container: "system",
srcs: ["core/java/android/security/*.aconfig"],
}
@@ -320,6 +321,19 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+java_aconfig_library {
+ name: "android.security.flags-aconfig-java-export",
+ aconfig_declarations: "android.security.flags-aconfig",
+ mode: "exported",
+ min_sdk_version: "30",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.tethering",
+ "com.android.wifi",
+ ],
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
cc_aconfig_library {
name: "android_security_flags_aconfig_c_lib",
aconfig_declarations: "android.security.flags-aconfig",
@@ -856,6 +870,11 @@ aconfig_declarations {
java_aconfig_library {
name: "android.app.flags-aconfig-java",
aconfig_declarations: "android.app.flags-aconfig",
+ min_sdk_version: "34",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.nfcservices",
+ ],
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
diff --git a/OWNERS b/OWNERS
index d0a634e529c5..058ea3619a58 100644
--- a/OWNERS
+++ b/OWNERS
@@ -34,6 +34,8 @@ per-file TestProtoLibraries.bp = file:platform/tools/tradefederation:/OWNERS
per-file *ravenwood* = file:ravenwood/OWNERS
per-file *Ravenwood* = file:ravenwood/OWNERS
+per-file PREUPLOAD.cfg = file:/PREUPLOAD_OWNERS
+
per-file INPUT_OWNERS = file:/INPUT_OWNERS
per-file ZYGOTE_OWNERS = file:/ZYGOTE_OWNERS
per-file SQLITE_OWNERS = file:/SQLITE_OWNERS
@@ -48,3 +50,4 @@ per-file BROADCASTS_OWNERS = file:/BROADCASTS_OWNERS
per-file ADPF_OWNERS = file:/ADPF_OWNERS
per-file GAME_MANAGER_OWNERS = file:/GAME_MANAGER_OWNERS
per-file SDK_OWNERS = file:/SDK_OWNERS
+per-file PREUPLOAD_OWNERS = file:/PREUPLOAD_OWNERS
diff --git a/PREUPLOAD_OWNERS b/PREUPLOAD_OWNERS
new file mode 100644
index 000000000000..ece4d3e5e268
--- /dev/null
+++ b/PREUPLOAD_OWNERS
@@ -0,0 +1,2 @@
+roosa@google.com
+gsennton@google.com
diff --git a/api/ApiDocs.bp b/api/ApiDocs.bp
index 1ebe0cdfabd7..796c8412b26c 100644
--- a/api/ApiDocs.bp
+++ b/api/ApiDocs.bp
@@ -129,6 +129,10 @@ droidstubs {
droidstubs {
name: "framework-doc-stubs",
defaults: ["android-non-updatable-doc-stubs-defaults"],
+ flags: [
+ // Ignore any compatibility errors, see check_api.last_released below for more information.
+ "--hide-category Compatibility",
+ ],
srcs: [":all-modules-public-stubs-source-exportable"],
api_levels_module: "api_versions_public",
aidl: {
@@ -137,13 +141,39 @@ droidstubs {
"packages/modules/Media/apex/aidl/stable",
],
},
+
+ // Pass the previously released API to support reverting flagged APIs. Without this, reverting
+ // a flagged API will cause it to be removed, even if it had previously been released. This
+ // has the side effect of causing compatibility issues to be reported but they are already
+ // checked elsewhere so they will be ignored, see `--hide-category Compatibility` above.
+ check_api: {
+ last_released: {
+ api_file: ":android.api.combined.public.latest",
+ removed_api_file: ":android-removed.api.combined.public.latest",
+ },
+ },
}
droidstubs {
name: "framework-doc-system-stubs",
defaults: ["framework-doc-stubs-sources-default"],
- flags: ["--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)"],
+ flags: [
+ "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)",
+ // Ignore any compatibility errors, see check_api.last_released below for more information.
+ "--hide-category Compatibility",
+ ],
api_levels_module: "api_versions_system",
+
+ // Pass the previously released API to support reverting flagged APIs. Without this, reverting
+ // a flagged API will cause it to be removed, even if it had previously been released. This
+ // has the side effect of causing compatibility issues to be reported but they are already
+ // checked elsewhere so they will be ignored, see `--hide-category Compatibility` above.
+ check_api: {
+ last_released: {
+ api_file: ":android.api.combined.system.latest",
+ removed_api_file: ":android-removed.api.combined.system.latest",
+ },
+ },
}
/////////////////////////////////////////////////////////////////////
diff --git a/boot/preloaded-classes b/boot/preloaded-classes
index a696e03d5bdf..afd9984cb124 100644
--- a/boot/preloaded-classes
+++ b/boot/preloaded-classes
@@ -6469,6 +6469,7 @@ android.os.connectivity.WifiActivityEnergyInfo$1
android.os.connectivity.WifiActivityEnergyInfo
android.os.connectivity.WifiBatteryStats$1
android.os.connectivity.WifiBatteryStats
+android.os.flagging.AconfigPackage
android.os.health.HealthKeys$Constant
android.os.health.HealthKeys$Constants
android.os.health.HealthKeys$SortedIntArray
diff --git a/config/preloaded-classes b/config/preloaded-classes
index ed402767ee64..343de0bf3b98 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -6473,6 +6473,7 @@ android.os.connectivity.WifiActivityEnergyInfo$1
android.os.connectivity.WifiActivityEnergyInfo
android.os.connectivity.WifiBatteryStats$1
android.os.connectivity.WifiBatteryStats
+android.os.flagging.AconfigPackage
android.os.health.HealthKeys$Constant
android.os.health.HealthKeys$Constants
android.os.health.HealthKeys$SortedIntArray
diff --git a/core/api/current.txt b/core/api/current.txt
index 3effcc629b20..16852ae78a46 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1491,6 +1491,7 @@ package android {
field public static final int shadowRadius = 16843108; // 0x1010164
field public static final int shape = 16843162; // 0x101019a
field public static final int shareInterpolator = 16843195; // 0x10101bb
+ field @FlaggedApi("android.nfc.nfc_associated_role_services") public static final int shareRolePriority;
field @Deprecated public static final int sharedUserId = 16842763; // 0x101000b
field @Deprecated public static final int sharedUserLabel = 16843361; // 0x1010261
field public static final int sharedUserMaxSdkVersion = 16844365; // 0x101064d
@@ -13033,6 +13034,7 @@ package android.content.pm {
method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int);
method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle);
method @NonNull public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence, @NonNull android.os.UserHandle);
+ method @FlaggedApi("android.content.pm.cloud_compilation_pm") @NonNull public static android.content.pm.SigningInfo getVerifiedSigningInfo(@NonNull String, int) throws android.content.pm.SigningInfoException;
method @NonNull @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions(@NonNull String, int);
method @Nullable public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo);
method public boolean hasSigningCertificate(@NonNull String, @NonNull byte[], int);
@@ -13671,8 +13673,17 @@ package android.content.pm {
method public android.content.pm.Signature[] getSigningCertificateHistory();
method public boolean hasMultipleSigners();
method public boolean hasPastSigningCertificates();
+ method @FlaggedApi("android.content.pm.cloud_compilation_pm") public boolean signersMatchExactly(@NonNull android.content.pm.SigningInfo);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.SigningInfo> CREATOR;
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_JAR = 1; // 0x1
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V2 = 2; // 0x2
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V3 = 3; // 0x3
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V4 = 4; // 0x4
+ }
+
+ @FlaggedApi("android.content.pm.cloud_compilation_pm") public class SigningInfoException extends java.lang.Exception {
+ method @FlaggedApi("android.content.pm.cloud_compilation_pm") public int getCode();
}
public final class VersionedPackage implements android.os.Parcelable {
@@ -48166,7 +48177,7 @@ package android.text {
method public static void dumpSpans(CharSequence, android.util.Printer, String);
method public static CharSequence ellipsize(CharSequence, android.text.TextPaint, float, android.text.TextUtils.TruncateAt);
method public static CharSequence ellipsize(CharSequence, android.text.TextPaint, float, android.text.TextUtils.TruncateAt, boolean, @Nullable android.text.TextUtils.EllipsizeCallback);
- method public static boolean equals(CharSequence, CharSequence);
+ method public static boolean equals(@Nullable CharSequence, @Nullable CharSequence);
method public static CharSequence expandTemplate(CharSequence, java.lang.CharSequence...);
method public static int getCapsMode(CharSequence, int, int);
method public static void getChars(CharSequence, int, int, char[], int);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 5790a732f134..b2331cb55fb5 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -129,7 +129,6 @@ package android.content.pm {
public abstract class PackageManager {
method @NonNull public String getSdkSandboxPackageName();
- method @FlaggedApi("android.content.pm.cloud_compilation_pm") @NonNull public static android.content.pm.SigningInfo getVerifiedSigningInfo(@NonNull String, int) throws android.content.pm.SigningInfoException;
method @RequiresPermission(android.Manifest.permission.MAKE_UID_VISIBLE) public void makeUidVisible(int, int);
field public static final String EXTRA_VERIFICATION_ROOT_HASH = "android.content.pm.extra.VERIFICATION_ROOT_HASH";
field public static final int MATCH_STATIC_SHARED_AND_SDK_LIBRARIES = 67108864; // 0x4000000
@@ -140,18 +139,6 @@ package android.content.pm {
method @NonNull public String getPackageName();
}
- public final class SigningInfo implements android.os.Parcelable {
- method @FlaggedApi("android.content.pm.cloud_compilation_pm") public boolean signersMatchExactly(@NonNull android.content.pm.SigningInfo);
- field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_JAR = 1; // 0x1
- field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V2 = 2; // 0x2
- field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V3 = 3; // 0x3
- field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V4 = 4; // 0x4
- }
-
- @FlaggedApi("android.content.pm.cloud_compilation_pm") public class SigningInfoException extends java.lang.Exception {
- method @FlaggedApi("android.content.pm.cloud_compilation_pm") public int getCode();
- }
-
}
package android.hardware.usb {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index f722ba24c6b4..903e18dcccdb 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -309,6 +309,7 @@ package android {
field public static final String READ_RUNTIME_PROFILES = "android.permission.READ_RUNTIME_PROFILES";
field public static final String READ_SAFETY_CENTER_STATUS = "android.permission.READ_SAFETY_CENTER_STATUS";
field public static final String READ_SEARCH_INDEXABLES = "android.permission.READ_SEARCH_INDEXABLES";
+ field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final String READ_SUBSCRIPTION_PLANS = "android.permission.READ_SUBSCRIPTION_PLANS";
field @FlaggedApi("android.app.system_terms_of_address_enabled") public static final String READ_SYSTEM_GRAMMATICAL_GENDER = "android.permission.READ_SYSTEM_GRAMMATICAL_GENDER";
field public static final String READ_SYSTEM_UPDATE_INFO = "android.permission.READ_SYSTEM_UPDATE_INFO";
field public static final String READ_WALLPAPER_INTERNAL = "android.permission.READ_WALLPAPER_INTERNAL";
@@ -10462,6 +10463,7 @@ package android.nfc.cardemulation {
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setDynamicAidGroup(@NonNull android.nfc.cardemulation.AidGroup);
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setOffHostSecureElement(@NonNull String);
method @FlaggedApi("android.nfc.nfc_observe_mode") public void setShouldDefaultToObserveMode(boolean);
+ method @FlaggedApi("android.nfc.nfc_associated_role_services") public boolean shareRolePriority();
method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean shouldDefaultToObserveMode();
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void writeToParcel(@NonNull android.os.Parcel, int);
field @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.ApduServiceInfo> CREATOR;
diff --git a/core/java/android/content/EventLogTags.logtags b/core/java/android/content/EventLogTags.logtags
index 21ea90ad2e1e..861a5b72c86c 100644
--- a/core/java/android/content/EventLogTags.logtags
+++ b/core/java/android/content/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.content;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 759d1919e4e1..07775f765348 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -11863,11 +11863,8 @@ public abstract class PackageManager {
* file.
*
* @throws SigningInfoException if the verification fails
- *
- * @hide
*/
@FlaggedApi(android.content.pm.Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static @NonNull SigningInfo getVerifiedSigningInfo(@NonNull String path,
@AppSigningSchemeVersion int minAppSigningSchemeVersion) throws SigningInfoException {
ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
diff --git a/core/java/android/content/pm/SigningInfo.java b/core/java/android/content/pm/SigningInfo.java
index e4fbd1f28dbb..21bbb0a0a81c 100644
--- a/core/java/android/content/pm/SigningInfo.java
+++ b/core/java/android/content/pm/SigningInfo.java
@@ -22,7 +22,6 @@ import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.content.pm.SigningDetails.SignatureSchemeVersion;
import android.os.Parcel;
import android.os.Parcelable;
@@ -40,41 +39,29 @@ public final class SigningInfo implements Parcelable {
/**
* JAR signing (v1 scheme).
* See https://source.android.com/docs/security/features/apksigning#v1.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int VERSION_JAR = SignatureSchemeVersion.JAR;
/**
* APK signature scheme v2.
* See https://source.android.com/docs/security/features/apksigning/v2.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int VERSION_SIGNING_BLOCK_V2 = SignatureSchemeVersion.SIGNING_BLOCK_V2;
/**
* APK signature scheme v3.
* See https://source.android.com/docs/security/features/apksigning/v3.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int VERSION_SIGNING_BLOCK_V3 = SignatureSchemeVersion.SIGNING_BLOCK_V3;
/**
* APK signature scheme v4.
* See https://source.android.com/docs/security/features/apksigning/v4.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int VERSION_SIGNING_BLOCK_V4 = SignatureSchemeVersion.SIGNING_BLOCK_V4;
/** @hide */
@@ -255,11 +242,8 @@ public final class SigningInfo implements Parcelable {
/**
* Returns true if the signing certificates in this and other match exactly.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public boolean signersMatchExactly(@NonNull SigningInfo other) {
return mSigningDetails.signaturesMatchExactly(other.mSigningDetails);
}
diff --git a/core/java/android/content/pm/SigningInfoException.java b/core/java/android/content/pm/SigningInfoException.java
index a81e07e73685..2fd1bfb46f4c 100644
--- a/core/java/android/content/pm/SigningInfoException.java
+++ b/core/java/android/content/pm/SigningInfoException.java
@@ -19,17 +19,13 @@ package android.content.pm;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
/**
* Indicates an error when verifying the
* <a href="https://source.android.com/docs/security/features/apksigning">app signing</a>
* information.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public class SigningInfoException extends Exception {
private final int mCode;
diff --git a/core/java/android/net/EventLogTags.logtags b/core/java/android/net/EventLogTags.logtags
index d5ed01496eba..32953c92d120 100644
--- a/core/java/android/net/EventLogTags.logtags
+++ b/core/java/android/net/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.net
diff --git a/core/java/android/os/EventLogTags.logtags b/core/java/android/os/EventLogTags.logtags
index b143a7443066..f57aad00e591 100644
--- a/core/java/android/os/EventLogTags.logtags
+++ b/core/java/android/os/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.os
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 8d353384f1e2..f3bb51490f20 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -115,13 +115,20 @@ per-file ProfilingServiceManager.java = file:/PERFORMANCE_OWNERS
# Performance
per-file IpcDataCache.java = file:/PERFORMANCE_OWNERS
+# Processes, threads, and scheduling
+per-file Process.java = file:/PERFORMANCE_OWNERS
+
# Memory
per-file OomKillRecord.java = file:/MEMORY_OWNERS
# MessageQueue and related classes
per-file MessageQueue.java = mfasheh@google.com, shayba@google.com
per-file Message.java = mfasheh@google.com, shayba@google.com
+per-file Looper.java = mfasheh@google.com, shayba@google.com
per-file TestLooperManager.java = mfasheh@google.com, shayba@google.com
+per-file Handler.java = mfasheh@google.com, shayba@google.com
+per-file HandlerThread.java = mfasheh@google.com, shayba@google.com
+per-file HandlerExecutor.java = mfasheh@google.com, shayba@google.com
# Stats
per-file IStatsBootstrapAtomService.aidl = file:/services/core/java/com/android/server/stats/OWNERS
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index f7285523c01a..a41cdd269e5e 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -892,6 +892,12 @@ public final class Parcel {
/**
* Report whether the parcel contains any marshalled file descriptors.
+ *
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
*/
public boolean hasFileDescriptors() {
return nativeHasFileDescriptors(mNativePtr);
@@ -901,6 +907,12 @@ public final class Parcel {
* Report whether the parcel contains any marshalled file descriptors in the range defined by
* {@code offset} and {@code length}.
*
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @param offset The offset from which the range starts. Should be between 0 and
* {@link #dataSize()}.
* @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
@@ -921,6 +933,12 @@ public final class Parcel {
* <p>For most cases, it will use the self-reported {@link Parcelable#describeContents()} method
* for that.
*
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @throws IllegalArgumentException if you provide any object not supported by above methods
* (including if the unsupported object is inside a nested container).
*
@@ -990,6 +1008,13 @@ public final class Parcel {
*
* @throws UnsupportedOperationException if binder kernel driver was disabled or if method was
* invoked in case of Binder RPC protocol.
+ *
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @hide
*/
public boolean hasBinders() {
@@ -1000,6 +1025,12 @@ public final class Parcel {
* Report whether the parcel contains any marshalled {@link IBinder} objects in the range
* defined by {@code offset} and {@code length}.
*
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @param offset The offset from which the range starts. Should be between 0 and
* {@link #dataSize()}.
* @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 49b696d95723..7ea521ec5dd4 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -50,7 +50,8 @@ public final class ServiceManagerNative {
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
- mServiceManager = IServiceManager.Stub.asInterface(this.getNativeServiceManager());
+ mServiceManager = IServiceManager.Stub.asInterface(
+ Binder.allowBlocking(this.getNativeServiceManager()));
}
public IBinder asBinder() {
diff --git a/core/java/android/speech/tts/EventLogTags.logtags b/core/java/android/speech/tts/EventLogTags.logtags
index e209a286966a..5ba2baec6fcf 100644
--- a/core/java/android/speech/tts/EventLogTags.logtags
+++ b/core/java/android/speech/tts/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.speech.tts;
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 6ea462eb969f..71c9a2a888be 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -675,7 +675,7 @@ public class TextUtils {
* @return true if a and b are equal
*/
@android.ravenwood.annotation.RavenwoodKeep
- public static boolean equals(CharSequence a, CharSequence b) {
+ public static boolean equals(@Nullable CharSequence a, @Nullable CharSequence b) {
if (a == b) return true;
int length;
if (a != null && b != null && (length = a.length()) == b.length()) {
diff --git a/core/java/android/view/EventLogTags.logtags b/core/java/android/view/EventLogTags.logtags
index f1cd671ef176..a43ba17a2bf4 100644
--- a/core/java/android/view/EventLogTags.logtags
+++ b/core/java/android/view/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.view
@@ -35,7 +35,7 @@ option java_package android.view
# 6: Percent
# Default value for data of type int/long is 2 (bytes).
#
-# See system/core/logcat/event.logtags for the master copy of the tags.
+# See system/logging/logcat/event.logtags for the master copy of the tags.
# 32000 - 32999 reserved for input method framework
# IME animation is started.
diff --git a/core/java/android/webkit/EventLogTags.logtags b/core/java/android/webkit/EventLogTags.logtags
index a90aebd71716..8bbd5a9d0246 100644
--- a/core/java/android/webkit/EventLogTags.logtags
+++ b/core/java/android/webkit/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.webkit;
diff --git a/core/java/com/android/internal/app/EventLogTags.logtags b/core/java/com/android/internal/app/EventLogTags.logtags
index d681a8d26e8e..a18a8243305b 100644
--- a/core/java/com/android/internal/app/EventLogTags.logtags
+++ b/core/java/com/android/internal/app/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.internal.app;
diff --git a/core/java/com/android/internal/jank/EventLogTags.logtags b/core/java/com/android/internal/jank/EventLogTags.logtags
index 66ee131badac..dfec49907c69 100644
--- a/core/java/com/android/internal/jank/EventLogTags.logtags
+++ b/core/java/com/android/internal/jank/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.internal.jank;
diff --git a/core/java/com/android/internal/logging/EventLogTags.logtags b/core/java/com/android/internal/logging/EventLogTags.logtags
index 693bd16e6170..db47797cb03d 100644
--- a/core/java/com/android/internal/logging/EventLogTags.logtags
+++ b/core/java/com/android/internal/logging/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.internal.logging;
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 19c6f51ff9a7..9bd52372e6c4 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1326,7 +1326,7 @@ public class LockPatternUtils {
try {
getLockSettings().registerStrongAuthTracker(strongAuthTracker.getStub());
} catch (RemoteException e) {
- throw new RuntimeException("Could not register StrongAuthTracker");
+ e.rethrowFromSystemServer();
}
}
diff --git a/core/java/org/chromium/arc/EventLogTags.logtags b/core/java/org/chromium/arc/EventLogTags.logtags
index 1b7160e90224..8102d6f10ed4 100644
--- a/core/java/org/chromium/arc/EventLogTags.logtags
+++ b/core/java/org/chromium/arc/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package org.chromium.arc
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 805d5ad41e83..cd39e6f93fb4 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -34,23 +34,27 @@
namespace android {
namespace {
-std::atomic<selabel_handle*> sehandle{nullptr};
+std::atomic<selabel_handle *> file_sehandle{nullptr};
-selabel_handle* GetSELabelHandle() {
- selabel_handle* h = sehandle.load();
+selabel_handle *GetSELabelHandle_impl(selabel_handle *(*handle_func)(),
+ std::atomic<selabel_handle *> *handle_cache) {
+ selabel_handle *h = handle_cache->load();
if (h != nullptr) {
return h;
}
- h = selinux_android_file_context_handle();
+ h = handle_func();
selabel_handle* expected = nullptr;
- if (!sehandle.compare_exchange_strong(expected, h)) {
+ if (!handle_cache->compare_exchange_strong(expected, h)) {
selabel_close(h);
- return sehandle.load();
+ return handle_cache->load();
}
return h;
}
+selabel_handle *GetSELabelFileBackendHandle() {
+ return GetSELabelHandle_impl(selinux_android_file_context_handle, &file_sehandle);
+}
}
struct SecurityContext_Delete {
@@ -106,7 +110,7 @@ static jstring fileSelabelLookup(JNIEnv* env, jobject, jstring pathStr) {
return NULL;
}
- auto* selabel_handle = GetSELabelHandle();
+ auto *selabel_handle = GetSELabelFileBackendHandle();
if (selabel_handle == NULL) {
ALOGE("fileSelabelLookup => Failed to get SEHandle");
return NULL;
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index aeaeeca3e845..8c7b335e6e86 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -88,8 +88,8 @@
#include "nativebridge/native_bridge.h"
#if defined(__BIONIC__)
+#include <android/dlext_private.h>
extern "C" void android_reset_stack_guards();
-extern "C" void android_set_16kb_appcompat_mode(bool enable_app_compat);
#endif
namespace {
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 4254a47877da..b54fd986b718 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -164,6 +164,7 @@ android_app {
"com.android.window.flags.window-aconfig",
"android.permission.flags-aconfig",
"ranging_aconfig_flags",
+ "telephony_flags",
],
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d74065589361..0d460fea7efd 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -6814,6 +6814,13 @@
<permission android:name="android.permission.MANAGE_SUBSCRIPTION_PLANS"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi @hide Allows for reading subscription plan fields for status and end date.
+ @FlaggedApi(com.android.internal.telephony.flags.Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE)
+ -->
+ <permission android:name="android.permission.READ_SUBSCRIPTION_PLANS"
+ android:protectionLevel="signature|privileged"
+ android:featureFlag="com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date" />
+
<!-- C2DM permission.
@hide Used internally.
-->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9846b710300f..4952400441c0 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4460,6 +4460,12 @@
<!-- Whether the device should default to observe mode when this service is
default or in the foreground. -->
<attr name="shouldDefaultToObserveMode" format="boolean"/>
+ <!-- Whether this service should share the same AID routing priority as the role
+ owner. This package and the role owner must have the same signature, and the
+ role owner must opt into this behavior by using the property named by
+ {@link android.nfc.cardemulation.CardEmulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY }
+ in the <code>&lt;application&rt;</code> tag. -->
+ <attr name="shareRolePriority" format="boolean"/>
</declare-styleable>
<!-- Use <code>offhost-apdu-service</code> as the root tag of the XML resource that
@@ -4487,6 +4493,7 @@
<!-- Whether the device should default to observe mode when this service is
default or in the foreground. -->
<attr name="shouldDefaultToObserveMode"/>
+ <attr name="shareRolePriority"/>
</declare-styleable>
<!-- Specify one or more <code>aid-group</code> elements inside a
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index b64334f7f95a..d0846326094c 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -118,6 +118,8 @@
<public name="languageSettingsActivity"/>
<!-- @FlaggedApi("android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM") -->
<public name="dreamCategory"/>
+ <!-- @FlaggedApi(android.nfc.Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES) -->
+ <public name="shareRolePriority"/>
</staging-public-group>
<staging-public-group type="id" first-id="0x01b60000">
diff --git a/core/tests/overlaytests/host/Android.bp b/core/tests/overlaytests/host/Android.bp
index 634098074cca..9b7200436f02 100644
--- a/core/tests/overlaytests/host/Android.bp
+++ b/core/tests/overlaytests/host/Android.bp
@@ -28,14 +28,14 @@ java_test_host {
test_suites: [
"device-tests",
],
- target_required: [
- "OverlayHostTests_NonPlatformSignatureOverlay",
- "OverlayHostTests_PlatformSignatureStaticOverlay",
- "OverlayHostTests_PlatformSignatureOverlay",
- "OverlayHostTests_UpdateOverlay",
- "OverlayHostTests_FrameworkOverlayV1",
- "OverlayHostTests_FrameworkOverlayV2",
- "OverlayHostTests_AppOverlayV1",
- "OverlayHostTests_AppOverlayV2",
+ device_common_data: [
+ ":OverlayHostTests_NonPlatformSignatureOverlay",
+ ":OverlayHostTests_PlatformSignatureStaticOverlay",
+ ":OverlayHostTests_PlatformSignatureOverlay",
+ ":OverlayHostTests_UpdateOverlay",
+ ":OverlayHostTests_FrameworkOverlayV1",
+ ":OverlayHostTests_FrameworkOverlayV2",
+ ":OverlayHostTests_AppOverlayV1",
+ ":OverlayHostTests_AppOverlayV2",
],
}
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index fc184fe5c872..8419ce761a4a 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -1149,9 +1149,9 @@ status_t JMediaCodec::unsubscribeFromVendorParameters(JNIEnv *env, jobject names
static jobject getJavaResources(
JNIEnv *env,
- const std::vector<MediaCodec::InstanceResourceInfo>& resources) {
+ const std::vector<InstanceResourceInfo>& resources) {
jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId);
- for (const MediaCodec::InstanceResourceInfo& res : resources) {
+ for (const InstanceResourceInfo& res : resources) {
ScopedLocalRef<jobject> object{env, env->NewObject(
gInstanceResourceInfo.clazz, gInstanceResourceInfo.ctorId)};
ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())};
@@ -1169,7 +1169,7 @@ static jobject getJavaResources(
}
status_t JMediaCodec::getRequiredResources(JNIEnv *env, jobject *resourcesObj) {
- std::vector<MediaCodec::InstanceResourceInfo> resources;
+ std::vector<InstanceResourceInfo> resources;
status_t status = mCodec->getRequiredResources(resources);
if (status != OK) {
return status;
@@ -3615,9 +3615,9 @@ static void android_media_MediaCodec_unsubscribeFromVendorParameters(
static jobject getJavaResources(
JNIEnv *env,
- const std::vector<MediaCodec::GlobalResourceInfo>& resources) {
+ const std::vector<GlobalResourceInfo>& resources) {
jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId);
- for (const MediaCodec::GlobalResourceInfo& res : resources) {
+ for (const GlobalResourceInfo& res : resources) {
ScopedLocalRef<jobject> object{env, env->NewObject(
gGlobalResourceInfo.clazz, gGlobalResourceInfo.ctorId)};
ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())};
@@ -3633,7 +3633,7 @@ static jobject getJavaResources(
static jobject android_media_MediaCodec_getGloballyAvailableResources(
JNIEnv *env, jobject thiz) {
(void)thiz;
- std::vector<MediaCodec::GlobalResourceInfo> resources;
+ std::vector<GlobalResourceInfo> resources;
status_t status = MediaCodec::getGloballyAvailableResources(resources);
if (status != OK) {
if (status == ERROR_UNSUPPORTED) {
diff --git a/mms/java/android/telephony/MmsManager.java b/mms/java/android/telephony/MmsManager.java
index b893b45611fb..ac2927711c9a 100644
--- a/mms/java/android/telephony/MmsManager.java
+++ b/mms/java/android/telephony/MmsManager.java
@@ -26,6 +26,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import com.android.internal.telephony.IMms;
@@ -69,9 +70,9 @@ public class MmsManager {
return;
}
- iMms.sendMessage(subId, ActivityThread.currentPackageName(), contentUri,
- locationUrl, configOverrides, sentIntent, messageId,
- mContext.getAttributionTag());
+ iMms.sendMessage(subId, /* placeholder callingUser= */ UserHandle.USER_NULL,
+ ActivityThread.currentPackageName(), contentUri, locationUrl,
+ configOverrides, sentIntent, messageId, mContext.getAttributionTag());
} catch (RemoteException e) {
// Ignore it
}
@@ -101,9 +102,9 @@ public class MmsManager {
if (iMms == null) {
return;
}
- iMms.downloadMessage(subId, ActivityThread.currentPackageName(),
- locationUrl, contentUri, configOverrides, downloadedIntent,
- messageId, mContext.getAttributionTag());
+ iMms.downloadMessage(subId, /* placeholder callingUser= */ UserHandle.USER_NULL,
+ ActivityThread.currentPackageName(), locationUrl, contentUri,
+ configOverrides, downloadedIntent, messageId, mContext.getAttributionTag());
} catch (RemoteException e) {
// Ignore it
}
diff --git a/mms/java/com/android/internal/telephony/IMms.aidl b/mms/java/com/android/internal/telephony/IMms.aidl
index 3cdde10e4fc2..1c7595164de2 100644
--- a/mms/java/com/android/internal/telephony/IMms.aidl
+++ b/mms/java/com/android/internal/telephony/IMms.aidl
@@ -29,6 +29,7 @@ interface IMms {
* Send an MMS message with attribution tag.
*
* @param subId the SIM id
+ * @param callingUser user id of the calling app
* @param callingPkg the package name of the calling app
* @param contentUri the content uri from which to read MMS message encoded in standard MMS
* PDU format
@@ -40,7 +41,7 @@ interface IMms {
* @param messageId An id that uniquely identifies the message requested to be sent.
* @param attributionTag a tag that attributes the call to a client App.
*/
- void sendMessage(int subId, String callingPkg, in Uri contentUri,
+ void sendMessage(int subId, in int callingUser, String callingPkg, in Uri contentUri,
String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent,
in long messageId, String attributionTag);
@@ -48,6 +49,7 @@ interface IMms {
* Download an MMS message using known location and transaction id
*
* @param subId the SIM id
+ * @param callingUser user id of the calling app
* @param callingPkg the package name of the calling app
* @param locationUrl the location URL of the MMS message to be downloaded, usually obtained
* from the MMS WAP push notification
@@ -60,7 +62,7 @@ interface IMms {
* @param messageId An id that uniquely identifies the message requested to be downloaded.
* @param attributionTag a tag that attributes the call to a client App.
*/
- void downloadMessage(int subId, String callingPkg, String locationUrl,
+ void downloadMessage(int subId, in int callingUser, String callingPkg, String locationUrl,
in Uri contentUri, in Bundle configOverrides,
in PendingIntent downloadedIntent, in long messageId, String attributionTag);
@@ -82,6 +84,7 @@ interface IMms {
/**
* Import a multimedia message into system's MMS store
*
+ * @param callingUser user id of the calling app
* @param callingPkg the package name of the calling app
* @param contentUri the content uri from which to read PDU of the message to import
* @param messageId the optional message id
@@ -90,7 +93,7 @@ interface IMms {
* @param read if the message is read
* @return the message URI, null if failed
*/
- Uri importMultimediaMessage(String callingPkg, in Uri contentUri, String messageId,
+ Uri importMultimediaMessage(in int callingUser, String callingPkg, in Uri contentUri, String messageId,
long timestampSecs, boolean seen, boolean read);
/**
@@ -146,11 +149,12 @@ interface IMms {
/**
* Add a multimedia message draft to system MMS store
*
+ * @param callingUser user id of the calling app
* @param callingPkg the package name of the calling app
* @param contentUri the content Uri from which to read PDU data of the draft MMS
* @return the URI of the stored draft message
*/
- Uri addMultimediaMessageDraft(String callingPkg, in Uri contentUri);
+ Uri addMultimediaMessageDraft(in int callingUser, String callingPkg, in Uri contentUri);
/**
* Send a system stored MMS message
diff --git a/nfc/Android.bp b/nfc/Android.bp
index 7ad8c4c8de41..abe0ab757ba6 100644
--- a/nfc/Android.bp
+++ b/nfc/Android.bp
@@ -37,6 +37,7 @@ filegroup {
java_sdk_library {
name: "framework-nfc",
libs: [
+ "androidx.annotation_annotation",
"unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
"framework-permission-s.stubs.module_lib",
"framework-permission.stubs.module_lib",
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 2aa73db06204..0ee81cbb7a73 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -233,6 +233,7 @@ package android.nfc.cardemulation {
field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1; // 0x1
field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2; // 0x2
field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0; // 0x0
+ field @FlaggedApi("android.nfc.nfc_associated_role_services") public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY = "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3; // 0x3
field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0; // 0x0
field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1; // 0x1
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index e97b15d3b926..6bd6072a2f43 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -85,6 +85,10 @@ package android.nfc {
field public static final int HCE_ACTIVATE = 1; // 0x1
field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
field public static final int HCE_DEACTIVATE = 3; // 0x3
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_A = 1; // 0x1
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_B = 2; // 0x2
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_F = 4; // 0x4
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_NONE = 0; // 0x0
field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
field public static final int STATUS_OK = 0; // 0x0
@@ -196,9 +200,11 @@ package android.nfc {
method @Nullable @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public android.nfc.T4tNdefNfceeCcFileInfo readCcfile();
method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public byte[] readData(@IntRange(from=0, to=65535) int);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int writeData(@IntRange(from=0, to=65535) int, @NonNull byte[]);
+ field public static final int CLEAR_DATA_FAILED_DEVICE_BUSY = -1; // 0xffffffff
field public static final int CLEAR_DATA_FAILED_INTERNAL = 0; // 0x0
field public static final int CLEAR_DATA_SUCCESS = 1; // 0x1
field public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6; // 0xfffffffa
+ field public static final int WRITE_DATA_ERROR_DEVICE_BUSY = -9; // 0xfffffff7
field public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7; // 0xfffffff9
field public static final int WRITE_DATA_ERROR_INTERNAL = -1; // 0xffffffff
field public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4; // 0xfffffffc
@@ -213,21 +219,14 @@ package android.nfc {
method public int describeContents();
method @IntRange(from=15, to=32767) public int getCcFileLength();
method @IntRange(from=0xffffffff, to=65535) public int getFileId();
- method @IntRange(from=15, to=65535) public int getMaxReadLength();
method @IntRange(from=5, to=32767) public int getMaxSize();
- method @IntRange(from=13, to=65535) public int getMaxWriteLength();
- method public int getReadAccess();
method public int getVersion();
- method public int getWriteAccess();
+ method public boolean isReadAllowed();
+ method public boolean isWriteAllowed();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.nfc.T4tNdefNfceeCcFileInfo> CREATOR;
- field public static final int READ_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
- field public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
field public static final int VERSION_2_0 = 32; // 0x20
field public static final int VERSION_3_0 = 48; // 0x30
- field public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
- field public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
- field public static final int WRITE_ACCESS_NOT_GRANTED = 255; // 0xff
}
}
@@ -250,6 +249,7 @@ package android.nfc.cardemulation {
field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1; // 0x1
field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3; // 0x3
field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0; // 0x0
+ field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1; // 0xffffffff
}
}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index fb11875ec7d7..b46e34368e77 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -150,28 +150,24 @@ public final class NfcOemExtension {
/**
* Technology Type for {@link #getActiveNfceeList()}.
- * @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int NFCEE_TECH_NONE = 0;
/**
* Technology Type for {@link #getActiveNfceeList()}.
- * @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int NFCEE_TECH_A = 1;
/**
* Technology Type for {@link #getActiveNfceeList()}.
- * @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int NFCEE_TECH_B = 1 << 1;
/**
* Technology Type for {@link #getActiveNfceeList()}.
- * @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int NFCEE_TECH_F = 1 << 2;
@@ -670,12 +666,15 @@ public final class NfcOemExtension {
/**
* Get the Active NFCEE (NFC Execution Environment) List
*
- * @see Reader#getName() for the list of possible NFCEE names.
- *
* @return Map< String, @NfceeTechnology Integer >
* A HashMap where keys are activated secure elements and
- * the values are bitmap of technologies supported by each secure element
- * on success keys can contain "eSE" and "UICC", otherwise empty map.
+ * the values are bitmap of technologies supported by each secure element:
+ * NFCEE_TECH_A == 0x1
+ * NFCEE_TECH_B == 0x2
+ * NFCEE_TECH_F == 0x4
+ * and keys can contain "eSE" and "SIM" with a number,
+ * in case of failure an empty map is returned.
+ * @see Reader#getName() for the list of possible NFCEE names.
*/
@NonNull
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
diff --git a/nfc/java/android/nfc/T4tNdefNfcee.java b/nfc/java/android/nfc/T4tNdefNfcee.java
index 06d02c54eb2e..05a30aad76fc 100644
--- a/nfc/java/android/nfc/T4tNdefNfcee.java
+++ b/nfc/java/android/nfc/T4tNdefNfcee.java
@@ -100,9 +100,14 @@ public final class T4tNdefNfcee {
public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7;
/**
* Returns flag for {@link #writeData(int, byte[])}.
- * It idicates write data fail due to invalid ndef format.
+ * It indicates write data fail due to invalid ndef format.
*/
public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8;
+ /**
+ * Returns flag for {@link #writeData(int, byte[])}.
+ * It indicates write data fail if a concurrent NDEF NFCEE operation is ongoing.
+ */
+ public static final int WRITE_DATA_ERROR_DEVICE_BUSY = -9;
/**
* Possible return values for {@link #writeData(int, byte[])}.
@@ -119,6 +124,7 @@ public final class T4tNdefNfcee {
WRITE_DATA_ERROR_CONNECTION_FAILED,
WRITE_DATA_ERROR_EMPTY_PAYLOAD,
WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED,
+ WRITE_DATA_ERROR_DEVICE_BUSY,
})
@Retention(RetentionPolicy.SOURCE)
public @interface WriteDataStatus{}
@@ -128,6 +134,9 @@ public final class T4tNdefNfcee {
*
* <p>This is an I/O operation and will block until complete. It must
* not be called from the main application thread.</p>
+ * <p>Applications must send complete Ndef Message payload, do not need to fragment
+ * the payload, it will be automatically fragmented and defragmented by
+ * {@link #writeData} if it exceeds max message length limits</p>
*
* @param fileId File id (Refer NFC Forum Type 4 Tag Specification
* Section 4.2 File Identifiers and Access Conditions
@@ -155,9 +164,10 @@ public final class T4tNdefNfcee {
* @param fileId File Id (Refer
* Section 4.2 File Identifiers and Access Conditions
* for more information) from which to read.
- * @return - Returns Ndef message if success
+ * @return - Returns complete Ndef message if success
* Refer to Nfc forum NDEF specification NDEF Message section
- * @throws IllegalStateException if read fails because the fileId is invalid.
+ * @throws IllegalStateException if read fails because the fileId is invalid
+ * or if a concurrent operation is in progress.
* @hide
*/
@SystemApi
@@ -179,6 +189,12 @@ public final class T4tNdefNfcee {
* It indicates clear data failed due to internal error while processing the clear.
*/
public static final int CLEAR_DATA_FAILED_INTERNAL = 0;
+ /**
+ * Return flag for {@link #clearNdefData()}.
+ * It indicates clear data failed if a concurrent NDEF NFCEE operation is ongoing.
+ */
+ public static final int CLEAR_DATA_FAILED_DEVICE_BUSY = -1;
+
/**
* Possible return values for {@link #clearNdefData()}.
@@ -188,6 +204,7 @@ public final class T4tNdefNfcee {
@IntDef(prefix = { "CLEAR_DATA_" }, value = {
CLEAR_DATA_SUCCESS,
CLEAR_DATA_FAILED_INTERNAL,
+ CLEAR_DATA_FAILED_DEVICE_BUSY,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ClearDataStatus{}
@@ -245,6 +262,7 @@ public final class T4tNdefNfcee {
* Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
*
* @return Returns CC file content if success or null if failed to read.
+ * @throws IllegalStateException if the device is busy.
* @hide
*/
@SystemApi
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
index 5fca0529124e..ce67f8f9aea7 100644
--- a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
@@ -47,14 +47,6 @@ public final class T4tNdefNfceeCcFileInfo implements Parcelable {
*/
private int mVersion;
/**
- * Indicates the max data size by a single ReadBinary<p>
- */
- private int mMaxReadLength;
- /**
- * Indicates the max data size by a single UpdateBinary<p>
- */
- private int mMaxWriteLength;
- /**
* Indicates the NDEF File Identifier<p>
*/
private int mFileId;
@@ -65,40 +57,35 @@ public final class T4tNdefNfceeCcFileInfo implements Parcelable {
/**
* Indicates the read access condition<p>
*/
- private int mReadAccess;
+ private boolean mIsReadAllowed;
/**
* Indicates the write access condition<p>
*/
- private int mWriteAccess;
+ private boolean mIsWriteAllowed;
/**
* Constructor to be used by NFC service and internal classes.
* @hide
*/
- public T4tNdefNfceeCcFileInfo(int cclen, int version, int maxLe, int maxLc,
+ public T4tNdefNfceeCcFileInfo(int cclen, int version,
int ndefFileId, int ndefMaxSize,
- int ndefReadAccess, int ndefWriteAccess) {
+ boolean isReadAllowed, boolean isWriteAllowed) {
mCcLength = cclen;
mVersion = version;
- mMaxWriteLength = maxLc;
- mMaxReadLength = maxLe;
mFileId = ndefFileId;
mMaxSize = ndefMaxSize;
- mReadAccess = ndefReadAccess;
- mWriteAccess = ndefWriteAccess;
+ mIsReadAllowed = isReadAllowed;
+ mIsWriteAllowed = isWriteAllowed;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
-
dest.writeInt(mCcLength);
dest.writeInt(mVersion);
- dest.writeInt(mMaxWriteLength);
- dest.writeInt(mMaxReadLength);
dest.writeInt(mFileId);
dest.writeInt(mMaxSize);
- dest.writeInt(mReadAccess);
- dest.writeInt(mWriteAccess);
+ dest.writeBoolean(mIsReadAllowed);
+ dest.writeBoolean(mIsWriteAllowed);
}
/**
@@ -146,30 +133,6 @@ public final class T4tNdefNfceeCcFileInfo implements Parcelable {
}
/**
- * Indicates the max data size that can be read by a single invocation of
- * {@link T4tNdefNfcee#readData(int)}.
- *
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLe.
- * @return max size of read (in bytes).
- */
- @IntRange(from = 0xf, to = 0xffff)
- public int getMaxReadLength() {
- return mMaxReadLength;
- }
-
- /**
- * Indicates the max data size that can be written by a single invocation of
- * {@link T4tNdefNfcee#writeData(int, byte[])}
- *
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLc.
- * @return max size of write (in bytes).
- */
- @IntRange(from = 0xd, to = 0xffff)
- public int getMaxWriteLength() {
- return mMaxWriteLength;
- }
-
- /**
* Indicates the NDEF File Identifier. This is the identifier used in the last invocation of
* {@link T4tNdefNfcee#writeData(int, byte[])}
*
@@ -191,73 +154,21 @@ public final class T4tNdefNfceeCcFileInfo implements Parcelable {
}
/**
- * T4T tag read access granted without any security.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0x0;
- /**
- * T4T tag read access granted with limited proprietary access only.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int READ_ACCESS_GRANTED_RESTRICTED = 0x80;
-
- /**
- * Possible return values for {@link #getVersion()}.
- * @hide
- */
- @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
- READ_ACCESS_GRANTED_RESTRICTED,
- READ_ACCESS_GRANTED_UNRESTRICTED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ReadAccess {}
-
- /**
* Indicates the read access condition.
* Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- * @return read access restriction
+ * @return boolean true if read access is allowed, otherwise false.
*/
- @ReadAccess
- public int getReadAccess() {
- return mReadAccess;
+ public boolean isReadAllowed() {
+ return mIsReadAllowed;
}
/**
- * T4T tag write access granted without any security.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0x0;
- /**
- * T4T tag write access granted with limited proprietary access only.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 0x80;
- /**
- * T4T tag write access not granted.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int WRITE_ACCESS_NOT_GRANTED = 0xFF;
-
- /**
- * Possible return values for {@link #getVersion()}.
- * @hide
- */
- @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
- WRITE_ACCESS_GRANTED_RESTRICTED,
- WRITE_ACCESS_GRANTED_UNRESTRICTED,
- WRITE_ACCESS_NOT_GRANTED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface WriteAccess {}
-
- /**
* Indicates the write access condition.
* Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- * @return write access restriction
+ * @return boolean if write access is allowed, otherwise false.
*/
- @WriteAccess
- public int getWriteAccess() {
- return mWriteAccess;
+ public boolean isWriteAllowed() {
+ return mIsWriteAllowed;
}
@Override
@@ -273,16 +184,14 @@ public final class T4tNdefNfceeCcFileInfo implements Parcelable {
// NdefNfceeCcFileInfo fields
int cclen = in.readInt();
int version = in.readInt();
- int maxLe = in.readInt();
- int maxLc = in.readInt();
int ndefFileId = in.readInt();
int ndefMaxSize = in.readInt();
- int ndefReadAccess = in.readInt();
- int ndefWriteAccess = in.readInt();
+ boolean isReadAllowed = in.readBoolean();
+ boolean isWriteAllowed = in.readBoolean();
- return new T4tNdefNfceeCcFileInfo(cclen, version, maxLe, maxLc,
+ return new T4tNdefNfceeCcFileInfo(cclen, version,
ndefFileId, ndefMaxSize,
- ndefReadAccess, ndefWriteAccess);
+ isReadAllowed, isWriteAllowed);
}
@Override
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
index 3d293f7546a5..eac783628ed9 100644
--- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -148,6 +148,12 @@ public final class ApduServiceInfo implements Parcelable {
private boolean mShouldDefaultToObserveMode;
/**
+ * Whether or not this service wants to share the same routing priority as the
+ * Wallet role owner.
+ */
+ private boolean mShareRolePriority;
+
+ /**
* @hide
*/
@UnsupportedAppUsage
@@ -284,6 +290,12 @@ public final class ApduServiceInfo implements Parcelable {
mShouldDefaultToObserveMode = sa.getBoolean(
R.styleable.HostApduService_shouldDefaultToObserveMode,
false);
+ if (Flags.nfcAssociatedRoleServices()) {
+ mShareRolePriority = sa.getBoolean(
+ R.styleable.HostApduService_shareRolePriority,
+ false
+ );
+ }
sa.recycle();
} else {
TypedArray sa = res.obtainAttributes(attrs,
@@ -314,6 +326,12 @@ public final class ApduServiceInfo implements Parcelable {
}
}
mStaticOffHostName = mOffHostName;
+ if (Flags.nfcAssociatedRoleServices()) {
+ mShareRolePriority = sa.getBoolean(
+ R.styleable.OffHostApduService_shareRolePriority,
+ false
+ );
+ }
sa.recycle();
}
@@ -705,6 +723,17 @@ public final class ApduServiceInfo implements Parcelable {
}
/**
+ * Returns whether or not this service wants to share the Wallet role holder priority
+ * with other packages/services with the same signature.
+ *
+ * @return whether or not this service wants to share priority
+ */
+ @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
+ public boolean shareRolePriority() {
+ return mShareRolePriority;
+ }
+
+ /**
* Returns description of service.
* @return user readable description of service
*/
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index cb364fb3298e..e0bc15fe6e94 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -246,6 +246,25 @@ public final class CardEmulation {
@Retention(RetentionPolicy.SOURCE)
public @interface SetServiceEnabledStatusCode {}
+ /**
+ * Property name used to indicate that an application wants to allow associated services
+ * to share the same AID routing priority when this application is the role holder.
+ * <p>
+ * Example:
+ * <pre>
+ * {@code
+ * <application>
+ * ...
+ * <property android:name="android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY"
+ * android:value="true"/>
+ * </application>
+ * }
+ * </pre>
+ */
+ @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
+ public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY =
+ "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
+
static boolean sIsInitialized = false;
static HashMap<Context, CardEmulation> sCardEmus = new HashMap<Context, CardEmulation>();
static INfcCardEmulation sService;
@@ -1095,6 +1114,14 @@ public final class CardEmulation {
@FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3;
+ /**
+ * Setting the default subscription ID failed because of unknown error.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+ public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1;
+
/** @hide */
@IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_",
value = {
@@ -1102,6 +1129,7 @@ public final class CardEmulation {
SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID,
SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR,
SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED,
+ SET_SUBSCRIPTION_ID_STATUS_UNKNOWN
})
@Retention(RetentionPolicy.SOURCE)
public @interface SetSubscriptionIdStatus {}
@@ -1110,9 +1138,10 @@ public final class CardEmulation {
* Sets the system's default NFC subscription id.
*
* <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this sets the
- * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+ * default UICC NFCEE that will handle NFC offhost CE transactions </p>
*
- * @param subscriptionId the default NFC subscription Id to set.
+ * @param subscriptionId the default NFC subscription Id to set. User can get subscription id
+ * from {@link SubscriptionManager#getSubscriptionId(int)}
* @return status of the operation.
*
* @throws UnsupportedOperationException If the device does not have
@@ -1134,7 +1163,7 @@ public final class CardEmulation {
* Returns the system's default NFC subscription id.
*
* <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this returns the
- * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+ * default UICC NFCEE that will handle NFC offhost CE transactions </p>
* <p> If the device has no UICC that can serve as NFCEE, this will return
* {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.</p>
*
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
index db1f6a2bb3b1..fbf2203b40b4 100644
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ b/nfc/java/android/nfc/cardemulation/HostApduService.java
@@ -289,7 +289,7 @@ public abstract class HostApduService extends Service {
try {
mNfcService.send(responseMsg);
} catch (RemoteException e) {
- Log.e("TAG", "Response not sent; RemoteException calling into " +
+ Log.e(TAG, "Response not sent; RemoteException calling into " +
"NfcService.");
}
}
diff --git a/nfc/lint-baseline.xml b/nfc/lint-baseline.xml
index d0f797e5c6b8..c6c627e4ea8d 100644
--- a/nfc/lint-baseline.xml
+++ b/nfc/lint-baseline.xml
@@ -2,215 +2,6 @@
<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
<issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `new android.nfc.cardemulation.AidGroup`"
- errorLine1=" AidGroup aidGroup = new AidGroup(aids, category);"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="377"
- column="29"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.AidGroup#getAids`"
- errorLine1=" return (group != null ? group.getAids() : null);"
- errorLine2=" ~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="537"
- column="43"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.AidGroup#getAids`"
- errorLine1=" return (group != null ? group.getAids() : null);"
- errorLine2=" ~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="547"
- column="47"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#getAids`"
- errorLine1=" return (serviceInfo != null ? serviceInfo.getAids() : null);"
- errorLine2=" ~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="714"
- column="55"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#getAids`"
- errorLine1=" return (serviceInfo != null ? serviceInfo.getAids() : null);"
- errorLine2=" ~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="724"
- column="59"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#isOnHost`"
- errorLine1=" if (!serviceInfo.isOnHost()) {"
- errorLine2=" ~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="755"
- column="34"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#getOffHostSecureElement`"
- errorLine1=" return serviceInfo.getOffHostSecureElement() == null ?"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="756"
- column="40"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#getOffHostSecureElement`"
- errorLine1=' "OffHost" : serviceInfo.getOffHostSecureElement();'
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="757"
- column="53"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#isOnHost`"
- errorLine1=" if (!serviceInfo.isOnHost()) {"
- errorLine2=" ~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="772"
- column="38"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#getOffHostSecureElement`"
- errorLine1=" return serviceInfo.getOffHostSecureElement() == null ?"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="773"
- column="44"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#getOffHostSecureElement`"
- errorLine1=' "Offhost" : serviceInfo.getOffHostSecureElement();'
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="774"
- column="57"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#getDescription`"
- errorLine1=" return (serviceInfo != null ? serviceInfo.getDescription() : null);"
- errorLine2=" ~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="798"
- column="55"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.nfc.cardemulation.ApduServiceInfo#getDescription`"
- errorLine1=" return (serviceInfo != null ? serviceInfo.getDescription() : null);"
- errorLine2=" ~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="808"
- column="59"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.app.Activity#isResumed`"
- errorLine1=" if (!activity.isResumed()) {"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="1032"
- column="23"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.app.Activity#isResumed`"
- errorLine1=" if (!activity.isResumed()) {"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/CardEmulation.java"
- line="1066"
- column="23"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.app.Activity#isResumed`"
- errorLine1=" resumed = activity.isResumed();"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/NfcActivityManager.java"
- line="124"
- column="32"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.app.Activity#isResumed`"
- errorLine1=" if (!activity.isResumed()) {"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
- line="2457"
- column="23"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.app.Activity#isResumed`"
- errorLine1=" if (!activity.isResumed()) {"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java"
- line="315"
- column="23"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 35 (current min is 34): `android.app.Activity#isResumed`"
- errorLine1=" if (!activity.isResumed()) {"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java"
- line="351"
- column="23"/>
- </issue>
-
- <issue
id="FlaggedApi"
message="Method `PollingFrame()` is a flagged API and should be inside an `if (Flags.nfcReadPollingLoop())` check (or annotate the surrounding method `handleMessage` with `@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) to transfer requirement to caller`)"
errorLine1=" pollingFrames.add(new PollingFrame(frame));"
@@ -265,4 +56,4 @@
column="44"/>
</issue>
-</issues> \ No newline at end of file
+</issues>
diff --git a/nfc/tests/Android.bp b/nfc/tests/Android.bp
index bfa814d149f0..b6090e853158 100644
--- a/nfc/tests/Android.bp
+++ b/nfc/tests/Android.bp
@@ -25,17 +25,36 @@ package {
android_test {
name: "NfcManagerTests",
static_libs: [
- "androidx.test.ext.junit",
+ "androidx.test.core",
"androidx.test.rules",
- "mockito-target-minus-junit4",
+ "androidx.test.runner",
+ "androidx.test.ext.junit",
+ "framework-nfc.impl",
+ "mockito-target-extended-minus-junit4",
+ "frameworks-base-testutils",
"truth",
+ "androidx.annotation_annotation",
+ "androidx.appcompat_appcompat",
+ "flag-junit",
+ "platform-test-annotations",
+ "testables",
],
libs: [
- "framework-nfc.impl",
+ "android.test.base.stubs.system",
+ "android.test.mock.stubs.system",
"android.test.runner.stubs.system",
],
+ jni_libs: [
+ // Required for ExtendedMockito
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
srcs: ["src/**/*.java"],
platform_apis: true,
certificate: "platform",
- test_suites: ["device-tests"],
+ test_suites: [
+ "device-tests",
+ "mts-nfc",
+ ],
+ min_sdk_version: "35", // Should be 36 later.
}
diff --git a/nfc/tests/AndroidManifest.xml b/nfc/tests/AndroidManifest.xml
index 99e2c34c656b..95646720d3d5 100644
--- a/nfc/tests/AndroidManifest.xml
+++ b/nfc/tests/AndroidManifest.xml
@@ -17,7 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.nfc">
- <application>
+ <application android:debuggable="true">
<uses-library android:name="android.test.runner" />
</application>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index 2227943c0cc0..9140cefe4574 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -66,7 +66,6 @@ import java.util.Map;
public final class DeviceConfigService extends Binder {
private static final List<String> sAconfigTextProtoFilesOnDevice = List.of(
"/system/etc/aconfig_flags.pb",
- "/system_ext/etc/aconfig_flags.pb",
"/product/etc/aconfig_flags.pb",
"/vendor/etc/aconfig_flags.pb");
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/EventLogTags.logtags b/packages/SettingsProvider/src/com/android/providers/settings/EventLogTags.logtags
index 7eff16b0def4..0367fe0dab01 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/EventLogTags.logtags
+++ b/packages/SettingsProvider/src/com/android/providers/settings/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.providers.settings;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 68b66dfa2657..3b4988e1f0e6 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -171,7 +171,6 @@ final class SettingsState {
private static final List<String> sAconfigTextProtoFilesOnDevice = List.of(
"/system/etc/aconfig_flags.pb",
- "/system_ext/etc/aconfig_flags.pb",
"/product/etc/aconfig_flags.pb",
"/vendor/etc/aconfig_flags.pb");
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
index 032979447861..0a4198a99bba 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
@@ -32,7 +32,8 @@ import java.util.Optional
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -125,14 +126,11 @@ class HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest : SysuiTes
)
underTest =
- HomeControlsKeyguardQuickAffordanceConfig(
- context = context,
- component = component,
- )
+ HomeControlsKeyguardQuickAffordanceConfig(context = context, component = component)
}
@Test
- fun state() = runBlockingTest {
+ fun state() = runTest(UnconfinedTestDispatcher()) {
whenever(component.isEnabled()).thenReturn(isFeatureEnabled)
whenever(controlsController.getFavorites())
.thenReturn(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
index 7d68cc0a3560..c9b436614505 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
@@ -19,19 +19,20 @@ package com.android.systemui.keyguard.data.quickaffordance
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
+import com.android.systemui.res.R
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import java.util.Optional
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -54,14 +55,11 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))
underTest =
- HomeControlsKeyguardQuickAffordanceConfig(
- context = context,
- component = component,
- )
+ HomeControlsKeyguardQuickAffordanceConfig(context = context, component = component)
}
@Test
- fun state_whenCannotShowWhileLocked_returnsHidden() = runBlockingTest {
+ fun state_whenCannotShowWhileLocked_returnsHidden() = runTest(UnconfinedTestDispatcher()) {
whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
whenever(component.isEnabled()).thenReturn(true)
whenever(component.getTileImageId()).thenReturn(R.drawable.controls_icon)
@@ -81,7 +79,7 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
}
@Test
- fun state_whenListingControllerIsMissing_returnsHidden() = runBlockingTest {
+ fun state_whenListingControllerIsMissing_returnsHidden() = runTest(UnconfinedTestDispatcher()) {
whenever(component.isEnabled()).thenReturn(true)
whenever(component.getTileImageId()).thenReturn(R.drawable.controls_icon)
whenever(component.getTileTitleId()).thenReturn(R.string.quick_controls_title)
@@ -100,23 +98,25 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
}
@Test
- fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsTrue() = runBlockingTest {
- whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))
+ fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsTrue() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))
- val onClickedResult = underTest.onTriggered(expandable)
+ val onClickedResult = underTest.onTriggered(expandable)
- assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
- assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked).isTrue()
- }
+ assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
+ assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked).isTrue()
+ }
@Test
- fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsFalse() = runBlockingTest {
- whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
+ fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsFalse() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
- val onClickedResult = underTest.onTriggered(expandable)
+ val onClickedResult = underTest.onTriggered(expandable)
- assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
- assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked)
- .isFalse()
- }
+ assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
+ assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked)
+ .isFalse()
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
index ca64cec98b2e..a3f07634940e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
@@ -29,7 +29,7 @@ import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -56,60 +56,63 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
}
@Test
- fun affordance_setsUpRegistrationAndDeliversInitialModel() = runBlockingTest {
- whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
- var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
-
- val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+ fun affordance_setsUpRegistrationAndDeliversInitialModel() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+ var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+
+ val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+
+ val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+ verify(controller).addCallback(callbackCaptor.capture())
+ verify(controller)
+ .registerQRCodeScannerChangeObservers(
+ QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
+ QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE,
+ )
+ assertVisibleState(latest)
- val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
- verify(controller).addCallback(callbackCaptor.capture())
- verify(controller)
- .registerQRCodeScannerChangeObservers(
- QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
- QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE
- )
- assertVisibleState(latest)
-
- job.cancel()
- verify(controller).removeCallback(callbackCaptor.value)
- }
+ job.cancel()
+ verify(controller).removeCallback(callbackCaptor.value)
+ }
@Test
- fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() = runBlockingTest {
- whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
- var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
- val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
- val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
- verify(controller).addCallback(callbackCaptor.capture())
+ fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+ var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+ val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+ val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+ verify(controller).addCallback(callbackCaptor.capture())
- whenever(controller.intent).thenReturn(INTENT_2)
- callbackCaptor.value.onQRCodeScannerActivityChanged()
+ whenever(controller.intent).thenReturn(INTENT_2)
+ callbackCaptor.value.onQRCodeScannerActivityChanged()
- assertVisibleState(latest)
+ assertVisibleState(latest)
- job.cancel()
- verify(controller).removeCallback(callbackCaptor.value)
- }
+ job.cancel()
+ verify(controller).removeCallback(callbackCaptor.value)
+ }
@Test
- fun affordance_scannerPreferenceChanged_deliversVisibleModel() = runBlockingTest {
- var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
- val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
- val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
- verify(controller).addCallback(callbackCaptor.capture())
+ fun affordance_scannerPreferenceChanged_deliversVisibleModel() =
+ runTest(UnconfinedTestDispatcher()) {
+ var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+ val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+ val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+ verify(controller).addCallback(callbackCaptor.capture())
- whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
- callbackCaptor.value.onQRCodeScannerPreferenceChanged()
+ whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+ callbackCaptor.value.onQRCodeScannerPreferenceChanged()
- assertVisibleState(latest)
+ assertVisibleState(latest)
- job.cancel()
- verify(controller).removeCallback(callbackCaptor.value)
- }
+ job.cancel()
+ verify(controller).removeCallback(callbackCaptor.value)
+ }
@Test
- fun affordance_scannerPreferenceChanged_deliversNone() = runBlockingTest {
+ fun affordance_scannerPreferenceChanged_deliversNone() = runTest(UnconfinedTestDispatcher()) {
var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
@@ -128,30 +131,29 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
fun onQuickAffordanceTriggered() {
assertThat(underTest.onTriggered(mock()))
.isEqualTo(
- OnTriggeredResult.StartActivity(
- intent = INTENT_1,
- canShowWhileLocked = true,
- )
+ OnTriggeredResult.StartActivity(intent = INTENT_1, canShowWhileLocked = true)
)
}
@Test
- fun getPickerScreenState_enabledIfConfiguredOnDevice_isEnabledForPickerState() = runTest {
- whenever(controller.isAllowedOnLockScreen).thenReturn(true)
- whenever(controller.isAbleToLaunchScannerActivity).thenReturn(true)
+ fun getPickerScreenState_enabledIfConfiguredOnDevice_isEnabledForPickerState() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(controller.isAllowedOnLockScreen).thenReturn(true)
+ whenever(controller.isAbleToLaunchScannerActivity).thenReturn(true)
- assertThat(underTest.getPickerScreenState())
- .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
- }
+ assertThat(underTest.getPickerScreenState())
+ .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
+ }
@Test
- fun getPickerScreenState_disabledIfConfiguredOnDevice_isDisabledForPickerState() = runTest {
- whenever(controller.isAllowedOnLockScreen).thenReturn(true)
- whenever(controller.isAbleToLaunchScannerActivity).thenReturn(false)
-
- assertThat(underTest.getPickerScreenState())
- .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
- }
+ fun getPickerScreenState_disabledIfConfiguredOnDevice_isDisabledForPickerState() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(controller.isAllowedOnLockScreen).thenReturn(true)
+ whenever(controller.isAbleToLaunchScannerActivity).thenReturn(false)
+
+ assertThat(underTest.getPickerScreenState())
+ .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
+ }
private fun assertVisibleState(latest: KeyguardQuickAffordanceConfig.LockScreenState?) {
assertThat(latest)
diff --git a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
index 08236b7e280a..ca5424bc0c52 100644
--- a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
+++ b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.systemui;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
index 1f66c91b3573..1ed8c068f974 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
@@ -1,3 +1,4 @@
# Bug component: 44215
-include /core/java/android/view/accessibility/OWNERS \ No newline at end of file
+include /core/java/android/view/accessibility/OWNERS
+jonesriley@google.com \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS b/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
index 95b8fa74feeb..4976d94d9057 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
@@ -1,3 +1,3 @@
# Bug component: 1280508
-# Files in this directory should still be reviewed by a member of SystemUI team
+asapperstein@google.com
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
index 2c1718176571..bfbdc50c32b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
@@ -24,9 +24,9 @@ import android.os.Handler
import android.os.Looper
import android.os.PatternMatcher
import android.os.UserHandle
-import androidx.test.filters.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
import com.android.systemui.dump.DumpManager
@@ -40,8 +40,9 @@ import java.util.concurrent.Executor
import junit.framework.Assert.assertSame
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.advanceUntilIdle
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -68,39 +69,28 @@ class BroadcastDispatcherTest : SysuiTestCase() {
val DEFAULT_PERMISSION: String? = null
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
+
const val TEST_ACTION = "TEST_ACTION"
const val TEST_SCHEME = "TEST_SCHEME"
const val TEST_PATH = "TEST_PATH"
const val TEST_TYPE = "test/type"
}
- @Mock
- private lateinit var mockContext: Context
- @Mock
- private lateinit var mockUBRUser0: UserBroadcastDispatcher
- @Mock
- private lateinit var mockUBRUser1: UserBroadcastDispatcher
- @Mock
- private lateinit var broadcastReceiver: BroadcastReceiver
- @Mock
- private lateinit var broadcastReceiverOther: BroadcastReceiver
- @Mock
- private lateinit var intentFilter: IntentFilter
- @Mock
- private lateinit var intentFilterOther: IntentFilter
- @Mock
- private lateinit var mockHandler: Handler
- @Mock
- private lateinit var logger: BroadcastDispatcherLogger
- @Mock
- private lateinit var userTracker: UserTracker
- @Mock
- private lateinit var removalPendingStore: PendingRemovalStore
+ @Mock private lateinit var mockContext: Context
+ @Mock private lateinit var mockUBRUser0: UserBroadcastDispatcher
+ @Mock private lateinit var mockUBRUser1: UserBroadcastDispatcher
+ @Mock private lateinit var broadcastReceiver: BroadcastReceiver
+ @Mock private lateinit var broadcastReceiverOther: BroadcastReceiver
+ @Mock private lateinit var intentFilter: IntentFilter
+ @Mock private lateinit var intentFilterOther: IntentFilter
+ @Mock private lateinit var mockHandler: Handler
+ @Mock private lateinit var logger: BroadcastDispatcherLogger
+ @Mock private lateinit var userTracker: UserTracker
+ @Mock private lateinit var removalPendingStore: PendingRemovalStore
private lateinit var mainExecutor: Executor
- @Captor
- private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>
+ @Captor private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>
private lateinit var testableLooper: TestableLooper
private lateinit var broadcastDispatcher: BroadcastDispatcher
@@ -112,7 +102,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {
mainExecutor = FakeExecutor(FakeSystemClock())
`when`(mockContext.mainExecutor).thenReturn(mainExecutor)
- broadcastDispatcher = TestBroadcastDispatcher(
+ broadcastDispatcher =
+ TestBroadcastDispatcher(
mockContext,
mainExecutor,
testableLooper.looper,
@@ -121,7 +112,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {
logger,
userTracker,
removalPendingStore,
- mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
+ mapOf(0 to mockUBRUser0, 1 to mockUBRUser1),
+ )
// These should be valid filters
`when`(intentFilter.countActions()).thenReturn(1)
@@ -131,10 +123,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testAddingReceiverToCorrectUBR() {
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user0)
broadcastDispatcher.registerReceiverWithHandler(
- broadcastReceiverOther, intentFilterOther, mockHandler, user1)
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user0,
+ )
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiverOther,
+ intentFilterOther,
+ mockHandler,
+ user1,
+ )
testableLooper.processAllMessages()
@@ -152,7 +152,11 @@ class BroadcastDispatcherTest : SysuiTestCase() {
fun testAddingReceiverToCorrectUBR_executor() {
broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mainExecutor, user0)
broadcastDispatcher.registerReceiver(
- broadcastReceiverOther, intentFilterOther, mainExecutor, user1)
+ broadcastReceiverOther,
+ intentFilterOther,
+ mainExecutor,
+ user1,
+ )
testableLooper.processAllMessages()
@@ -169,7 +173,10 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testAddReceiverDefaultFlag_handler() {
broadcastDispatcher.registerReceiverWithHandler(
- broadcastReceiver, intentFilter, mockHandler)
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ )
testableLooper.processAllMessages()
verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG))
@@ -183,7 +190,11 @@ class BroadcastDispatcherTest : SysuiTestCase() {
val flag = 3
broadcastDispatcher.registerReceiverWithHandler(
- broadcastReceiver, intentFilter, mockHandler, flags = flag)
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ flags = flag,
+ )
testableLooper.processAllMessages()
verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(flag))
@@ -212,7 +223,7 @@ class BroadcastDispatcherTest : SysuiTestCase() {
broadcastReceiver,
intentFilter,
flags = flag,
- permission = permission
+ permission = permission,
)
testableLooper.processAllMessages()
@@ -250,10 +261,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testRemovingReceiversRemovesFromAllUBR() {
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user0)
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user1)
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user0,
+ )
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user1,
+ )
broadcastDispatcher.unregisterReceiver(broadcastReceiver)
@@ -265,10 +284,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testRemoveReceiverFromUser() {
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user0)
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user1)
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user0,
+ )
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user1,
+ )
broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, user0)
@@ -282,13 +309,17 @@ class BroadcastDispatcherTest : SysuiTestCase() {
fun testRegisterCurrentAsActualUser() {
`when`(userTracker.userId).thenReturn(user1.identifier)
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, UserHandle.CURRENT)
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ UserHandle.CURRENT,
+ )
testableLooper.processAllMessages()
- verify(mockUBRUser1).registerReceiver(
- capture(argumentCaptor), eq(Context.RECEIVER_EXPORTED))
+ verify(mockUBRUser1)
+ .registerReceiver(capture(argumentCaptor), eq(Context.RECEIVER_EXPORTED))
assertSame(broadcastReceiver, argumentCaptor.value.receiver)
}
@@ -300,41 +331,38 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataScheme() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- addDataScheme(TEST_SCHEME)
- }
+ val testFilter = IntentFilter(TEST_ACTION).apply { addDataScheme(TEST_SCHEME) }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataAuthority() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- addDataAuthority(mock(IntentFilter.AuthorityEntry::class.java))
- }
+ val testFilter =
+ IntentFilter(TEST_ACTION).apply {
+ addDataAuthority(mock(IntentFilter.AuthorityEntry::class.java))
+ }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataPath() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- addDataPath(TEST_PATH, PatternMatcher.PATTERN_LITERAL)
- }
+ val testFilter =
+ IntentFilter(TEST_ACTION).apply {
+ addDataPath(TEST_PATH, PatternMatcher.PATTERN_LITERAL)
+ }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataType() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- addDataType(TEST_TYPE)
- }
+ val testFilter = IntentFilter(TEST_ACTION).apply { addDataType(TEST_TYPE) }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotSetPriority() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- priority = IntentFilter.SYSTEM_HIGH_PRIORITY
- }
+ val testFilter =
+ IntentFilter(TEST_ACTION).apply { priority = IntentFilter.SYSTEM_HIGH_PRIORITY }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@@ -366,12 +394,14 @@ class BroadcastDispatcherTest : SysuiTestCase() {
val inOrderUser0 = inOrder(mockUBRUser0, removalPendingStore)
inOrderUser0.verify(mockUBRUser0).unregisterReceiver(broadcastReceiver)
- inOrderUser0.verify(removalPendingStore)
+ inOrderUser0
+ .verify(removalPendingStore)
.clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)
val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
- inOrderUser1.verify(removalPendingStore)
+ inOrderUser1
+ .verify(removalPendingStore)
.clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)
}
@@ -385,21 +415,21 @@ class BroadcastDispatcherTest : SysuiTestCase() {
val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
- inOrderUser1.verify(removalPendingStore)
+ inOrderUser1
+ .verify(removalPendingStore)
.clearPendingRemoval(broadcastReceiver, user1.identifier)
}
@Test
- fun testBroadcastFlow() = runBlockingTest {
- val flow = broadcastDispatcher.broadcastFlow(intentFilter, user1) { intent, receiver ->
- intent to receiver
- }
+ fun testBroadcastFlow() = runTest(UnconfinedTestDispatcher()) {
+ val flow =
+ broadcastDispatcher.broadcastFlow(intentFilter, user1) { intent, receiver ->
+ intent to receiver
+ }
// Collect the values into collectedValues.
val collectedValues = mutableListOf<Pair<Intent, BroadcastReceiver>>()
- val job = launch {
- flow.collect { collectedValues.add(it) }
- }
+ val job = launch { flow.collect { collectedValues.add(it) } }
testableLooper.processAllMessages()
verify(mockUBRUser1).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG))
@@ -436,17 +466,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {
logger: BroadcastDispatcherLogger,
userTracker: UserTracker,
removalPendingStore: PendingRemovalStore,
- var mockUBRMap: Map<Int, UserBroadcastDispatcher>
- ) : BroadcastDispatcher(
- context,
- mainExecutor,
- backgroundRunningLooper,
- backgroundRunningExecutor,
- dumpManager,
- logger,
- userTracker,
- removalPendingStore
- ) {
+ var mockUBRMap: Map<Int, UserBroadcastDispatcher>,
+ ) :
+ BroadcastDispatcher(
+ context,
+ mainExecutor,
+ backgroundRunningLooper,
+ backgroundRunningExecutor,
+ dumpManager,
+ logger,
+ userTracker,
+ removalPendingStore,
+ ) {
override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
index 0669cb8b8ba5..fceeb752194b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
@@ -37,7 +37,7 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.TestCoroutineScope
+import kotlinx.coroutines.test.TestScope
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -125,11 +125,7 @@ class UserRepositoryImplTest : SysuiTestCase() {
whenever(mainUser.identifier).thenReturn(mainUserId)
underTest = create(this)
- val initialExpectedValue =
- setUpUsers(
- count = 3,
- selectedIndex = 0,
- )
+ val initialExpectedValue = setUpUsers(count = 3, selectedIndex = 0)
var userInfos: List<UserInfo>? = null
var selectedUserInfo: UserInfo? = null
underTest.userInfos.onEach { userInfos = it }.launchIn(this)
@@ -140,23 +136,14 @@ class UserRepositoryImplTest : SysuiTestCase() {
assertThat(selectedUserInfo).isEqualTo(initialExpectedValue[0])
assertThat(underTest.lastSelectedNonGuestUserId).isEqualTo(selectedUserInfo?.id)
- val secondExpectedValue =
- setUpUsers(
- count = 4,
- selectedIndex = 1,
- )
+ val secondExpectedValue = setUpUsers(count = 4, selectedIndex = 1)
underTest.refreshUsers()
assertThat(userInfos).isEqualTo(secondExpectedValue)
assertThat(selectedUserInfo).isEqualTo(secondExpectedValue[1])
assertThat(underTest.lastSelectedNonGuestUserId).isEqualTo(selectedUserInfo?.id)
val selectedNonGuestUserId = selectedUserInfo?.id
- val thirdExpectedValue =
- setUpUsers(
- count = 2,
- isLastGuestUser = true,
- selectedIndex = 1,
- )
+ val thirdExpectedValue = setUpUsers(count = 2, isLastGuestUser = true, selectedIndex = 1)
underTest.refreshUsers()
assertThat(userInfos).isEqualTo(thirdExpectedValue)
assertThat(selectedUserInfo).isEqualTo(thirdExpectedValue[1])
@@ -168,12 +155,7 @@ class UserRepositoryImplTest : SysuiTestCase() {
@Test
fun refreshUsers_sortsByCreationTime_guestUserLast() = runSelfCancelingTest {
underTest = create(this)
- val unsortedUsers =
- setUpUsers(
- count = 3,
- selectedIndex = 0,
- isLastGuestUser = true,
- )
+ val unsortedUsers = setUpUsers(count = 3, selectedIndex = 0, isLastGuestUser = true)
unsortedUsers[0].creationTime = 999
unsortedUsers[1].creationTime = 900
unsortedUsers[2].creationTime = 950
@@ -197,30 +179,22 @@ class UserRepositoryImplTest : SysuiTestCase() {
): List<UserInfo> {
val userInfos =
(0 until count).map { index ->
- createUserInfo(
- index,
- isGuest = isLastGuestUser && index == count - 1,
- )
+ createUserInfo(index, isGuest = isLastGuestUser && index == count - 1)
}
whenever(manager.aliveUsers).thenReturn(userInfos)
tracker.set(userInfos, selectedIndex)
return userInfos
}
+
@Test
fun userTrackerCallback_updatesSelectedUserInfo() = runSelfCancelingTest {
underTest = create(this)
var selectedUserInfo: UserInfo? = null
underTest.selectedUserInfo.onEach { selectedUserInfo = it }.launchIn(this)
- setUpUsers(
- count = 2,
- selectedIndex = 0,
- )
+ setUpUsers(count = 2, selectedIndex = 0)
tracker.onProfileChanged()
assertThat(selectedUserInfo?.id).isEqualTo(0)
- setUpUsers(
- count = 2,
- selectedIndex = 1,
- )
+ setUpUsers(count = 2, selectedIndex = 1)
tracker.onProfileChanged()
assertThat(selectedUserInfo?.id).isEqualTo(1)
}
@@ -259,10 +233,7 @@ class UserRepositoryImplTest : SysuiTestCase() {
assertThat(selectedUser!!.selectionStatus).isEqualTo(SelectionStatus.SELECTION_IN_PROGRESS)
}
- private fun createUserInfo(
- id: Int,
- isGuest: Boolean,
- ): UserInfo {
+ private fun createUserInfo(id: Int, isGuest: Boolean): UserInfo {
val flags = 0
return UserInfo(
id,
@@ -312,16 +283,14 @@ class UserRepositoryImplTest : SysuiTestCase() {
* Executes the given block of execution within the scope of a dedicated [CoroutineScope] which
* is then automatically canceled and cleaned-up.
*/
- private fun runSelfCancelingTest(
- block: suspend CoroutineScope.() -> Unit,
- ) =
+ private fun runSelfCancelingTest(block: suspend CoroutineScope.() -> Unit) =
runBlocking(Dispatchers.Main.immediate) {
val scope = CoroutineScope(coroutineContext + Job())
block(scope)
scope.cancel()
}
- private fun create(scope: CoroutineScope = TestCoroutineScope()): UserRepositoryImpl {
+ private fun create(scope: CoroutineScope = TestScope()): UserRepositoryImpl {
return UserRepositoryImpl(
appContext = context,
manager = manager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
index 01795e92d141..670c84dcfed2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
@@ -27,6 +27,7 @@ import com.android.internal.logging.UiEventLogger
import com.android.systemui.GuestResetOrExitSessionReceiver
import com.android.systemui.GuestResumeSessionReceiver
import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.user.domain.model.ShowDialogRequestModel
@@ -34,8 +35,9 @@ import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.kotlinArgumentCaptor
import com.android.systemui.util.mockito.whenever
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.TestCoroutineScope
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -62,9 +64,10 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
@Mock private lateinit var otherContext: Context
+ private val testDispatcher = UnconfinedTestDispatcher()
+ private val testScope = TestScope(testDispatcher)
private lateinit var underTest: GuestUserInteractor
- private lateinit var scope: TestCoroutineScope
private lateinit var repository: FakeUserRepository
@Before
@@ -72,7 +75,6 @@ class GuestUserInteractorTest : SysuiTestCase() {
MockitoAnnotations.initMocks(this)
whenever(manager.createGuest(any())).thenReturn(GUEST_USER_INFO)
- scope = TestCoroutineScope()
repository = FakeUserRepository()
repository.setUserInfos(ALL_USERS)
@@ -82,17 +84,17 @@ class GuestUserInteractorTest : SysuiTestCase() {
private fun initGuestUserInteractor(context: Context) =
GuestUserInteractor(
applicationContext = context,
- applicationScope = scope,
- mainDispatcher = IMMEDIATE,
- backgroundDispatcher = IMMEDIATE,
+ applicationScope = testScope,
+ mainDispatcher = testDispatcher,
+ backgroundDispatcher = testDispatcher,
manager = manager,
repository = repository,
deviceProvisionedController = deviceProvisionedController,
devicePolicyManager = devicePolicyManager,
refreshUsersScheduler =
RefreshUsersScheduler(
- applicationScope = scope,
- mainDispatcher = IMMEDIATE,
+ applicationScope = testScope,
+ mainDispatcher = testDispatcher,
repository = repository,
),
uiEventLogger = uiEventLogger,
@@ -118,7 +120,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun onDeviceBootCompleted_allowedToAdd_createGuest() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
setAllowedToAdd()
underTest.onDeviceBootCompleted()
@@ -129,7 +131,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun onDeviceBootCompleted_awaitProvisioning_andCreateGuest() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
setAllowedToAdd(isAllowed = false)
underTest.onDeviceBootCompleted()
val captor =
@@ -145,7 +147,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun createAndSwitchTo() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
underTest.createAndSwitchTo(
showDialog = showDialog,
dismissDialog = dismissDialog,
@@ -160,7 +162,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun createAndSwitchTo_failsToCreate_doesNotSwitchTo() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
whenever(manager.createGuest(any())).thenReturn(null)
underTest.createAndSwitchTo(
@@ -177,7 +179,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_returnsToTargetUser() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
repository.setSelectedUserInfo(GUEST_USER_INFO)
val targetUserId = NON_GUEST_USER_INFO.id
@@ -197,7 +199,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_returnsToLastNonGuest() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
val expectedUserId = NON_GUEST_USER_INFO.id
whenever(manager.getUserInfo(expectedUserId)).thenReturn(NON_GUEST_USER_INFO)
repository.lastSelectedNonGuestUserId = expectedUserId
@@ -219,7 +221,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_lastNonGuestWasRemoved_returnsToMainUser() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
val removedUserId = 310
val mainUserId = 10
repository.lastSelectedNonGuestUserId = removedUserId
@@ -242,7 +244,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_guestWasEphemeral_itIsRemoved() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setUserInfos(listOf(NON_GUEST_USER_INFO, EPHEMERAL_GUEST_USER_INFO))
repository.setSelectedUserInfo(EPHEMERAL_GUEST_USER_INFO)
@@ -265,7 +267,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_forceRemoveGuest_itIsRemoved() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setSelectedUserInfo(GUEST_USER_INFO)
val targetUserId = NON_GUEST_USER_INFO.id
@@ -287,7 +289,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_selectedDifferentFromGuestUser_doNothing() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
underTest.exit(
@@ -304,7 +306,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_selectedIsActuallyNotAguestUser_doNothing() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
underTest.exit(
@@ -321,7 +323,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun remove_returnsToTargetUser() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setSelectedUserInfo(GUEST_USER_INFO)
@@ -342,7 +344,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun remove_selectedDifferentFromGuestUser_doNothing() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
@@ -359,7 +361,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun remove_selectedIsActuallyNotAguestUser_doNothing() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
@@ -395,11 +397,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
companion object {
private val IMMEDIATE = Dispatchers.Main.immediate
private val NON_GUEST_USER_INFO =
- UserInfo(
- /* id= */ 818,
- /* name= */ "non_guest",
- /* flags= */ UserInfo.FLAG_FULL,
- )
+ UserInfo(/* id= */ 818, /* name= */ "non_guest", /* flags= */ UserInfo.FLAG_FULL)
private val GUEST_USER_INFO =
UserInfo(
/* id= */ 669,
@@ -416,10 +414,6 @@ class GuestUserInteractorTest : SysuiTestCase() {
/* flags= */ UserInfo.FLAG_EPHEMERAL or UserInfo.FLAG_FULL,
UserManager.USER_TYPE_FULL_GUEST,
)
- private val ALL_USERS =
- listOf(
- NON_GUEST_USER_INFO,
- GUEST_USER_INFO,
- )
+ private val ALL_USERS = listOf(NON_GUEST_USER_INFO, GUEST_USER_INFO)
}
}
diff --git a/ravenwood/scripts/extract-last-soong-commands.py b/ravenwood/scripts/extract-last-soong-commands.py
index bdc1de0c44f4..c08d4aa799a5 100755
--- a/ravenwood/scripts/extract-last-soong-commands.py
+++ b/ravenwood/scripts/extract-last-soong-commands.py
@@ -48,6 +48,7 @@ def main(args):
with open(outfile, "w") as out:
out.write(HEADER)
+ count = 0
with gzip.open(log) as f:
for line in f:
s = line.decode("utf-8")
@@ -63,7 +64,8 @@ def main(args):
if m:
command = m.groups()[0]
- out.write('#========\n')
+ count += 1
+ out.write(f'### Command {count} ========\n')
# Show the full command line before executing it.
out.write('#echo ' + shlex.quote(command) + '\n')
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index ced7773eff56..11de25832a2d 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -130,17 +130,18 @@ public class MmsServiceBroker extends SystemService {
}
@Override
- public void sendMessage(int subId, String callingPkg, Uri contentUri, String locationUrl,
- Bundle configOverrides, PendingIntent sentIntent, long messageId,
+ public void sendMessage(int subId, int callingUser, String callingPkg,
+ Uri contentUri, String locationUrl, Bundle configOverrides,
+ PendingIntent sentIntent, long messageId,
String attributionTag) throws RemoteException {
returnPendingIntentWithError(sentIntent);
}
@Override
- public void downloadMessage(int subId, String callingPkg, String locationUrl,
- Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent,
- long messageId, String attributionTag)
- throws RemoteException {
+ public void downloadMessage(int subId, int callingUser, String callingPkg,
+ String locationUrl, Uri contentUri, Bundle configOverrides,
+ PendingIntent downloadedIntent,
+ long messageId, String attributionTag) throws RemoteException {
returnPendingIntentWithError(downloadedIntent);
}
@@ -151,8 +152,9 @@ public class MmsServiceBroker extends SystemService {
}
@Override
- public Uri importMultimediaMessage(String callingPkg, Uri contentUri, String messageId,
- long timestampSecs, boolean seen, boolean read) throws RemoteException {
+ public Uri importMultimediaMessage(int callingUser, String callingPkg,
+ Uri contentUri, String messageId, long timestampSecs,
+ boolean seen, boolean read) throws RemoteException {
return null;
}
@@ -187,8 +189,8 @@ public class MmsServiceBroker extends SystemService {
}
@Override
- public Uri addMultimediaMessageDraft(String callingPkg, Uri contentUri)
- throws RemoteException {
+ public Uri addMultimediaMessageDraft(int callingUser, String callingPkg,
+ Uri contentUri) throws RemoteException {
return null;
}
@@ -333,9 +335,9 @@ public class MmsServiceBroker extends SystemService {
private static final String PHONE_PACKAGE_NAME = "com.android.phone";
@Override
- public void sendMessage(int subId, String callingPkg, Uri contentUri,
- String locationUrl, Bundle configOverrides, PendingIntent sentIntent,
- long messageId, String attributionTag)
+ public void sendMessage(int subId, int callingUser, String callingPkg,
+ Uri contentUri, String locationUrl, Bundle configOverrides,
+ PendingIntent sentIntent, long messageId, String attributionTag)
throws RemoteException {
Slog.d(TAG, "sendMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message");
@@ -360,14 +362,15 @@ public class MmsServiceBroker extends SystemService {
CarrierMessagingService.SERVICE_INTERFACE,
Intent.FLAG_GRANT_READ_URI_PERMISSION,
subId);
- getServiceGuarded().sendMessage(subId, callingPkg, contentUri, locationUrl,
- configOverrides, sentIntent, messageId, attributionTag);
+ getServiceGuarded().sendMessage(subId, getCallingUserId(), callingPkg, contentUri,
+ locationUrl, configOverrides, sentIntent, messageId, attributionTag);
}
@Override
- public void downloadMessage(int subId, String callingPkg, String locationUrl,
- Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent,
- long messageId, String attributionTag) throws RemoteException {
+ public void downloadMessage(int subId, int callingUser, String callingPkg,
+ String locationUrl, Uri contentUri, Bundle configOverrides,
+ PendingIntent downloadedIntent, long messageId, String attributionTag)
+ throws RemoteException {
Slog.d(TAG, "downloadMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.RECEIVE_MMS,
"Download MMS message");
@@ -381,8 +384,8 @@ public class MmsServiceBroker extends SystemService {
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
subId);
- getServiceGuarded().downloadMessage(subId, callingPkg, locationUrl, contentUri,
- configOverrides, downloadedIntent, messageId, attributionTag);
+ getServiceGuarded().downloadMessage(subId, getCallingUserId(), callingPkg, locationUrl,
+ contentUri, configOverrides, downloadedIntent, messageId, attributionTag);
}
@Override
@@ -399,8 +402,8 @@ public class MmsServiceBroker extends SystemService {
}
@Override
- public Uri importMultimediaMessage(String callingPkg, Uri contentUri,
- String messageId, long timestampSecs, boolean seen, boolean read)
+ public Uri importMultimediaMessage(int callingUser, String callingPkg,
+ Uri contentUri, String messageId, long timestampSecs, boolean seen, boolean read)
throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
@@ -408,8 +411,8 @@ public class MmsServiceBroker extends SystemService {
// while writing the TelephonyProvider
return FAKE_MMS_SENT_URI;
}
- return getServiceGuarded().importMultimediaMessage(
- callingPkg, contentUri, messageId, timestampSecs, seen, read);
+ return getServiceGuarded().importMultimediaMessage(getCallingUserId(), callingPkg,
+ contentUri, messageId, timestampSecs, seen, read);
}
@Override
@@ -467,15 +470,16 @@ public class MmsServiceBroker extends SystemService {
}
@Override
- public Uri addMultimediaMessageDraft(String callingPkg, Uri contentUri)
- throws RemoteException {
+ public Uri addMultimediaMessageDraft(int callingUser, String callingPkg,
+ Uri contentUri) throws RemoteException {
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
callingPkg, null, null) != AppOpsManager.MODE_ALLOWED) {
// Silently fail AppOps failure due to not being the default SMS app
// while writing the TelephonyProvider
return FAKE_MMS_DRAFT_URI;
}
- return getServiceGuarded().addMultimediaMessageDraft(callingPkg, contentUri);
+ return getServiceGuarded().addMultimediaMessageDraft(getCallingUserId(), callingPkg,
+ contentUri);
}
@Override
@@ -572,4 +576,13 @@ public class MmsServiceBroker extends SystemService {
if (info == null) return INVALID_SIM_SLOT_INDEX;
return info.getSimSlotIndex();
}
+
+ /**
+ * Retrieves the calling user id.
+ * @return The id of the calling user.
+ */
+ private int getCallingUserId() {
+ return Binder.getCallingUserHandle().getIdentifier();
+ }
+
}
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index d9926a4a0f0d..674e1492fe33 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -1849,15 +1849,19 @@ public class PackageWatchdog {
bootMitigationCounts.put(observer.name, observer.getBootMitigationCount());
}
+ FileOutputStream fileStream = null;
+ ObjectOutputStream objectStream = null;
try {
- FileOutputStream fileStream = new FileOutputStream(new File(filePath));
- ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
+ fileStream = new FileOutputStream(new File(filePath));
+ objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(bootMitigationCounts);
objectStream.flush();
- objectStream.close();
- fileStream.close();
} catch (Exception e) {
Slog.i(TAG, "Could not save observers metadata to file: " + e);
+ return;
+ } finally {
+ IoUtils.closeQuietly(objectStream);
+ IoUtils.closeQuietly(fileStream);
}
}
@@ -2008,23 +2012,32 @@ public class PackageWatchdog {
void readAllObserversBootMitigationCountIfNecessary(String filePath) {
File metadataFile = new File(filePath);
if (metadataFile.exists()) {
+ FileInputStream fileStream = null;
+ ObjectInputStream objectStream = null;
+ HashMap<String, Integer> bootMitigationCounts = null;
try {
- FileInputStream fileStream = new FileInputStream(metadataFile);
- ObjectInputStream objectStream = new ObjectInputStream(fileStream);
- HashMap<String, Integer> bootMitigationCounts =
+ fileStream = new FileInputStream(metadataFile);
+ objectStream = new ObjectInputStream(fileStream);
+ bootMitigationCounts =
(HashMap<String, Integer>) objectStream.readObject();
- objectStream.close();
- fileStream.close();
-
- for (int i = 0; i < mAllObservers.size(); i++) {
- final ObserverInternal observer = mAllObservers.valueAt(i);
- if (bootMitigationCounts.containsKey(observer.name)) {
- observer.setBootMitigationCount(
- bootMitigationCounts.get(observer.name));
- }
- }
} catch (Exception e) {
Slog.i(TAG, "Could not read observer metadata file: " + e);
+ return;
+ } finally {
+ IoUtils.closeQuietly(objectStream);
+ IoUtils.closeQuietly(fileStream);
+ }
+
+ if (bootMitigationCounts == null || bootMitigationCounts.isEmpty()) {
+ Slog.i(TAG, "No observer in metadata file");
+ return;
+ }
+ for (int i = 0; i < mAllObservers.size(); i++) {
+ final ObserverInternal observer = mAllObservers.valueAt(i);
+ if (bootMitigationCounts.containsKey(observer.name)) {
+ observer.setBootMitigationCount(
+ bootMitigationCounts.get(observer.name));
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0152f94072f4..3cac3a8e44ed 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2861,9 +2861,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mIsolatedAppBindArgs = new ArrayMap<>(1);
// See b/79378449 about the following exemption.
addServiceToMap(mIsolatedAppBindArgs, "package");
- if (!android.server.Flags.removeJavaServiceManagerCache()) {
- addServiceToMap(mIsolatedAppBindArgs, "permissionmgr");
- }
+ addServiceToMap(mIsolatedAppBindArgs, "permissionmgr");
}
return mIsolatedAppBindArgs;
}
@@ -2874,38 +2872,27 @@ public class ActivityManagerService extends IActivityManager.Stub
// Add common services.
// IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
// Enable the check in ApplicationThread.bindApplication() to make sure.
-
- // Removing User Service and App Ops Service from cache breaks boot for auto.
- // Removing permissionmgr breaks tests for Android Auto due to SELinux restrictions.
- // TODO: fix SELinux restrictions and remove caching for Android Auto.
- if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
- || !android.server.Flags.removeJavaServiceManagerCache()) {
- addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
- addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
- addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
- addServiceToMap(mAppBindArgs, Context.CONNECTIVITY_SERVICE);
- addServiceToMap(mAppBindArgs, Context.ACCESSIBILITY_SERVICE);
- addServiceToMap(mAppBindArgs, Context.INPUT_METHOD_SERVICE);
- addServiceToMap(mAppBindArgs, Context.INPUT_SERVICE);
- addServiceToMap(mAppBindArgs, "graphicsstats");
- addServiceToMap(mAppBindArgs, "content");
- addServiceToMap(mAppBindArgs, Context.JOB_SCHEDULER_SERVICE);
- addServiceToMap(mAppBindArgs, Context.NOTIFICATION_SERVICE);
- addServiceToMap(mAppBindArgs, Context.VIBRATOR_SERVICE);
- addServiceToMap(mAppBindArgs, Context.ACCOUNT_SERVICE);
- addServiceToMap(mAppBindArgs, Context.POWER_SERVICE);
- addServiceToMap(mAppBindArgs, "mount");
- addServiceToMap(mAppBindArgs, Context.PLATFORM_COMPAT_SERVICE);
- }
- // See b/79378449
- // Getting the window service and package service binder from servicemanager
- // is blocked for Apps. However they are necessary for apps.
- // TODO: remove exception
addServiceToMap(mAppBindArgs, "package");
- addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
- addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
addServiceToMap(mAppBindArgs, "permissionmgr");
+ addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.CONNECTIVITY_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.ACCESSIBILITY_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.INPUT_METHOD_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.INPUT_SERVICE);
+ addServiceToMap(mAppBindArgs, "graphicsstats");
addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
+ addServiceToMap(mAppBindArgs, "content");
+ addServiceToMap(mAppBindArgs, Context.JOB_SCHEDULER_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.NOTIFICATION_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.VIBRATOR_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.ACCOUNT_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.POWER_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
+ addServiceToMap(mAppBindArgs, "mount");
+ addServiceToMap(mAppBindArgs, Context.PLATFORM_COMPAT_SERVICE);
}
return mAppBindArgs;
}
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index f79256d6147b..c4a787db6922 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -39,6 +39,7 @@ import android.aconfigd.Aconfigd.StorageRequestMessages;
import android.aconfigd.Aconfigd.StorageReturnMessage;
import android.aconfigd.Aconfigd.StorageReturnMessages;
import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon;
+import static com.android.aconfig_new_storage.Flags.enableAconfigdFromMainline;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -388,16 +389,38 @@ public class SettingsToPropertiesMapper {
* @param requests: request proto output stream
* @return aconfigd socket return as proto input stream
*/
- static ProtoInputStream sendAconfigdRequests(ProtoOutputStream requests) {
+ static void sendAconfigdRequests(ProtoOutputStream requests) {
+ ProtoInputStream returns = sendAconfigdRequests("aconfigd_system", requests);
+ try {
+ parseAndLogAconfigdReturn(returns);
+ } catch (IOException ioe) {
+ logErr("failed to parse aconfigd return", ioe);
+ }
+ if (enableAconfigdFromMainline()) {
+ returns = sendAconfigdRequests("aconfigd_mainline", requests);
+ try {
+ parseAndLogAconfigdReturn(returns);
+ } catch (IOException ioe) {
+ logErr("failed to parse aconfigd return", ioe);
+ }
+ }
+ }
+
+ /**
+ * apply flag local override in aconfig new storage
+ * @param socketName: the socket to send to
+ * @param requests: request proto output stream
+ * @return aconfigd socket return as proto input stream
+ */
+ static ProtoInputStream sendAconfigdRequests(String socketName, ProtoOutputStream requests) {
// connect to aconfigd socket
LocalSocket client = new LocalSocket();
- String socketName = "aconfigd_system";
try {
client.connect(new LocalSocketAddress(
socketName, LocalSocketAddress.Namespace.RESERVED));
- Slog.d(TAG, "connected to aconfigd socket");
+ Slog.d(TAG, "connected to " + socketName + " socket");
} catch (IOException ioe) {
- logErr("failed to connect to aconfigd socket", ioe);
+ logErr("failed to connect to " + socketName + " socket", ioe);
return null;
}
@@ -416,9 +439,9 @@ public class SettingsToPropertiesMapper {
byte[] requests_bytes = requests.getBytes();
outputStream.writeInt(requests_bytes.length);
outputStream.write(requests_bytes, 0, requests_bytes.length);
- Slog.d(TAG, "flag override requests sent to aconfigd");
+ Slog.d(TAG, "flag override requests sent to " + socketName);
} catch (IOException ioe) {
- logErr("failed to send requests to aconfigd", ioe);
+ logErr("failed to send requests to " + socketName, ioe);
return null;
}
@@ -426,10 +449,10 @@ public class SettingsToPropertiesMapper {
try {
int num_bytes = inputStream.readInt();
ProtoInputStream returns = new ProtoInputStream(inputStream);
- Slog.d(TAG, "received " + num_bytes + " bytes back from aconfigd");
+ Slog.d(TAG, "received " + num_bytes + " bytes back from " + socketName);
return returns;
} catch (IOException ioe) {
- logErr("failed to read requests return from aconfigd", ioe);
+ logErr("failed to read requests return from " + socketName, ioe);
return null;
}
}
@@ -524,15 +547,8 @@ public class SettingsToPropertiesMapper {
return;
}
- // send requests to aconfigd and obtain the return byte buffer
- ProtoInputStream returns = sendAconfigdRequests(requests);
-
- // deserialize back using proto input stream
- try {
- parseAndLogAconfigdReturn(returns);
- } catch (IOException ioe) {
- logErr("failed to parse aconfigd return", ioe);
- }
+ // send requests to aconfigd
+ sendAconfigdRequests(requests);
}
public static SettingsToPropertiesMapper start(ContentResolver contentResolver) {
@@ -642,15 +658,8 @@ public class SettingsToPropertiesMapper {
return;
}
- // send requests to aconfigd and obtain the return
- ProtoInputStream returns = sendAconfigdRequests(requests);
-
- // deserialize back using proto input stream
- try {
- parseAndLogAconfigdReturn(returns);
- } catch (IOException ioe) {
- logErr("failed to parse aconfigd return", ioe);
- }
+ // send requests to aconfigd
+ sendAconfigdRequests(requests);
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b22bc2b8c5be..0e0b518bf3b9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3019,6 +3019,16 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mDexOptHelper.performPackageDexOptUpgradeIfNeeded();
}
+ public void updateMetricsIfNeeded() {
+ final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+ if (displayManager != null) {
+ final Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+ if (display != null) {
+ display.getMetrics(mMetrics);
+ }
+ }
+ }
+
private void notifyPackageUseInternal(String packageName, int reason) {
long time = System.currentTimeMillis();
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/policy/EventLogTags.logtags b/services/core/java/com/android/server/policy/EventLogTags.logtags
index 75633820d01f..a4b6472fbe62 100644
--- a/services/core/java/com/android/server/policy/EventLogTags.logtags
+++ b/services/core/java/com/android/server/policy/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.server.policy
diff --git a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
index 1208b6ef396f..08ceb61e14a8 100644
--- a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
+++ b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
@@ -142,6 +142,8 @@ public class ActivityServiceConnectionsHolder<T> {
/** Used by {@link ActivityRecord#dump}. */
@Override
public String toString() {
- return String.valueOf(mConnections);
+ synchronized (mActivity) {
+ return String.valueOf(mConnections);
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index cfd5300417b4..66ed0dae53f5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1535,7 +1535,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final ActivityRecord[] outActivity = new ActivityRecord[1];
- getActivityStartController().obtainStarter(intent, "dream")
+ final int res = getActivityStartController()
+ .obtainStarter(intent, "dream")
.setCallingUid(callingUid)
.setCallingPid(callingPid)
.setCallingPackage(intent.getPackage())
@@ -1549,9 +1550,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
.execute();
final ActivityRecord started = outActivity[0];
- final IAppTask appTask = started == null ? null :
- new AppTaskImpl(this, started.getTask().mTaskId, callingUid);
- return appTask;
+ if (started == null || !ActivityManager.isStartResultSuccessful(res)) {
+ // start the dream activity failed.
+ return null;
+ }
+ return new AppTaskImpl(this, started.getTask().mTaskId, callingUid);
}
}
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index d70a88062ebd..e86cb7d96ccf 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -453,15 +453,17 @@ final class ContentRecorder implements WindowContainerListener {
case RECORD_CONTENT_TASK:
// Given the WindowToken of the region to record, retrieve the associated
// SurfaceControl.
- if (tokenToRecord == null) {
+ final WindowContainer wc = tokenToRecord != null
+ ? WindowContainer.fromBinder(tokenToRecord) : null;
+ if (wc == null) {
handleStartRecordingFailed();
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Unable to start recording due to null token for "
- + "display %d",
+ "Content Recording: Unable to start recording due to null token or " +
+ "null window container for " + "display %d",
mDisplayContent.getDisplayId());
return null;
}
- Task taskToRecord = WindowContainer.fromBinder(tokenToRecord).asTask();
+ final Task taskToRecord = wc.asTask();
if (taskToRecord == null) {
handleStartRecordingFailed();
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index aaa7f12690fb..b278274d9387 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8010,42 +8010,45 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void waitForAllWindowsDrawn(Message message, long timeout, int displayId) {
Objects.requireNonNull(message.getTarget());
- final WindowContainer<?> container = displayId == INVALID_DISPLAY
- ? mRoot : mRoot.getDisplayContent(displayId);
- if (container == null) {
- // The waiting container doesn't exist, no need to wait to run the callback. Run and
- // return;
- message.sendToTarget();
- return;
- }
boolean allWindowsDrawn = false;
synchronized (mGlobalLock) {
- if (mRoot.getDefaultDisplay().mDisplayUpdater.waitForTransition(message)) {
- // Use the ready-to-play of transition as the signal.
- return;
- }
- container.waitForAllWindowsDrawn();
- mWindowPlacerLocked.requestTraversal();
- mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
- if (container.mWaitingForDrawn.isEmpty()) {
- allWindowsDrawn = true;
- } else {
- if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
- for (int i = 0; i < container.mWaitingForDrawn.size(); i++) {
- traceStartWaitingForWindowDrawn(container.mWaitingForDrawn.get(i));
- }
- }
-
- mWaitingForDrawnCallbacks.put(container, message);
- mH.sendNewMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, container, timeout);
- checkDrawnWindowsLocked();
- }
+ allWindowsDrawn = waitForAllWindowsDrawnLocked(message, timeout, displayId);
}
if (allWindowsDrawn) {
message.sendToTarget();
}
}
+ /** Return {@code true} if all windows have been drawn. */
+ private boolean waitForAllWindowsDrawnLocked(Message message, long timeout, int displayId) {
+ final WindowContainer<?> container = displayId == INVALID_DISPLAY
+ ? mRoot : mRoot.getDisplayContent(displayId);
+ if (container == null) {
+ // The waiting container doesn't exist, no need to wait. Treat as drawn.
+ return true;
+ }
+ if (mRoot.getDefaultDisplay().mDisplayUpdater.waitForTransition(message)) {
+ // Use the ready-to-play of transition as the signal.
+ return false;
+ }
+ container.waitForAllWindowsDrawn();
+ mWindowPlacerLocked.requestTraversal();
+ mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
+ if (container.mWaitingForDrawn.isEmpty()) {
+ return true;
+ }
+ if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
+ for (int i = 0; i < container.mWaitingForDrawn.size(); i++) {
+ traceStartWaitingForWindowDrawn(container.mWaitingForDrawn.get(i));
+ }
+ }
+
+ mWaitingForDrawnCallbacks.put(container, message);
+ mH.sendNewMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, container, timeout);
+ checkDrawnWindowsLocked();
+ return false;
+ }
+
@Override
public void setForcedDisplaySize(int displayId, int width, int height) {
WindowManagerService.this.setForcedDisplaySize(displayId, width, height);
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 95e7b198c1bb..d9af3df6e0d6 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -564,8 +564,8 @@ static jstring com_android_server_am_CachedAppOptimizer_getFreezerCheckPath(JNIE
jobject clazz) {
std::string path;
- if (!getAttributePathForTask("FreezerState", getpid(), &path)) {
- path = "";
+ if (!CgroupGetAttributePathForTask("FreezerState", getpid(), &path)) {
+ path.clear();
}
return env->NewStringUTF(path.c_str());
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0718f043ae2a..32f88f78426c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1847,6 +1847,10 @@ public final class SystemServer implements Dumpable {
}
t.traceEnd();
+ t.traceBegin("UpdateMetricsIfNeeded");
+ mPackageManagerService.updateMetricsIfNeeded();
+ t.traceEnd();
+
t.traceBegin("PerformFstrimIfNeeded");
try {
mPackageManagerService.performFstrimIfNeeded();
diff --git a/services/java/com/android/server/flags.aconfig b/services/java/com/android/server/flags.aconfig
index 41a9646cb6d5..38354e849129 100644
--- a/services/java/com/android/server/flags.aconfig
+++ b/services/java/com/android/server/flags.aconfig
@@ -10,14 +10,6 @@ flag {
}
flag {
- name: "remove_java_service_manager_cache"
- namespace: "system_performance"
- description: "This flag turns off Java's Service Manager caching mechanism."
- bug: "333854840"
- is_fixed_read_only: true
-}
-
-flag {
name: "remove_text_service"
namespace: "wear_frameworks"
description: "Remove TextServiceManagerService on Wear"
diff --git a/services/tests/ondeviceintelligencetests/OWNERS b/services/tests/ondeviceintelligencetests/OWNERS
index 09774f78d712..a4fc7582a785 100644
--- a/services/tests/ondeviceintelligencetests/OWNERS
+++ b/services/tests/ondeviceintelligencetests/OWNERS
@@ -1 +1,3 @@
-file:/core/java/android/app/ondeviceintelligence/OWNERS
+shiqing@google.com
+sandeepbandaru@google.com
+shivanker@google.com
diff --git a/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java b/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java
new file mode 100644
index 000000000000..a2df73b7d540
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.server.utils;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class LazyJniRegistrarTest {
+
+ @Test
+ public void testNativeMethodsResolve() throws Exception {
+ // Basic test with a few explicit invocations to make sure methods resolve and don't throw.
+ LazyJniRegistrar.registerConsumerIrService();
+ LazyJniRegistrar.registerGameManagerService();
+ LazyJniRegistrar.registerVrManagerService();
+ }
+
+ @Test
+ public void testAllNativeRegisterMethodsResolve() throws Exception {
+ // Catch-all test to make sure public static register* methods resolve and don't throw.
+ for (Method method : LazyJniRegistrar.class.getDeclaredMethods()) {
+ if (Modifier.isPublic(method.getModifiers())
+ && Modifier.isStatic(method.getModifiers())
+ && method.getName().startsWith("register")) {
+ method.invoke(null);
+ }
+ }
+ }
+
+ // TODO(b/302724778): Remove manual JNI load
+ static {
+ System.loadLibrary("servicestestjni");
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/utils/OWNERS b/services/tests/servicestests/src/com/android/server/utils/OWNERS
index f5b19a1c40ae..69b9fa23c040 100644
--- a/services/tests/servicestests/src/com/android/server/utils/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/utils/OWNERS
@@ -1,5 +1,6 @@
per-file EventLoggerTest.java = file:/platform/frameworks/av:/media/janitors/media_solutions_OWNERS
per-file EventLoggerTest.java = jmtrivi@google.com
+per-file LazyJniRegistrarTest.java = file:/PERFORMANCE_OWNERS
# Bug component : 158088 = per-file AnrTimer*.java
per-file AnrTimer*.java = file:/PERFORMANCE_OWNERS
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
index 100d869a663f..c51c6d661314 100644
--- a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
@@ -17,8 +17,12 @@
package com.android.systemfeatures
import android.annotation.SdkConstant
+import com.squareup.javapoet.ClassName
+import com.squareup.javapoet.CodeBlock
import com.squareup.javapoet.FieldSpec
import com.squareup.javapoet.JavaFile
+import com.squareup.javapoet.MethodSpec
+import com.squareup.javapoet.ParameterizedTypeName
import com.squareup.javapoet.TypeSpec
import java.io.IOException
import javax.annotation.processing.AbstractProcessor
@@ -27,6 +31,7 @@ import javax.annotation.processing.RoundEnvironment
import javax.lang.model.SourceVersion
import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement
+import javax.lang.model.element.VariableElement
import javax.tools.Diagnostic
/*
@@ -35,7 +40,16 @@ import javax.tools.Diagnostic
* <p>The output is a single class file, `com.android.internal.pm.SystemFeaturesMetadata`, with
* properties computed from feature constant definitions in the PackageManager class. This
* class is only produced if the processed environment includes PackageManager; all other
- * invocations are ignored.
+ * invocations are ignored. The generated API is as follows:
+ *
+ * <pre>
+ * package android.content.pm;
+ * public final class SystemFeaturesMetadata {
+ * public static final int SDK_FEATURE_COUNT;
+ * // @return [0, SDK_FEATURE_COUNT) if an SDK-defined system feature, -1 otherwise.
+ * public static int maybeGetSdkFeatureIndex(String featureName);
+ * }
+ * </pre>
*/
class SystemFeaturesMetadataProcessor : AbstractProcessor() {
@@ -56,19 +70,31 @@ class SystemFeaturesMetadataProcessor : AbstractProcessor() {
return false
}
- // We're only interested in feature constants defined in PackageManager.
- var featureCount = 0
- roundEnv.getElementsAnnotatedWith(SdkConstant::class.java).forEach {
- if (
- it.enclosingElement == packageManagerType &&
- it.getAnnotation(SdkConstant::class.java).value ==
- SdkConstant.SdkConstantType.FEATURE
- ) {
- featureCount++
- }
- }
+ // Collect all FEATURE-annotated fields from PackageManager, and
+ // 1) Use the field values to de-duplicate, as there can be multiple FEATURE_* fields that
+ // map to the same feature string name value.
+ // 2) Ensure they're sorted to ensure consistency and determinism between builds.
+ val featureVarNames =
+ roundEnv
+ .getElementsAnnotatedWith(SdkConstant::class.java)
+ .asSequence()
+ .filter {
+ it.enclosingElement == packageManagerType &&
+ it.getAnnotation(SdkConstant::class.java).value ==
+ SdkConstant.SdkConstantType.FEATURE
+ }
+ .mapNotNull { element ->
+ (element as? VariableElement)?.let { varElement ->
+ varElement.getConstantValue()?.toString() to
+ varElement.simpleName.toString()
+ }
+ }
+ .toMap()
+ .values
+ .sorted()
+ .toList()
- if (featureCount == 0) {
+ if (featureVarNames.isEmpty()) {
// This is fine, and happens for any environment that doesn't include PackageManager.
return false
}
@@ -77,16 +103,8 @@ class SystemFeaturesMetadataProcessor : AbstractProcessor() {
TypeSpec.classBuilder("SystemFeaturesMetadata")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addJavadoc("@hide")
- .addField(
- FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
- .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
- .addJavadoc(
- "The number of `@SdkConstant` features defined in PackageManager."
- )
- .addJavadoc("@hide")
- .initializer("\$L", featureCount)
- .build()
- )
+ .addFeatureCount(featureVarNames)
+ .addFeatureIndexLookup(featureVarNames)
.build()
try {
@@ -104,7 +122,71 @@ class SystemFeaturesMetadataProcessor : AbstractProcessor() {
return true
}
+ private fun TypeSpec.Builder.addFeatureCount(
+ featureVarNames: Collection<String>
+ ): TypeSpec.Builder {
+ return addField(
+ FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
+ .addJavadoc(
+ "# of {@link android.annotation.SdkConstant}` features in PackageManager."
+ )
+ .addJavadoc("\n\n@hide")
+ .initializer("\$L", featureVarNames.size)
+ .build()
+ )
+ }
+
+ private fun TypeSpec.Builder.addFeatureIndexLookup(
+ featureVarNames: Collection<String>
+ ): TypeSpec.Builder {
+ // NOTE: This was initially implemented in terms of a single, long switch() statement.
+ // However, this resulted in:
+ // 1) relatively large compiled code size for the lookup method (~20KB)
+ // 2) worse runtime lookup performance than a simple ArraySet
+ // The ArraySet approach adds just ~1KB to the code/image and is 2x faster at runtime.
+
+ // Provide the initial capacity of the ArraySet for efficiency.
+ addField(
+ FieldSpec.builder(
+ ParameterizedTypeName.get(ARRAYSET_CLASS, ClassName.get(String::class.java)),
+ "sFeatures",
+ )
+ .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
+ .initializer("new ArraySet<>(\$L)", featureVarNames.size)
+ .build()
+ )
+
+ // Use a temp array + Collections.addAll() to minimizes the generated code size.
+ addStaticBlock(
+ CodeBlock.builder()
+ .add("final \$T[] features = {\n", String::class.java)
+ .indent()
+ .apply { featureVarNames.forEach { add("\$T.\$N,\n", PACKAGEMANAGER_CLASS, it) } }
+ .unindent()
+ .addStatement("}")
+ .addStatement("\$T.addAll(sFeatures, features)", COLLECTIONS_CLASS)
+ .build()
+ )
+
+ // Use ArraySet.indexOf to provide the implicit feature index mapping.
+ return addMethod(
+ MethodSpec.methodBuilder("maybeGetSdkFeatureIndex")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .addJavadoc("@return an index in [0, SDK_FEATURE_COUNT) for features defined ")
+ .addJavadoc("in PackageManager, else -1.")
+ .addJavadoc("\n\n@hide")
+ .returns(Int::class.java)
+ .addParameter(String::class.java, "featureName")
+ .addStatement("return sFeatures.indexOf(featureName)")
+ .build()
+ )
+ }
+
companion object {
private val SDK_CONSTANT_ANNOTATION_NAME = SdkConstant::class.qualifiedName
+ private val PACKAGEMANAGER_CLASS = ClassName.get("android.content.pm", "PackageManager")
+ private val ARRAYSET_CLASS = ClassName.get("android.util", "ArraySet")
+ private val COLLECTIONS_CLASS = ClassName.get("java.util", "Collections")
}
}
diff --git a/tools/systemfeatures/tests/src/ArraySet.java b/tools/systemfeatures/tests/src/ArraySet.java
new file mode 100644
index 000000000000..0eb8f298bd89
--- /dev/null
+++ b/tools/systemfeatures/tests/src/ArraySet.java
@@ -0,0 +1,34 @@
+/*
+ * 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 android.util;
+
+import java.util.ArrayList;
+
+/** Stub for testing, we extend ArrayList to get indexOf() for free. */
+public final class ArraySet<K> extends ArrayList<K> {
+ public ArraySet(int capacity) {
+ super(capacity);
+ }
+
+ @Override
+ public boolean add(K k) {
+ if (!contains(k)) {
+ return super.add(k);
+ }
+ return false;
+ }
+}
diff --git a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
index 4ffb5b979d75..74ce6daaffc4 100644
--- a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
+++ b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
@@ -16,10 +16,16 @@
package com.android.systemfeatures;
+import static com.android.internal.pm.SystemFeaturesMetadata.maybeGetSdkFeatureIndex;
+
import static com.google.common.truth.Truth.assertThat;
+import android.content.pm.PackageManager;
+
import com.android.internal.pm.SystemFeaturesMetadata;
+import com.google.common.collect.Range;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -33,4 +39,17 @@ public class SystemFeaturesMetadataProcessorTest {
// It defines 5 annotated features, and any/all other constants should be ignored.
assertThat(SystemFeaturesMetadata.SDK_FEATURE_COUNT).isEqualTo(5);
}
+
+ @Test
+ public void testSdkFeatureIndex() {
+ // Only SDK-defined features return valid indices.
+ final Range validIndexRange = Range.closedOpen(0, SystemFeaturesMetadata.SDK_FEATURE_COUNT);
+ assertThat(maybeGetSdkFeatureIndex(PackageManager.FEATURE_PC)).isIn(validIndexRange);
+ assertThat(maybeGetSdkFeatureIndex(PackageManager.FEATURE_VULKAN)).isIn(validIndexRange);
+ assertThat(maybeGetSdkFeatureIndex(PackageManager.FEATURE_NOT_ANNOTATED)).isEqualTo(-1);
+ assertThat(maybeGetSdkFeatureIndex(PackageManager.NOT_FEATURE)).isEqualTo(-1);
+ assertThat(maybeGetSdkFeatureIndex("foo")).isEqualTo(-1);
+ assertThat(maybeGetSdkFeatureIndex("0")).isEqualTo(-1);
+ assertThat(maybeGetSdkFeatureIndex("")).isEqualTo(-1);
+ }
}