diff options
135 files changed, 1666 insertions, 1070 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 777228292eb5..f69fd55beb3a 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -49,7 +49,6 @@ aconfig_declarations_group { "android.media.tv.flags-aconfig-java", "android.multiuser.flags-aconfig-java", "android.net.platform.flags-aconfig-java", - "android.net.vcn.flags-aconfig-java-export", "android.net.wifi.flags-aconfig-java", "android.nfc.flags-aconfig-java", "android.os.flags-aconfig-java", @@ -304,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"], } @@ -321,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", @@ -857,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"], } @@ -1068,25 +1086,6 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } -// VCN -// TODO:376339506 Move the VCN code, the flag declaration and -// java_aconfig_library to framework-connectivity-b -aconfig_declarations { - name: "android.net.vcn.flags-aconfig", - package: "android.net.vcn", - container: "com.android.tethering", - exportable: true, - srcs: ["core/java/android/net/vcn/*.aconfig"], -} - -java_aconfig_library { - name: "android.net.vcn.flags-aconfig-java-export", - aconfig_declarations: "android.net.vcn.flags-aconfig", - mode: "exported", - min_sdk_version: "35", - defaults: ["framework-minus-apex-aconfig-java-defaults"], -} - // DevicePolicy aconfig_declarations { name: "device_policy_aconfig_flags", diff --git a/Android.bp b/Android.bp index 20e58ed377a8..68048c6bd445 100644 --- a/Android.bp +++ b/Android.bp @@ -87,6 +87,7 @@ filegroup { ":framework-wifi-non-updatable-sources", ":PacProcessor-aidl-sources", ":ProxyHandler-aidl-sources", + ":vcn-utils-platform-sources", ":net-utils-framework-common-srcs", // AIDL from frameworks/base/native/ @@ -314,6 +315,7 @@ java_defaults { ":framework-telephony-sources", ":framework-wifi-annotations", ":framework-wifi-non-updatable-sources", + ":vcn-utils-platform-sources", ":PacProcessor-aidl-sources", ":ProxyHandler-aidl-sources", ":net-utils-framework-common-srcs", @@ -582,7 +584,7 @@ filegroup { srcs: [ "core/java/com/android/internal/util/HexDump.java", "core/java/com/android/internal/util/WakeupMessage.java", - "core/java/android/net/vcn/util/PersistableBundleUtils.java", + "packages/Vcn/framework-b/src/android/net/vcn/util/PersistableBundleUtils.java", "telephony/java/android/telephony/Annotation.java", ], } 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 7915509c1381..579210507db3 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 @@ -29468,128 +29469,6 @@ package android.net.sip { } -package android.net.vcn { - - public final class VcnCellUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate { - method public int getCbs(); - method public int getDun(); - method public int getIms(); - method public int getInternet(); - method public int getMms(); - method @NonNull public java.util.Set<java.lang.String> getOperatorPlmnIds(); - method public int getOpportunistic(); - method public int getRcs(); - method public int getRoaming(); - method @NonNull public java.util.Set<java.lang.Integer> getSimSpecificCarrierIds(); - } - - public static final class VcnCellUnderlyingNetworkTemplate.Builder { - ctor public VcnCellUnderlyingNetworkTemplate.Builder(); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate build(); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setCbs(int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setDun(int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setIms(int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setInternet(int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMetered(int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMms(int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOperatorPlmnIds(@NonNull java.util.Set<java.lang.String>); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOpportunistic(int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRcs(int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRoaming(int); - method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setSimSpecificCarrierIds(@NonNull java.util.Set<java.lang.Integer>); - } - - public final class VcnConfig implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public java.util.Set<android.net.vcn.VcnGatewayConnectionConfig> getGatewayConnectionConfigs(); - method @NonNull public java.util.Set<java.lang.Integer> getRestrictedUnderlyingNetworkTransports(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnConfig> CREATOR; - } - - public static final class VcnConfig.Builder { - ctor public VcnConfig.Builder(@NonNull android.content.Context); - method @NonNull public android.net.vcn.VcnConfig.Builder addGatewayConnectionConfig(@NonNull android.net.vcn.VcnGatewayConnectionConfig); - method @NonNull public android.net.vcn.VcnConfig build(); - method @NonNull public android.net.vcn.VcnConfig.Builder setRestrictedUnderlyingNetworkTransports(@NonNull java.util.Set<java.lang.Integer>); - } - - public final class VcnGatewayConnectionConfig { - method @NonNull public int[] getExposedCapabilities(); - method @NonNull public String getGatewayConnectionName(); - method @IntRange(from=0x500) public int getMaxMtu(); - method public int getMinUdpPort4500NatTimeoutSeconds(); - method @NonNull public long[] getRetryIntervalsMillis(); - method @NonNull public java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkPriorities(); - method public boolean hasGatewayOption(int); - method @FlaggedApi("android.net.vcn.safe_mode_config") public boolean isSafeModeEnabled(); - field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1; // 0xffffffff - field public static final int VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY = 0; // 0x0 - } - - public static final class VcnGatewayConnectionConfig.Builder { - ctor public VcnGatewayConnectionConfig.Builder(@NonNull String, @NonNull android.net.ipsec.ike.IkeTunnelConnectionParams); - method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int); - method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addGatewayOption(int); - method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build(); - method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int); - method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeGatewayOption(int); - method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int); - method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int); - method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]); - method @FlaggedApi("android.net.vcn.safe_mode_config") @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setSafeModeEnabled(boolean); - method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate>); - } - - public class VcnManager { - method @RequiresPermission("carrier privileges") public void clearVcnConfig(@NonNull android.os.ParcelUuid) throws java.io.IOException; - method @NonNull public java.util.List<android.os.ParcelUuid> getConfiguredSubscriptionGroups(); - method public void registerVcnStatusCallback(@NonNull android.os.ParcelUuid, @NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnStatusCallback); - method @RequiresPermission("carrier privileges") public void setVcnConfig(@NonNull android.os.ParcelUuid, @NonNull android.net.vcn.VcnConfig) throws java.io.IOException; - method public void unregisterVcnStatusCallback(@NonNull android.net.vcn.VcnManager.VcnStatusCallback); - field public static final int VCN_ERROR_CODE_CONFIG_ERROR = 1; // 0x1 - field public static final int VCN_ERROR_CODE_INTERNAL_ERROR = 0; // 0x0 - field public static final int VCN_ERROR_CODE_NETWORK_ERROR = 2; // 0x2 - field public static final int VCN_STATUS_CODE_ACTIVE = 2; // 0x2 - field public static final int VCN_STATUS_CODE_INACTIVE = 1; // 0x1 - field public static final int VCN_STATUS_CODE_NOT_CONFIGURED = 0; // 0x0 - field public static final int VCN_STATUS_CODE_SAFE_MODE = 3; // 0x3 - } - - public abstract static class VcnManager.VcnStatusCallback { - ctor public VcnManager.VcnStatusCallback(); - method public abstract void onGatewayConnectionError(@NonNull String, int, @Nullable Throwable); - method public abstract void onStatusChanged(int); - } - - public abstract class VcnUnderlyingNetworkTemplate { - method public int getMetered(); - method public int getMinEntryDownstreamBandwidthKbps(); - method public int getMinEntryUpstreamBandwidthKbps(); - method public int getMinExitDownstreamBandwidthKbps(); - method public int getMinExitUpstreamBandwidthKbps(); - field public static final int MATCH_ANY = 0; // 0x0 - field public static final int MATCH_FORBIDDEN = 2; // 0x2 - field public static final int MATCH_REQUIRED = 1; // 0x1 - } - - public final class VcnWifiUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate { - method @NonNull public java.util.Set<java.lang.String> getSsids(); - } - - public static final class VcnWifiUnderlyingNetworkTemplate.Builder { - ctor public VcnWifiUnderlyingNetworkTemplate.Builder(); - method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate build(); - method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMetered(int); - method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int); - method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int); - method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setSsids(@NonNull java.util.Set<java.lang.String>); - } - -} - package android.opengl { public class EGL14 { @@ -48288,7 +48167,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 d3775dbb036d..5790a732f134 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -273,10 +273,6 @@ package android.media.session { package android.net { - @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class ConnectivityFrameworkInitializerBaklava { - method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static void registerServiceWrappers(); - } - public class LocalSocket implements java.io.Closeable { ctor public LocalSocket(@NonNull java.io.FileDescriptor); } @@ -336,25 +332,6 @@ package android.net.netstats { } -package android.net.vcn { - - @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class VcnTransportInfo implements android.os.Parcelable android.net.TransportInfo { - method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int describeContents(); - method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public long getApplicableRedactions(); - method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int getMinUdpPort4500NatTimeoutSeconds(); - method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.TransportInfo makeCopy(long); - method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public void writeToParcel(@NonNull android.os.Parcel, int); - field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnTransportInfo> CREATOR; - } - - @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final class VcnTransportInfo.Builder { - ctor @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public VcnTransportInfo.Builder(); - method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo build(); - method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int); - } - -} - package android.nfc { public class NfcServiceManager { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index f94c97e2076c..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"; @@ -9977,28 +9978,6 @@ package android.net.util { } -package android.net.vcn { - - public class VcnManager { - method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener); - method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties); - method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void removeVcnNetworkPolicyChangeListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener); - } - - public static interface VcnManager.VcnNetworkPolicyChangeListener { - method public void onPolicyChanged(); - } - - public final class VcnNetworkPolicyResult implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities(); - method public boolean isTeardownRequested(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnNetworkPolicyResult> CREATOR; - } - -} - package android.net.wifi { public final class WifiKeystore { @@ -10484,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/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/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index 11123a9986f9..4d1c98daab8f 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; +import android.ravenwood.annotation.RavenwoodReplace; import android.util.ArraySet; import android.util.EmptyArray; @@ -39,6 +40,10 @@ import java.util.function.IntFunction; /** * Static utility methods for arrays that aren't already included in {@link java.util.Arrays}. + * <p> + * Test with: + * <code>atest FrameworksUtilTests:com.android.internal.util.ArrayUtilsTest</code> + * <code>atest FrameworksUtilTestsRavenwood:com.android.internal.util.ArrayUtilsTest</code> */ @android.ravenwood.annotation.RavenwoodKeepWholeClass public class ArrayUtils { @@ -85,6 +90,69 @@ public class ArrayUtils { } /** + * This is like <code>new byte[length]</code>, but it allocates the array as non-movable. This + * prevents copies of the data from being left on the Java heap as a result of heap compaction. + * Use this when the array will contain sensitive data such as a password or cryptographic key + * that needs to be wiped from memory when no longer needed. The owner of the array is still + * responsible for the zeroization; {@link #zeroize(byte[])} should be used to do so. + * + * @param length the length of the array to allocate + * @return the new array + */ + public static byte[] newNonMovableByteArray(int length) { + return (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, length); + } + + /** + * Like {@link #newNonMovableByteArray(int)}, but allocates a char array. + * + * @param length the length of the array to allocate + * @return the new array + */ + public static char[] newNonMovableCharArray(int length) { + return (char[]) VMRuntime.getRuntime().newNonMovableArray(char.class, length); + } + + /** + * Zeroizes a byte array as securely as possible. Use this when the array contains sensitive + * data such as a password or cryptographic key. + * <p> + * This zeroizes the array in a way that is guaranteed to not be optimized out by the compiler. + * If supported by the architecture, it zeroizes the data not just in the L1 data cache but also + * in other levels of the memory hierarchy up to and including main memory (but not above that). + * <p> + * This works on any <code>byte[]</code>, but to ensure that copies of the array aren't left on + * the Java heap the array should have been allocated with {@link #newNonMovableByteArray(int)}. + * Use on other arrays might also introduce performance anomalies. + * + * @param array the array to zeroize. If null, this method has no effect. + */ + @RavenwoodReplace public static native void zeroize(byte[] array); + + /** + * Replacement of the above method for host-side unit testing that doesn't support JNI yet. + */ + public static void zeroize$ravenwood(byte[] array) { + if (array != null) { + Arrays.fill(array, (byte) 0); + } + } + + /** + * Like {@link #zeroize(byte[])}, but for char arrays. + */ + @RavenwoodReplace public static native void zeroize(char[] array); + + /** + * Replacement of the above method for host-side unit testing that doesn't support JNI yet. + */ + public static void zeroize$ravenwood(char[] array) { + if (array != null) { + Arrays.fill(array, (char) 0); + } + } + + /** * Checks if the beginnings of two byte arrays are equal. * * @param array1 the first byte array 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.bp b/core/jni/Android.bp index 0196ef5ef852..e71f607c5cce 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -90,6 +90,7 @@ cc_library_shared_for_libandroid_runtime { "android_view_VelocityTracker.cpp", "android_view_VerifiedKeyEvent.cpp", "android_view_VerifiedMotionEvent.cpp", + "com_android_internal_util_ArrayUtils.cpp", "com_android_internal_util_VirtualRefBasePtr.cpp", "core_jni_helpers.cpp", ":deviceproductinfoconstants_aidl", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index c5df248ec1a9..c005d63ff797 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -215,6 +215,7 @@ extern int register_com_android_internal_os_Zygote(JNIEnv *env); extern int register_com_android_internal_os_ZygoteCommandBuffer(JNIEnv *env); extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env); extern int register_com_android_internal_security_VerityUtils(JNIEnv* env); +extern int register_com_android_internal_util_ArrayUtils(JNIEnv* env); extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env); extern int register_android_window_WindowInfosListener(JNIEnv* env); extern int register_android_window_ScreenCapture(JNIEnv* env); @@ -1613,6 +1614,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer), REG_JNI(register_com_android_internal_os_ZygoteInit), REG_JNI(register_com_android_internal_security_VerityUtils), + REG_JNI(register_com_android_internal_util_ArrayUtils), REG_JNI(register_com_android_internal_util_VirtualRefBasePtr), REG_JNI(register_android_hardware_Camera), REG_JNI(register_android_hardware_camera2_CameraMetadata), 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/jni/com_android_internal_util_ArrayUtils.cpp b/core/jni/com_android_internal_util_ArrayUtils.cpp new file mode 100644 index 000000000000..c70625815b90 --- /dev/null +++ b/core/jni/com_android_internal_util_ArrayUtils.cpp @@ -0,0 +1,119 @@ +/* + * 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. + */ + +#define LOG_TAG "ArrayUtils" + +#include <android-base/logging.h> +#include <jni.h> +#include <nativehelper/JNIHelp.h> +#include <string.h> +#include <unistd.h> +#include <utils/Log.h> + +namespace android { + +static size_t GetCacheLineSize() { + long size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); + if (size <= 0) { + ALOGE("Unable to determine L1 data cache line size. Assuming 32 bytes"); + return 32; + } + // The cache line size should always be a power of 2. + CHECK((size & (size - 1)) == 0); + + return size; +} + +static void CleanCacheLineContainingAddress(const uint8_t* p) { +#if defined(__aarch64__) + // 'dc cvac' stands for "Data Cache line Clean by Virtual Address to point-of-Coherency". + // It writes the cache line back to the "point-of-coherency", i.e. main memory. + asm volatile("dc cvac, %0" ::"r"(p)); +#elif defined(__i386__) || defined(__x86_64__) + asm volatile("clflush (%0)" ::"r"(p)); +#elif defined(__riscv) + // This should eventually work, but it is not ready to be enabled yet: + // 1.) The Android emulator needs to add support for zicbom. + // 2.) Kernel needs to enable zicbom in usermode. + // 3.) Android clang needs to add zicbom to the target. + // asm volatile("cbo.clean (%0)" ::"r"(p)); +#elif defined(__arm__) + // arm32 has a cacheflush() syscall, but it is undocumented and only flushes the icache. + // It is not the same as cacheflush(2) as documented in the Linux man-pages project. +#else +#error "Unknown architecture" +#endif +} + +static void CleanDataCache(const uint8_t* p, size_t buffer_size, size_t cache_line_size) { + // Clean the first line that overlaps the buffer. + CleanCacheLineContainingAddress(p); + // Clean any additional lines that overlap the buffer. Use cache-line-aligned addresses to + // ensure that (a) the last cache line gets flushed, and (b) no cache line is flushed twice. + for (size_t i = cache_line_size - ((uintptr_t)p & (cache_line_size - 1)); i < buffer_size; + i += cache_line_size) { + CleanCacheLineContainingAddress(p + i); + } +} + +static void ZeroizePrimitiveArray(JNIEnv* env, jclass clazz, jarray array, size_t component_len) { + static const size_t cache_line_size = GetCacheLineSize(); + + if (array == nullptr) { + return; + } + + size_t buffer_size = env->GetArrayLength(array) * component_len; + if (buffer_size == 0) { + return; + } + + // ART guarantees that GetPrimitiveArrayCritical never copies. + jboolean isCopy; + void* elems = env->GetPrimitiveArrayCritical(array, &isCopy); + CHECK(!isCopy); + +#ifdef __BIONIC__ + memset_explicit(elems, 0, buffer_size); +#else + memset(elems, 0, buffer_size); +#endif + // Clean the data cache so that the data gets zeroized in main memory right away. Without this, + // it might not be written to main memory until the cache line happens to be evicted. + CleanDataCache(static_cast<const uint8_t*>(elems), buffer_size, cache_line_size); + + env->ReleasePrimitiveArrayCritical(array, elems, /* mode= */ 0); +} + +static void ZeroizeByteArray(JNIEnv* env, jclass clazz, jbyteArray array) { + ZeroizePrimitiveArray(env, clazz, array, sizeof(jbyte)); +} + +static void ZeroizeCharArray(JNIEnv* env, jclass clazz, jcharArray array) { + ZeroizePrimitiveArray(env, clazz, array, sizeof(jchar)); +} + +static const JNINativeMethod sMethods[] = { + {"zeroize", "([B)V", (void*)ZeroizeByteArray}, + {"zeroize", "([C)V", (void*)ZeroizeCharArray}, +}; + +int register_com_android_internal_util_ArrayUtils(JNIEnv* env) { + return jniRegisterNativeMethods(env, "com/android/internal/util/ArrayUtils", sMethods, + NELEM(sMethods)); +} + +} // namespace android 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><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/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java index fc233fba082e..b28c9f7cc74f 100644 --- a/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java @@ -496,4 +496,58 @@ public class ArrayUtilsTest { // expected } } + + // Note: the zeroize() tests only test the behavior that can be tested from a Java test. + // They do not verify that no copy of the data is left anywhere. + + @Test + @SmallTest + public void testZeroizeNonMovableByteArray() { + final int length = 10; + byte[] array = ArrayUtils.newNonMovableByteArray(length); + assertArrayEquals(array, new byte[length]); + Arrays.fill(array, (byte) 0xff); + ArrayUtils.zeroize(array); + assertArrayEquals(array, new byte[length]); + } + + @Test + @SmallTest + public void testZeroizeRegularByteArray() { + final int length = 10; + byte[] array = new byte[length]; + assertArrayEquals(array, new byte[length]); + Arrays.fill(array, (byte) 0xff); + ArrayUtils.zeroize(array); + assertArrayEquals(array, new byte[length]); + } + + @Test + @SmallTest + public void testZeroizeNonMovableCharArray() { + final int length = 10; + char[] array = ArrayUtils.newNonMovableCharArray(length); + assertArrayEquals(array, new char[length]); + Arrays.fill(array, (char) 0xff); + ArrayUtils.zeroize(array); + assertArrayEquals(array, new char[length]); + } + + @Test + @SmallTest + public void testZeroizeRegularCharArray() { + final int length = 10; + char[] array = new char[length]; + assertArrayEquals(array, new char[length]); + Arrays.fill(array, (char) 0xff); + ArrayUtils.zeroize(array); + assertArrayEquals(array, new char[length]); + } + + @Test + @SmallTest + public void testZeroize_acceptsNull() { + ArrayUtils.zeroize((byte[]) null); + ArrayUtils.zeroize((char[]) null); + } } 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/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/packages/Vcn/TEST_MAPPING b/packages/Vcn/TEST_MAPPING index bde88fe9b717..9722a838ab8e 100644 --- a/packages/Vcn/TEST_MAPPING +++ b/packages/Vcn/TEST_MAPPING @@ -1,4 +1,12 @@ { + "presubmit": [ + { + "name": "FrameworksVcnTests" + }, + { + "name": "CtsVcnTestCases" + } + ], "postsubmit": [ { "name": "FrameworksVcnTests" diff --git a/packages/Vcn/flags/Android.bp b/packages/Vcn/flags/Android.bp new file mode 100644 index 000000000000..3943c6f7fe24 --- /dev/null +++ b/packages/Vcn/flags/Android.bp @@ -0,0 +1,38 @@ +// +// 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 { + default_team: "trendy_team_enigma", + default_applicable_licenses: ["Android-Apache-2.0"], +} + +aconfig_declarations { + name: "android.net.vcn.flags-aconfig", + package: "android.net.vcn", + container: "com.android.tethering", + exportable: true, + srcs: [ + "flags.aconfig", + ], +} + +java_aconfig_library { + name: "android.net.vcn.flags-aconfig-java-export", + aconfig_declarations: "android.net.vcn.flags-aconfig", + mode: "exported", + min_sdk_version: "35", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} diff --git a/core/java/android/net/vcn/flags.aconfig b/packages/Vcn/flags/flags.aconfig index b461f95fec53..b461f95fec53 100644 --- a/core/java/android/net/vcn/flags.aconfig +++ b/packages/Vcn/flags/flags.aconfig diff --git a/packages/Vcn/framework-b/Android.bp b/packages/Vcn/framework-b/Android.bp index 8b010c7f2ee7..c3121162b7f2 100644 --- a/packages/Vcn/framework-b/Android.bp +++ b/packages/Vcn/framework-b/Android.bp @@ -19,6 +19,18 @@ package { default_applicable_licenses: ["Android-Apache-2.0"], } +filegroup { + name: "vcn-utils-platform-sources", + srcs: [ + "src/android/net/vcn/persistablebundleutils/**/*.java", + "src/android/net/vcn/util/**/*.java", + ], + path: "src", + visibility: [ + "//frameworks/base", // For VpnProfile.java and Vpn.java + ], +} + java_defaults { name: "framework-connectivity-b-defaults", sdk_version: "module_current", @@ -27,7 +39,25 @@ java_defaults { srcs: [ "src/**/*.java", + "src/**/*.aidl", + ], + + libs: [ + "android.net.ipsec.ike.stubs.module_lib", + "app-compat-annotations", + "framework-wifi.stubs.module_lib", + "unsupportedappusage", + ], + static_libs: [ + //TODO:375213246 Use a non-exported flag lib when VCN is in mainline + "android.net.vcn.flags-aconfig-java-export", ], + aidl: { + include_dirs: [ + // For connectivity-framework classes such as Network.aidl, NetworkCapabilities.aidl + "packages/modules/Connectivity/framework/aidl-export", + ], + }, } java_sdk_library { @@ -36,10 +66,37 @@ java_sdk_library { "framework-connectivity-b-defaults", ], + //TODO: b/375213246 Use "framework-connectivity-jarjar-rules" when VCN is + // in mainline + jarjar_rules: "framework-vcn-jarjar-rules.txt", + permitted_packages: [ + "android.net", + "android.net.vcn", + "com.android.server.vcn.util", + + ], + api_packages: [ + "android.net", "android.net.vcn", ], + // Allow VCN APIs to reference APIs in IKE and Connectivity + stub_only_libs: [ + "android.net.ipsec.ike.stubs.module_lib", + "framework-connectivity.stubs.module_lib", + ], + + // To use non-jarjard names of utilities such as android.util.IndentingPrintWriter + impl_only_libs: [ + "framework-connectivity-pre-jarjar", + ], + + aconfig_declarations: [ + //TODO:375213246 Use a non-exported flag lib when VCN is in mainline + "android.net.vcn.flags-aconfig-java-export", + ], + impl_library_visibility: [ // Using for test only "//cts/tests/netlegacy22.api", @@ -63,5 +120,18 @@ java_sdk_library { "//packages/modules/Wifi/service/tests/wifitests", ], - // TODO: b/375213246 Expose this library to Tethering module + apex_available: [ + // TODO: b/374174952 Remove it when VCN modularization is released + "//apex_available:platform", + + "com.android.tethering", + ], +} + +java_library { + name: "framework-connectivity-b-pre-jarjar", + defaults: ["framework-connectivity-b-defaults"], + libs: [ + "framework-connectivity-pre-jarjar", + ], } diff --git a/packages/Vcn/framework-b/api/current.txt b/packages/Vcn/framework-b/api/current.txt index d802177e249b..831b74158e67 100644 --- a/packages/Vcn/framework-b/api/current.txt +++ b/packages/Vcn/framework-b/api/current.txt @@ -1 +1,123 @@ // Signature format: 2.0 +package android.net.vcn { + + public final class VcnCellUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate { + method public int getCbs(); + method public int getDun(); + method public int getIms(); + method public int getInternet(); + method public int getMms(); + method @NonNull public java.util.Set<java.lang.String> getOperatorPlmnIds(); + method public int getOpportunistic(); + method public int getRcs(); + method public int getRoaming(); + method @NonNull public java.util.Set<java.lang.Integer> getSimSpecificCarrierIds(); + } + + public static final class VcnCellUnderlyingNetworkTemplate.Builder { + ctor public VcnCellUnderlyingNetworkTemplate.Builder(); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate build(); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setCbs(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setDun(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setIms(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setInternet(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMetered(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMms(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOperatorPlmnIds(@NonNull java.util.Set<java.lang.String>); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOpportunistic(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRcs(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRoaming(int); + method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setSimSpecificCarrierIds(@NonNull java.util.Set<java.lang.Integer>); + } + + public final class VcnConfig implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public java.util.Set<android.net.vcn.VcnGatewayConnectionConfig> getGatewayConnectionConfigs(); + method @NonNull public java.util.Set<java.lang.Integer> getRestrictedUnderlyingNetworkTransports(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnConfig> CREATOR; + } + + public static final class VcnConfig.Builder { + ctor public VcnConfig.Builder(@NonNull android.content.Context); + method @NonNull public android.net.vcn.VcnConfig.Builder addGatewayConnectionConfig(@NonNull android.net.vcn.VcnGatewayConnectionConfig); + method @NonNull public android.net.vcn.VcnConfig build(); + method @NonNull public android.net.vcn.VcnConfig.Builder setRestrictedUnderlyingNetworkTransports(@NonNull java.util.Set<java.lang.Integer>); + } + + public final class VcnGatewayConnectionConfig { + method @NonNull public int[] getExposedCapabilities(); + method @NonNull public String getGatewayConnectionName(); + method @IntRange(from=0x500) public int getMaxMtu(); + method public int getMinUdpPort4500NatTimeoutSeconds(); + method @NonNull public long[] getRetryIntervalsMillis(); + method @NonNull public java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkPriorities(); + method public boolean hasGatewayOption(int); + method @FlaggedApi("android.net.vcn.safe_mode_config") public boolean isSafeModeEnabled(); + field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1; // 0xffffffff + field public static final int VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY = 0; // 0x0 + } + + public static final class VcnGatewayConnectionConfig.Builder { + ctor public VcnGatewayConnectionConfig.Builder(@NonNull String, @NonNull android.net.ipsec.ike.IkeTunnelConnectionParams); + method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int); + method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addGatewayOption(int); + method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build(); + method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int); + method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeGatewayOption(int); + method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int); + method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int); + method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]); + method @FlaggedApi("android.net.vcn.safe_mode_config") @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setSafeModeEnabled(boolean); + method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate>); + } + + public class VcnManager { + method @RequiresPermission("carrier privileges") public void clearVcnConfig(@NonNull android.os.ParcelUuid) throws java.io.IOException; + method @NonNull public java.util.List<android.os.ParcelUuid> getConfiguredSubscriptionGroups(); + method public void registerVcnStatusCallback(@NonNull android.os.ParcelUuid, @NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnStatusCallback); + method @RequiresPermission("carrier privileges") public void setVcnConfig(@NonNull android.os.ParcelUuid, @NonNull android.net.vcn.VcnConfig) throws java.io.IOException; + method public void unregisterVcnStatusCallback(@NonNull android.net.vcn.VcnManager.VcnStatusCallback); + field public static final int VCN_ERROR_CODE_CONFIG_ERROR = 1; // 0x1 + field public static final int VCN_ERROR_CODE_INTERNAL_ERROR = 0; // 0x0 + field public static final int VCN_ERROR_CODE_NETWORK_ERROR = 2; // 0x2 + field public static final int VCN_STATUS_CODE_ACTIVE = 2; // 0x2 + field public static final int VCN_STATUS_CODE_INACTIVE = 1; // 0x1 + field public static final int VCN_STATUS_CODE_NOT_CONFIGURED = 0; // 0x0 + field public static final int VCN_STATUS_CODE_SAFE_MODE = 3; // 0x3 + } + + public abstract static class VcnManager.VcnStatusCallback { + ctor public VcnManager.VcnStatusCallback(); + method public abstract void onGatewayConnectionError(@NonNull String, int, @Nullable Throwable); + method public abstract void onStatusChanged(int); + } + + public abstract class VcnUnderlyingNetworkTemplate { + method public int getMetered(); + method public int getMinEntryDownstreamBandwidthKbps(); + method public int getMinEntryUpstreamBandwidthKbps(); + method public int getMinExitDownstreamBandwidthKbps(); + method public int getMinExitUpstreamBandwidthKbps(); + field public static final int MATCH_ANY = 0; // 0x0 + field public static final int MATCH_FORBIDDEN = 2; // 0x2 + field public static final int MATCH_REQUIRED = 1; // 0x1 + } + + public final class VcnWifiUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate { + method @NonNull public java.util.Set<java.lang.String> getSsids(); + } + + public static final class VcnWifiUnderlyingNetworkTemplate.Builder { + ctor public VcnWifiUnderlyingNetworkTemplate.Builder(); + method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate build(); + method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMetered(int); + method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int); + method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int); + method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setSsids(@NonNull java.util.Set<java.lang.String>); + } + +} + diff --git a/packages/Vcn/framework-b/api/module-lib-current.txt b/packages/Vcn/framework-b/api/module-lib-current.txt index d802177e249b..8961b2830f86 100644 --- a/packages/Vcn/framework-b/api/module-lib-current.txt +++ b/packages/Vcn/framework-b/api/module-lib-current.txt @@ -1 +1,28 @@ // Signature format: 2.0 +package android.net { + + @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class ConnectivityFrameworkInitializerBaklava { + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static void registerServiceWrappers(); + } + +} + +package android.net.vcn { + + @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class VcnTransportInfo implements android.os.Parcelable android.net.TransportInfo { + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int describeContents(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public long getApplicableRedactions(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int getMinUdpPort4500NatTimeoutSeconds(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.TransportInfo makeCopy(long); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public void writeToParcel(@NonNull android.os.Parcel, int); + field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnTransportInfo> CREATOR; + } + + @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final class VcnTransportInfo.Builder { + ctor @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public VcnTransportInfo.Builder(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo build(); + method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int); + } + +} + diff --git a/packages/Vcn/framework-b/api/system-current.txt b/packages/Vcn/framework-b/api/system-current.txt index d802177e249b..9c5a67701b74 100644 --- a/packages/Vcn/framework-b/api/system-current.txt +++ b/packages/Vcn/framework-b/api/system-current.txt @@ -1 +1,23 @@ // Signature format: 2.0 +package android.net.vcn { + + public class VcnManager { + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener); + method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties); + method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void removeVcnNetworkPolicyChangeListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener); + } + + public static interface VcnManager.VcnNetworkPolicyChangeListener { + method public void onPolicyChanged(); + } + + public final class VcnNetworkPolicyResult implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities(); + method public boolean isTeardownRequested(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnNetworkPolicyResult> CREATOR; + } + +} + diff --git a/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt new file mode 100644 index 000000000000..757043bdbbc0 --- /dev/null +++ b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt @@ -0,0 +1,2 @@ +rule android.net.vcn.persistablebundleutils.** android.net.vcn.module.repackaged.persistablebundleutils.@1 +rule android.net.vcn.util.** android.net.vcn.module.repackaged.util.@1
\ No newline at end of file diff --git a/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java b/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java index 1f0fa92d7976..1f0fa92d7976 100644 --- a/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java +++ b/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java diff --git a/core/java/android/net/vcn/IVcnManagementService.aidl b/packages/Vcn/framework-b/src/android/net/vcn/IVcnManagementService.aidl index e16f6b167750..e16f6b167750 100644 --- a/core/java/android/net/vcn/IVcnManagementService.aidl +++ b/packages/Vcn/framework-b/src/android/net/vcn/IVcnManagementService.aidl diff --git a/core/java/android/net/vcn/IVcnStatusCallback.aidl b/packages/Vcn/framework-b/src/android/net/vcn/IVcnStatusCallback.aidl index 11bc443c9dd6..11bc443c9dd6 100644 --- a/core/java/android/net/vcn/IVcnStatusCallback.aidl +++ b/packages/Vcn/framework-b/src/android/net/vcn/IVcnStatusCallback.aidl diff --git a/core/java/android/net/vcn/IVcnUnderlyingNetworkPolicyListener.aidl b/packages/Vcn/framework-b/src/android/net/vcn/IVcnUnderlyingNetworkPolicyListener.aidl index 62de8216ce54..62de8216ce54 100644 --- a/core/java/android/net/vcn/IVcnUnderlyingNetworkPolicyListener.aidl +++ b/packages/Vcn/framework-b/src/android/net/vcn/IVcnUnderlyingNetworkPolicyListener.aidl diff --git a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java index ded94159a945..ded94159a945 100644 --- a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java diff --git a/core/java/android/net/vcn/VcnConfig.aidl b/packages/Vcn/framework-b/src/android/net/vcn/VcnConfig.aidl index 67006a42a701..67006a42a701 100644 --- a/core/java/android/net/vcn/VcnConfig.aidl +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnConfig.aidl diff --git a/core/java/android/net/vcn/VcnConfig.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnConfig.java index 0d0efb2f73f9..0d0efb2f73f9 100644 --- a/core/java/android/net/vcn/VcnConfig.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnConfig.java diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnGatewayConnectionConfig.java index 067144e6f474..067144e6f474 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnGatewayConnectionConfig.java diff --git a/core/java/android/net/vcn/VcnManager.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnManager.java index f275714e2cf5..594bbb8a2015 100644 --- a/core/java/android/net/vcn/VcnManager.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnManager.java @@ -334,7 +334,7 @@ public class VcnManager { * @param executor the Executor that will be used for invoking all calls to the specified * Listener * @param listener the VcnUnderlyingNetworkPolicyListener to be added - * @throws SecurityException if the caller does not have permission NETWORK_FACTORY + * @throws SecurityException if the caller does not have the required permission * @throws IllegalStateException if the specified VcnUnderlyingNetworkPolicyListener is already * registered * @hide @@ -423,7 +423,7 @@ public class VcnManager { * @param executor the Executor that will be used for invoking all calls to the specified * Listener * @param listener the VcnNetworkPolicyChangeListener to be added - * @throws SecurityException if the caller does not have permission NETWORK_FACTORY + * @throws SecurityException if the caller does not have the required permission * @throws IllegalStateException if the specified VcnNetworkPolicyChangeListener is already * registered * @hide @@ -455,7 +455,7 @@ public class VcnManager { * <p>If the specified listener is not currently registered, this is a no-op. * * @param listener the VcnNetworkPolicyChangeListener that will be removed - * @throws SecurityException if the caller does not have permission NETWORK_FACTORY + * @throws SecurityException if the caller does not have the required permission * @hide */ @SystemApi @@ -489,7 +489,7 @@ public class VcnManager { * policy result for this Network. * @param linkProperties the LinkProperties to be used in determining the Network policy result * for this Network. - * @throws SecurityException if the caller does not have permission NETWORK_FACTORY + * @throws SecurityException if the caller does not have the required permission * @return the {@link VcnNetworkPolicyResult} to be used for this Network. * @hide */ diff --git a/core/java/android/net/vcn/VcnNetworkPolicyResult.aidl b/packages/Vcn/framework-b/src/android/net/vcn/VcnNetworkPolicyResult.aidl index 3f13abe869da..3f13abe869da 100644 --- a/core/java/android/net/vcn/VcnNetworkPolicyResult.aidl +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnNetworkPolicyResult.aidl diff --git a/core/java/android/net/vcn/VcnNetworkPolicyResult.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnNetworkPolicyResult.java index fca084a00a79..fca084a00a79 100644 --- a/core/java/android/net/vcn/VcnNetworkPolicyResult.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnNetworkPolicyResult.java diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnTransportInfo.java index 3638429f33fb..3638429f33fb 100644 --- a/core/java/android/net/vcn/VcnTransportInfo.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnTransportInfo.java diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.aidl b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkPolicy.aidl index 6cb6ee685a64..6cb6ee685a64 100644 --- a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.aidl +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkPolicy.aidl diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkPolicy.java index 2b5305d05dcd..2b5305d05dcd 100644 --- a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkPolicy.java diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkSpecifier.java index e1d1b3c65c99..e1d1b3c65c99 100644 --- a/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkSpecifier.java diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkTemplate.java index 16114dd135af..16114dd135af 100644 --- a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkTemplate.java diff --git a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java index 770a8c118a4d..770a8c118a4d 100644 --- a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java diff --git a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/CertUtils.java index 35b318687773..35b318687773 100644 --- a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/CertUtils.java diff --git a/core/java/android/net/vcn/persistablebundleutils/ChildSaProposalUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/ChildSaProposalUtils.java index 48c1b25a97ab..48c1b25a97ab 100644 --- a/core/java/android/net/vcn/persistablebundleutils/ChildSaProposalUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/ChildSaProposalUtils.java diff --git a/core/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/EapSessionConfigUtils.java index dc1ee36b71c1..dc1ee36b71c1 100644 --- a/core/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/EapSessionConfigUtils.java diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeIdentificationUtils.java index 6e8616fc9cb0..6e8616fc9cb0 100644 --- a/core/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeIdentificationUtils.java diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSaProposalUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeSaProposalUtils.java index b590148de51f..b590148de51f 100644 --- a/core/java/android/net/vcn/persistablebundleutils/IkeSaProposalUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeSaProposalUtils.java diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java index aefac2e89aea..aefac2e89aea 100644 --- a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java index 6bbc6b1e8218..6bbc6b1e8218 100644 --- a/core/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java diff --git a/core/java/android/net/vcn/persistablebundleutils/SaProposalUtilsBase.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/SaProposalUtilsBase.java index 469966a48465..469966a48465 100644 --- a/core/java/android/net/vcn/persistablebundleutils/SaProposalUtilsBase.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/SaProposalUtilsBase.java diff --git a/core/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java index 0427742f9c0a..0427742f9c0a 100644 --- a/core/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java diff --git a/core/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtils.java index 3f4ba345a118..3f4ba345a118 100644 --- a/core/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtils.java diff --git a/core/java/android/net/vcn/util/LogUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/util/LogUtils.java index 7f7f85271603..742aa761e602 100644 --- a/core/java/android/net/vcn/util/LogUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/util/LogUtils.java @@ -19,7 +19,7 @@ package android.net.vcn.util; import android.annotation.Nullable; import android.os.ParcelUuid; -import com.android.internal.util.HexDump; +import com.android.net.module.util.HexDump; /** @hide */ public class LogUtils { diff --git a/core/java/android/net/vcn/util/MtuUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/util/MtuUtils.java index c3123bcecf33..c3123bcecf33 100644 --- a/core/java/android/net/vcn/util/MtuUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/util/MtuUtils.java diff --git a/core/java/android/net/vcn/util/OneWayBoolean.java b/packages/Vcn/framework-b/src/android/net/vcn/util/OneWayBoolean.java index a7ef67b187b9..a7ef67b187b9 100644 --- a/core/java/android/net/vcn/util/OneWayBoolean.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/util/OneWayBoolean.java diff --git a/core/java/android/net/vcn/util/PersistableBundleUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/util/PersistableBundleUtils.java index 4dc42c7827f8..8a687d8c5942 100644 --- a/core/java/android/net/vcn/util/PersistableBundleUtils.java +++ b/packages/Vcn/framework-b/src/android/net/vcn/util/PersistableBundleUtils.java @@ -21,7 +21,7 @@ import android.annotation.Nullable; import android.os.ParcelUuid; import android.os.PersistableBundle; -import com.android.internal.util.HexDump; +import com.android.net.module.util.HexDump; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/packages/Vcn/service-b/Android.bp b/packages/Vcn/service-b/Android.bp index 03ef4e67af1c..c1a1ee7875d0 100644 --- a/packages/Vcn/service-b/Android.bp +++ b/packages/Vcn/service-b/Android.bp @@ -32,6 +32,33 @@ filegroup { visibility: ["//frameworks/base/services/core"], } +// Do not static include this lib in VCN because these files exist in +// both service-connectivity.jar and framework.jar +// TODO: b/374174952 After VCN moves to Connectivity/ and the modularization is done +// this lib can be removed and "service-connectivity-b-pre-jarjar" can include +// "service-connectivity-pre-jarjar" +java_library { + name: "connectivity-utils-service-vcn-internal", + sdk_version: "module_current", + min_sdk_version: "30", + srcs: [ + ":framework-connectivity-shared-srcs", + ], + libs: [ + "framework-annotations-lib", + "unsupportedappusage", + ], + visibility: [ + "//visibility:private", + ], + apex_available: [ + // TODO: b/374174952 Remove it when VCN modularization is released + "//apex_available:platform", + + "com.android.tethering", + ], +} + java_library { name: "service-connectivity-b-pre-jarjar", sdk_version: "system_server_current", @@ -42,8 +69,33 @@ java_library { "src/**/*.java", ], - // TODO: b/375213246 Expose this library to Tethering module + libs: [ + "android.net.ipsec.ike.stubs.module_lib", + "connectivity-utils-service-vcn-internal", + "framework-annotations-lib", + "framework-connectivity-pre-jarjar", + "framework-connectivity-t-pre-jarjar", + "framework-connectivity-b-pre-jarjar", + "framework-wifi.stubs.module_lib", + "keepanno-annotations", + "modules-utils-statemachine", + "unsupportedappusage", + ], + + // TODO: b/374174952 Dynamically include these libs when VCN + // modularization is released + static_libs: [ + "net-utils-service-vcn", + "modules-utils-handlerexecutor", + ], + visibility: [ "//frameworks/base/services", ], + apex_available: [ + // TODO: b/374174952 Remove it when VCN modularization is released + "//apex_available:platform", + + "com.android.tethering", + ], } diff --git a/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java new file mode 100644 index 000000000000..02c8ce4f29e9 --- /dev/null +++ b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java @@ -0,0 +1,60 @@ +/* + * 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; + +import android.content.Context; +import android.util.Log; + +import com.android.tools.r8.keepanno.annotations.KeepItemKind; +import com.android.tools.r8.keepanno.annotations.UsedByReflection; + +/** + * Service initializer for VCN. This is called by system server to create a new instance of + * VcnManagementService. + */ +// This class is reflectively invoked from SystemServer and ConnectivityServiceInitializer. +// Without this annotation, this class will be treated as unused class and be removed during build +// time. +@UsedByReflection(kind = KeepItemKind.CLASS_AND_METHODS) +public final class ConnectivityServiceInitializerB extends SystemService { + private static final String TAG = ConnectivityServiceInitializerB.class.getSimpleName(); + private final VcnManagementService mVcnManagementService; + + public ConnectivityServiceInitializerB(Context context) { + super(context); + mVcnManagementService = VcnManagementService.create(context); + } + + @Override + public void onStart() { + if (mVcnManagementService != null) { + Log.i(TAG, "Registering " + Context.VCN_MANAGEMENT_SERVICE); + publishBinderService( + Context.VCN_MANAGEMENT_SERVICE, + mVcnManagementService, + /* allowIsolated= */ false); + } + } + + @Override + public void onBootPhase(int phase) { + if (mVcnManagementService != null && phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { + Log.i(TAG, "Starting " + Context.VCN_MANAGEMENT_SERVICE); + mVcnManagementService.systemReady(); + } + } +} diff --git a/services/core/java/com/android/server/VcnManagementService.java b/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java index a45b715ccac6..26db6a988e31 100644 --- a/services/core/java/com/android/server/VcnManagementService.java +++ b/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java @@ -86,6 +86,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; import com.android.net.module.util.BinderUtils; +import com.android.net.module.util.HandlerUtils; import com.android.net.module.util.LocationPermissionChecker; import com.android.net.module.util.PermissionUtils; import com.android.server.vcn.TelephonySubscriptionTracker; @@ -1332,41 +1333,46 @@ public class VcnManagementService extends IVcnManagementService.Stub { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "| "); // Post to handler thread to prevent ConcurrentModificationExceptions, and avoid lock-hell. - mHandler.runWithScissors(() -> { - mNetworkProvider.dump(pw); - pw.println(); + HandlerUtils.runWithScissorsForDump( + mHandler, + () -> { + mNetworkProvider.dump(pw); + pw.println(); - mTrackingNetworkCallback.dump(pw); - pw.println(); + mTrackingNetworkCallback.dump(pw); + pw.println(); - synchronized (mLock) { - mLastSnapshot.dump(pw); - pw.println(); + synchronized (mLock) { + mLastSnapshot.dump(pw); + pw.println(); - pw.println("mConfigs:"); - pw.increaseIndent(); - for (Entry<ParcelUuid, VcnConfig> entry : mConfigs.entrySet()) { - pw.println(entry.getKey() + ": " - + entry.getValue().getProvisioningPackageName()); - } - pw.decreaseIndent(); - pw.println(); + pw.println("mConfigs:"); + pw.increaseIndent(); + for (Entry<ParcelUuid, VcnConfig> entry : mConfigs.entrySet()) { + pw.println( + entry.getKey() + + ": " + + entry.getValue().getProvisioningPackageName()); + } + pw.decreaseIndent(); + pw.println(); - pw.println("mVcns:"); - pw.increaseIndent(); - for (Vcn vcn : mVcns.values()) { - vcn.dump(pw); - } - pw.decreaseIndent(); - pw.println(); - } + pw.println("mVcns:"); + pw.increaseIndent(); + for (Vcn vcn : mVcns.values()) { + vcn.dump(pw); + } + pw.decreaseIndent(); + pw.println(); + } - pw.println("Local log:"); - pw.increaseIndent(); - LOCAL_LOG.dump(pw); - pw.decreaseIndent(); - pw.println(); - }, DUMP_TIMEOUT_MILLIS); + pw.println("Local log:"); + pw.increaseIndent(); + LOCAL_LOG.dump(pw); + pw.decreaseIndent(); + pw.println(); + }, + DUMP_TIMEOUT_MILLIS); } // TODO(b/180452282): Make name more generic and implement directly with VcnManagementService diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java index 154897eecee4..b448f7595b3b 100644 --- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java @@ -29,7 +29,6 @@ import android.content.IntentFilter; import android.net.vcn.VcnManager; import android.net.vcn.util.PersistableBundleUtils.PersistableBundleWrapper; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; @@ -46,6 +45,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.modules.utils.HandlerExecutor; import java.util.ArrayList; import java.util.Collections; diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java index 95acb107fd05..2524d0eedac3 100644 --- a/services/core/java/com/android/server/vcn/Vcn.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java @@ -40,7 +40,6 @@ import android.net.vcn.VcnGatewayConnectionConfig; import android.net.vcn.VcnManager.VcnErrorCode; import android.net.vcn.util.LogUtils; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.Message; import android.os.ParcelUuid; import android.provider.Settings; @@ -53,6 +52,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.modules.utils.HandlerExecutor; import com.android.server.VcnManagementService.VcnCallback; import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot; diff --git a/services/core/java/com/android/server/vcn/VcnContext.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnContext.java index 9213d96ad4ca..9213d96ad4ca 100644 --- a/services/core/java/com/android/server/vcn/VcnContext.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnContext.java diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java index 77bda9dc6b14..e50fc3a6e8b9 100644 --- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java @@ -45,6 +45,7 @@ import android.net.InetAddresses; import android.net.IpPrefix; import android.net.IpSecManager; import android.net.IpSecManager.IpSecTunnelInterface; +import android.net.IpSecManager.PolicyDirection; import android.net.IpSecManager.ResourceUnavailableException; import android.net.IpSecTransform; import android.net.LinkAddress; @@ -59,7 +60,6 @@ import android.net.NetworkScore; import android.net.RouteInfo; import android.net.TelephonyNetworkSpecifier; import android.net.Uri; -import android.net.annotations.PolicyDirection; import android.net.ipsec.ike.ChildSaProposal; import android.net.ipsec.ike.ChildSessionCallback; import android.net.ipsec.ike.ChildSessionConfiguration; @@ -83,7 +83,6 @@ import android.net.vcn.util.MtuUtils; import android.net.vcn.util.OneWayBoolean; import android.net.wifi.WifiInfo; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.Message; import android.os.ParcelUuid; import android.os.PowerManager; @@ -101,6 +100,7 @@ import com.android.internal.annotations.VisibleForTesting.Visibility; import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.internal.util.WakeupMessage; +import com.android.modules.utils.HandlerExecutor; import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot; import com.android.server.vcn.Vcn.VcnGatewayStatusCallback; import com.android.server.vcn.routeselection.UnderlyingNetworkController; diff --git a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java index 78ff432f5423..4552f509b59a 100644 --- a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java @@ -33,7 +33,6 @@ import android.net.NetworkRequest; import android.net.NetworkScore; import android.net.vcn.VcnGatewayConnectionConfig; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.Looper; import android.util.ArraySet; import android.util.IndentingPrintWriter; @@ -41,6 +40,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.modules.utils.HandlerExecutor; import java.util.Objects; import java.util.Set; diff --git a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java index e6a1ff967508..72de61363d26 100644 --- a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java @@ -32,12 +32,12 @@ import android.net.IpSecTransformState; import android.net.Network; import android.net.vcn.VcnManager; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.OutcomeReceiver; import android.os.PowerManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.modules.utils.HandlerExecutor; import com.android.server.vcn.VcnContext; import java.lang.annotation.ElementType; diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkMetricMonitor.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java index 86cee554be6f..86cee554be6f 100644 --- a/services/core/java/com/android/server/vcn/routeselection/NetworkMetricMonitor.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java index 79c4116d0cd4..79c4116d0cd4 100644 --- a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java index f7a564ad5281..29a0762f5fe8 100644 --- a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java @@ -41,7 +41,6 @@ import android.net.vcn.VcnGatewayConnectionConfig; import android.net.vcn.VcnUnderlyingNetworkTemplate; import android.net.vcn.util.LogUtils; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.ParcelUuid; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; @@ -52,6 +51,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; +import com.android.modules.utils.HandlerExecutor; import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot; import com.android.server.vcn.VcnContext; import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback; diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java index 30f4ed1b9f0b..30f4ed1b9f0b 100644 --- a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java index 1945052b92df..1945052b92df 100644 --- a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java 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/vcn/TEST_MAPPING b/services/core/java/com/android/server/vcn/TEST_MAPPING deleted file mode 100644 index 5b04d884fc1a..000000000000 --- a/services/core/java/com/android/server/vcn/TEST_MAPPING +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presubmit": [ - { - "name": "FrameworksVcnTests" - }, - { - "name": "CtsVcnTestCases" - } - ] -}
\ No newline at end of file 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/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 688312e7e004..32f88f78426c 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -411,6 +411,8 @@ public final class SystemServer implements Dumpable { "/apex/com.android.tethering/javalib/service-connectivity.jar"; private static final String CONNECTIVITY_SERVICE_INITIALIZER_CLASS = "com.android.server.ConnectivityServiceInitializer"; + private static final String CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS = + "com.android.server.ConnectivityServiceInitializerB"; private static final String NETWORK_STATS_SERVICE_INITIALIZER_CLASS = "com.android.server.NetworkStatsServiceInitializer"; private static final String UWB_APEX_SERVICE_JAR_PATH = @@ -1447,7 +1449,6 @@ public final class SystemServer implements Dumpable { IStorageManager storageManager = null; NetworkManagementService networkManagement = null; VpnManagerService vpnManager = null; - VcnManagementService vcnManagement = null; NetworkPolicyManagerService networkPolicy = null; WindowManagerService wm = null; NetworkTimeUpdateService networkTimeUpdater = null; @@ -1846,6 +1847,10 @@ public final class SystemServer implements Dumpable { } t.traceEnd(); + t.traceBegin("UpdateMetricsIfNeeded"); + mPackageManagerService.updateMetricsIfNeeded(); + t.traceEnd(); + t.traceBegin("PerformFstrimIfNeeded"); try { mPackageManagerService.performFstrimIfNeeded(); @@ -2145,8 +2150,10 @@ public final class SystemServer implements Dumpable { t.traceBegin("StartVcnManagementService"); try { - vcnManagement = VcnManagementService.create(context); - ServiceManager.addService(Context.VCN_MANAGEMENT_SERVICE, vcnManagement); + // TODO: b/375213246 When VCN is in mainline module, load it from the apex path. + // Whether VCN will be in apex or in the platform will be gated by a build system + // flag. + mSystemServiceManager.startService(CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS); } catch (Throwable e) { reportWtf("starting VCN Management Service", e); } @@ -3038,7 +3045,6 @@ public final class SystemServer implements Dumpable { final MediaRouterService mediaRouterF = mediaRouter; final MmsServiceBroker mmsServiceF = mmsService; final VpnManagerService vpnManagerF = vpnManager; - final VcnManagementService vcnManagementF = vcnManagement; final WindowManagerService windowManagerF = wm; final ConnectivityManager connectivityF = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); @@ -3165,15 +3171,6 @@ public final class SystemServer implements Dumpable { reportWtf("making VpnManagerService ready", e); } t.traceEnd(); - t.traceBegin("MakeVcnManagementServiceReady"); - try { - if (vcnManagementF != null) { - vcnManagementF.systemReady(); - } - } catch (Throwable e) { - reportWtf("making VcnManagementService ready", e); - } - t.traceEnd(); t.traceBegin("MakeNetworkPolicyServiceReady"); try { if (networkPolicyF != null) { 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/tests/vcn/Android.bp b/tests/vcn/Android.bp index b16ba15a6867..51a300bff7ea 100644 --- a/tests/vcn/Android.bp +++ b/tests/vcn/Android.bp @@ -14,21 +14,24 @@ package { android_test { name: "FrameworksVcnTests", + // For access hidden connectivity methods in tests + defaults: ["framework-connectivity-test-defaults"], srcs: [ "java/**/*.java", "java/**/*.kt", ], platform_apis: true, - defaults: ["framework-connectivity-test-defaults"], test_suites: ["device-tests"], certificate: "platform", static_libs: [ + "android.net.vcn.flags-aconfig-java-export", "androidx.test.rules", "frameworks-base-testutils", "framework-protos", "mockito-target-minus-junit4", "net-tests-utils", "platform-test-annotations", + "service-connectivity-b-pre-jarjar", "services.core", "service-connectivity-tiramisu-pre-jarjar", "flag-junit", diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java index b999475cba38..77f82f0d8cf4 100644 --- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java +++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java @@ -55,7 +55,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.vcn.VcnManager; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.os.test.TestLooper; @@ -72,6 +71,8 @@ import android.util.ArraySet; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.modules.utils.HandlerExecutor; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; 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); + } } |