diff options
67 files changed, 825 insertions, 415 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 8ced596a6762..9fc4fff6f297 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -49,7 +49,7 @@ 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", + "android.net.vcn.flags-aconfig-java-export", "android.net.wifi.flags-aconfig-java", "android.nfc.flags-aconfig-java", "android.os.flags-aconfig-java", @@ -90,7 +90,7 @@ aconfig_declarations_group { "com.android.media.flags.performance-aconfig-java", "com.android.media.flags.projection-aconfig-java", "com.android.net.thread.platform.flags-aconfig-java", - "com.android.ranging.flags.ranging-aconfig-java", + "com.android.ranging.flags.ranging-aconfig-java-export", "com.android.server.contextualsearch.flags-java", "com.android.server.flags.services-aconfig-java", "com.android.text.flags-aconfig-java", @@ -1063,16 +1063,21 @@ java_aconfig_library { } // 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: "system", + container: "com.android.tethering", + exportable: true, srcs: ["core/java/android/net/vcn/*.aconfig"], } java_aconfig_library { - name: "android.net.vcn.flags-aconfig-java", + 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"], } @@ -1471,13 +1476,6 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } -// Ranging -java_aconfig_library { - name: "com.android.ranging.flags.ranging-aconfig-java", - aconfig_declarations: "ranging_aconfig_flags", - defaults: ["framework-minus-apex-aconfig-java-defaults"], -} - // System Server aconfig_declarations { name: "android.systemserver.flags-aconfig", diff --git a/Android.bp b/Android.bp index dc48668220bc..94e5e3342ae1 100644 --- a/Android.bp +++ b/Android.bp @@ -396,6 +396,8 @@ java_defaults { "ext", "framework-updatable-stubs-module_libs_api", "unsupportedappusage", + // TODO(b/379770939): remove prod version of flags from other containers in framework + "aconfig_storage_stub", ], sdk_version: "core_platform", static_libs: [ diff --git a/cmds/interrupter/Android.bp b/cmds/interrupter/Android.bp deleted file mode 100644 index d7f744d0834e..000000000000 --- a/cmds/interrupter/Android.bp +++ /dev/null @@ -1,20 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -cc_library_shared { - name: "interrupter", - host_supported: true, - srcs: ["interrupter.c"], - cflags: [ - "-Wall", - "-Werror", - "-Wunused", - "-Wunreachable-code", - ], -} diff --git a/cmds/interrupter/interrupter.c b/cmds/interrupter/interrupter.c deleted file mode 100644 index ae555150c969..000000000000 --- a/cmds/interrupter/interrupter.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012, 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. - */ - - -/** - * The probability of a syscall failing from 0.0 to 1.0 - */ -#define PROBABILITY 0.9 - - - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> - -/* for various intercepted calls */ -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <fcntl.h> - -/* For builds on glibc */ -#define __USE_GNU -#include <dlfcn.h> - -#include "interrupter.h" - -static int probability = PROBABILITY * RAND_MAX; - -static int maybe_interrupt() { - if (rand() < probability) { - return 1; - } - return 0; -} - -DEFINE_INTERCEPT(read, ssize_t, int, void*, size_t); -DEFINE_INTERCEPT(write, ssize_t, int, const void*, size_t); -DEFINE_INTERCEPT(accept, int, int, struct sockaddr*, socklen_t*); -DEFINE_INTERCEPT(creat, int, const char*, mode_t); diff --git a/cmds/interrupter/interrupter.h b/cmds/interrupter/interrupter.h deleted file mode 100644 index 9ad0277eebbe..000000000000 --- a/cmds/interrupter/interrupter.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012, 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 CONCATENATE(arg1, arg2) CONCATENATE1(arg1, arg2) -#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2) -#define CONCATENATE2(arg1, arg2) arg1##arg2 - -#define INTERRUPTER(sym) \ - if (real_##sym == NULL) \ - __init_##sym(); \ - if (maybe_interrupt()) { \ - errno = EINTR; \ - return -1; \ - } - -#define CALL_FUNCTION_1(sym, ret, type1) \ -ret (*real_##sym)(type1) = NULL; \ -ret sym(type1 arg1) { \ - INTERRUPTER(sym) \ - return real_##sym(arg1); \ -} - -#define CALL_FUNCTION_2(sym, ret, type1, type2) \ -ret (*real_##sym)(type1, type2) = NULL; \ -ret sym(type1 arg1, type2 arg2) { \ - INTERRUPTER(sym) \ - return real_##sym(arg1, arg2); \ -} - -#define CALL_FUNCTION_3(sym, ret, type1, type2, type3) \ -ret (*real_##sym)(type1, type2, type3) = NULL; \ -ret sym(type1 arg1, type2 arg2, type3 arg3) { \ - INTERRUPTER(sym) \ - return real_##sym(arg1, arg2, arg3); \ -} - -#define CALL_FUNCTION_4(sym, ret, type1, type2, type3, type4) \ -ret (*real_##sym)(type1, type2, type3, type4) = NULL; \ -ret sym(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - INTERRUPTER(sym) \ - return real_##sym(arg1, arg2, arg3, arg4); \ -} - -#define CALL_FUNCTION_5(sym, ret, type1, type2, type3, type4, type5) \ -ret (*real_##sym)(type1, type2, type3, type4, type5) = NULL; \ -ret sym(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ - INTERRUPTER(sym) \ - return real_##sym(arg1, arg2, arg3, arg4, arg5); \ -} - -#define DEFINE_INTERCEPT_N(N, sym, ret, ...) \ -static void __init_##sym(void); \ -CONCATENATE(CALL_FUNCTION_, N)(sym, ret, __VA_ARGS__) \ -static void __init_##sym(void) { \ - real_##sym = dlsym(RTLD_NEXT, #sym); \ - if (real_##sym == NULL) { \ - fprintf(stderr, "Error hooking " #sym ": %s\n", dlerror()); \ - } \ -} - -#define INTERCEPT_NARG(...) INTERCEPT_NARG_N(__VA_ARGS__, INTERCEPT_RSEQ_N()) -#define INTERCEPT_NARG_N(...) INTERCEPT_ARG_N(__VA_ARGS__) -#define INTERCEPT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N -#define INTERCEPT_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0 - -#define DEFINE_INTERCEPT(sym, ret, ...) DEFINE_INTERCEPT_N(INTERCEPT_NARG(__VA_ARGS__), sym, ret, __VA_ARGS__) diff --git a/core/api/current.txt b/core/api/current.txt index c96d18d66b50..eb769cea651f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -13109,6 +13109,7 @@ package android.content.pm { field public static final String FEATURE_BACKUP = "android.software.backup"; field public static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth"; field public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le"; + field @FlaggedApi("com.android.ranging.flags.ranging_cs_enabled") public static final String FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING = "android.hardware.bluetooth_le.channel_sounding"; field public static final String FEATURE_CAMERA = "android.hardware.camera"; field public static final String FEATURE_CAMERA_ANY = "android.hardware.camera.any"; field public static final String FEATURE_CAMERA_AR = "android.hardware.camera.ar"; @@ -22797,7 +22798,6 @@ package android.media { method public boolean isVendor(); field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_MEMORY_SAFE = 1; // 0x1 field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_SANDBOXED = 0; // 0x0 - field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2; // 0x2 } public static final class MediaCodecInfo.AudioCapabilities { @@ -23688,7 +23688,6 @@ package android.media { field public static final int COLOR_TRANSFER_ST2084 = 6; // 0x6 field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_MEMORY_SAFE = 2; // 0x2 field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_SANDBOXED = 1; // 0x1 - field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 4; // 0x4 field public static final String KEY_AAC_DRC_ALBUM_MODE = "aac-drc-album-mode"; field public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level"; field public static final String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level"; @@ -29520,6 +29519,7 @@ package android.net.vcn { 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 } diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 0b891f6e0a71..529e7f9b0bd3 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -260,6 +260,10 @@ 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); } @@ -319,6 +323,25 @@ 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/java/Android.bp b/core/java/Android.bp index 3f6e65b95c93..22566b75c987 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -639,43 +639,8 @@ java_library { // protolog end -// Whether to enable read-only system feature codegen. -gen_readonly_feature_apis = select(release_flag("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS"), { - true: "true", - false: "false", - default: "false", -}) - -// Generates com.android.internal.pm.RoSystemFeatures, optionally compiling in -// details about fixed system features defined by build flags. When disabled, -// the APIs are simply passthrough stubs with no meaningful side effects. -// TODO(b/203143243): Implement the `--feature=` aggregation directly with a native soong module. -genrule { +java_system_features_srcs { name: "systemfeatures-gen-srcs", - cmd: "$(location systemfeatures-gen-tool) com.android.internal.pm.RoSystemFeatures " + - // --readonly=false (default) makes the codegen an effective no-op passthrough API. - " --readonly=" + gen_readonly_feature_apis + - " --feature=AUTOMOTIVE:" + select(release_flag("RELEASE_SYSTEM_FEATURE_AUTOMOTIVE"), { - any @ value: value, - default: "", - }) + " --feature=EMBEDDED:" + select(release_flag("RELEASE_SYSTEM_FEATURE_EMBEDDED"), { - any @ value: value, - default: "", - }) + " --feature=LEANBACK:" + select(release_flag("RELEASE_SYSTEM_FEATURE_LEANBACK"), { - any @ value: value, - default: "", - }) + " --feature=PC:" + select(release_flag("RELEASE_SYSTEM_FEATURE_PC"), { - any @ value: value, - default: "", - }) + " --feature=TELEVISION:" + select(release_flag("RELEASE_SYSTEM_FEATURE_TELEVISION"), { - any @ value: value, - default: "", - }) + " --feature=WATCH:" + select(release_flag("RELEASE_SYSTEM_FEATURE_WATCH"), { - any @ value: value, - default: "", - }) + " > $(out)", - out: [ - "RoSystemFeatures.java", - ], - tools: ["systemfeatures-gen-tool"], + full_class_name: "com.android.internal.pm.RoSystemFeatures", + visibility: ["//visibility:private"], } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 093dad6ec165..918ae1cb8ab6 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -150,6 +150,7 @@ import android.media.tv.tunerresourcemanager.ITunerResourceManager; import android.media.tv.tunerresourcemanager.TunerResourceManager; import android.nearby.NearbyFrameworkInitializer; import android.net.ConnectivityFrameworkInitializer; +import android.net.ConnectivityFrameworkInitializerBaklava; import android.net.ConnectivityFrameworkInitializerTiramisu; import android.net.INetworkPolicyManager; import android.net.IPacProxyManager; @@ -160,7 +161,6 @@ import android.net.NetworkWatchlistManager; import android.net.PacProxyManager; import android.net.TetheringManager; import android.net.VpnManager; -import android.net.vcn.VcnFrameworkInitializer; import android.net.wifi.WifiFrameworkInitializer; import android.net.wifi.nl80211.WifiNl80211Manager; import android.net.wifi.sharedconnectivity.app.SharedConnectivityManager; @@ -1691,7 +1691,7 @@ public final class SystemServiceRegistry { OnDevicePersonalizationFrameworkInitializer.registerServiceWrappers(); DeviceLockFrameworkInitializer.registerServiceWrappers(); VirtualizationFrameworkInitializer.registerServiceWrappers(); - VcnFrameworkInitializer.registerServiceWrappers(); + ConnectivityFrameworkInitializerBaklava.registerServiceWrappers(); if (com.android.server.telecom.flags.Flags.telecomMainlineBlockedNumbersManager()) { ProviderFrameworkInitializer.registerServiceWrappers(); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 744f019a4988..2a5c533df017 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4484,7 +4484,6 @@ public abstract class Context { * @see #DISPLAY_HASH_SERVICE * @see android.view.displayhash.DisplayHashManager */ - // TODO(b/347269120): Re-add @Nullable public abstract Object getSystemService(@ServiceName @NonNull String name); /** @@ -4529,7 +4528,6 @@ public abstract class Context { * <b>never</b> throw a {@link RuntimeException} if the name is not supported. */ @SuppressWarnings("unchecked") - // TODO(b/347269120): Re-add @Nullable public final <T> T getSystemService(@NonNull Class<T> serviceClass) { // Because subclasses may override getSystemService(String) we cannot // perform a lookup by class alone. We must first map the class to its diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 79fa6ea4d157..77aa62886399 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -953,7 +953,6 @@ public class ContextWrapper extends Context { } @Override - // TODO(b/347269120): Re-add @Nullable public Object getSystemService(String name) { return mBase.getSystemService(name); } diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 4f062090ca40..0113129f5203 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -451,6 +451,13 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * Value of {@link #colorMode} indicating that the activity should use a * high dynamic range if the presentation display supports it. * + * <p>Note: This does not impact SurfaceViews or SurfaceControls, as those have their own + * independent HDR support.</p> + * + * <p><b>Important:</b> Although this value was added in API 26, it is strongly recommended + * to avoid using it until API 34 which is when HDR support for the UI toolkit was officially + * added.</p> + * * @see android.R.attr#colorMode */ public static final int COLOR_MODE_HDR = 2; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 2df187bc3122..0ed9c87e3d51 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -3164,6 +3164,16 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and + * {@link #hasSystemFeature}: The device is capable of ranging with + * other devices using channel sounding via Bluetooth Low Energy radio. + */ + @FlaggedApi(com.android.ranging.flags.Flags.FLAG_RANGING_CS_ENABLED) + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING = + "android.hardware.bluetooth_le.channel_sounding"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device has a camera facing away * from the screen. */ diff --git a/core/java/android/net/vcn/VcnFrameworkInitializer.java b/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java index 8cb213b306be..1f0fa92d7976 100644 --- a/core/java/android/net/vcn/VcnFrameworkInitializer.java +++ b/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java @@ -14,15 +14,21 @@ * limitations under the License. */ -package android.net.vcn; +package android.net; +import static android.net.vcn.Flags.FLAG_MAINLINE_VCN_MODULE_API; + +import android.annotation.FlaggedApi; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.app.SystemServiceRegistry; import android.compat.Compatibility; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.content.Context; import android.content.pm.PackageManager; +import android.net.vcn.IVcnManagementService; +import android.net.vcn.VcnManager; import android.os.Build; import android.os.SystemProperties; @@ -31,8 +37,9 @@ import android.os.SystemProperties; * * @hide */ -// TODO: Expose it as @SystemApi(client = MODULE_LIBRARIES) -public final class VcnFrameworkInitializer { +@FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public final class ConnectivityFrameworkInitializerBaklava { /** * Starting with {@link VANILLA_ICE_CREAM}, Telephony feature flags (e.g. {@link * PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}) are being checked before returning managers @@ -55,7 +62,7 @@ public final class VcnFrameworkInitializer { */ private static final int VENDOR_API_FOR_ANDROID_V = 202404; - private VcnFrameworkInitializer() {} + private ConnectivityFrameworkInitializerBaklava() {} // Suppressing AndroidFrameworkCompatChange because we're querying vendor // partition SDK level, not application's target SDK version (which BTW we @@ -86,7 +93,10 @@ public final class VcnFrameworkInitializer { * * @throws IllegalStateException if this is called anywhere besides {@link * SystemServiceRegistry}. + * @hide */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static void registerServiceWrappers() { SystemServiceRegistry.registerContextAwareService( VcnManager.VCN_MANAGEMENT_SERVICE_STRING, diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index af93c964a8ba..3219ce81c256 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -16,6 +16,7 @@ package android.net.vcn; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; +import static android.net.vcn.Flags.FLAG_MAINLINE_VCN_MODULE_API; import static android.net.vcn.Flags.FLAG_SAFE_MODE_CONFIG; import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED; @@ -82,7 +83,15 @@ import java.util.concurrent.TimeUnit; * </ul> */ public final class VcnGatewayConnectionConfig { - /** @hide */ + /** + * Minimum NAT timeout not set. + * + * <p>When the timeout is not set, the device will automatically choose a keepalive interval and + * may reduce the keepalive frequency for power-optimization. + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + // This constant does not represent a minimum value. It indicates the value is not configured. + @SuppressLint("MinMaxConstant") public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1; /** @hide */ @@ -773,7 +782,7 @@ public final class VcnGatewayConnectionConfig { * * @param minUdpPort4500NatTimeoutSeconds the maximum keepalive timeout supported by the VCN * Gateway Connection, generally the minimum duration a NAT mapping is cached on the VCN - * Gateway. + * Gateway; or {@link MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET} to clear this value. * @return this {@link Builder} instance, for chaining */ @NonNull @@ -781,8 +790,10 @@ public final class VcnGatewayConnectionConfig { @IntRange(from = MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS) int minUdpPort4500NatTimeoutSeconds) { Preconditions.checkArgument( - minUdpPort4500NatTimeoutSeconds >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS, - "Timeout must be at least 120s"); + minUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET + || minUdpPort4500NatTimeoutSeconds + >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS, + "Timeout must be at least 120s or MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET"); mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds; return this; diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java index 1fc91eea3138..3638429f33fb 100644 --- a/core/java/android/net/vcn/VcnTransportInfo.java +++ b/core/java/android/net/vcn/VcnTransportInfo.java @@ -17,13 +17,16 @@ package android.net.vcn; import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; +import static android.net.vcn.Flags.FLAG_MAINLINE_VCN_MODULE_API; import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS; import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; +import android.annotation.FlaggedApi; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.net.NetworkCapabilities; import android.net.TransportInfo; import android.net.wifi.WifiInfo; @@ -52,23 +55,29 @@ import java.util.Objects; * @hide */ // TODO: Do not store WifiInfo and subscription ID in VcnTransportInfo anymore -public class VcnTransportInfo implements TransportInfo, Parcelable { +@FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public final class VcnTransportInfo implements TransportInfo, Parcelable { @Nullable private final WifiInfo mWifiInfo; private final int mSubId; private final int mMinUdpPort4500NatTimeoutSeconds; + /** @hide */ public VcnTransportInfo(@NonNull WifiInfo wifiInfo) { this(wifiInfo, INVALID_SUBSCRIPTION_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET); } + /** @hide */ public VcnTransportInfo(@NonNull WifiInfo wifiInfo, int minUdpPort4500NatTimeoutSeconds) { this(wifiInfo, INVALID_SUBSCRIPTION_ID, minUdpPort4500NatTimeoutSeconds); } + /** @hide */ public VcnTransportInfo(int subId) { this(null /* wifiInfo */, subId, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET); } + /** @hide */ public VcnTransportInfo(int subId, int minUdpPort4500NatTimeoutSeconds) { this(null /* wifiInfo */, subId, minUdpPort4500NatTimeoutSeconds); } @@ -86,6 +95,7 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { * <p>If the underlying Network for the associated VCN is Cellular, returns null. * * @return the WifiInfo if there is an underlying WiFi connection, else null. + * @hide */ @Nullable public WifiInfo getWifiInfo() { @@ -100,17 +110,27 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { * * @return the Subscription ID if a cellular underlying Network is present, else {@link * android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID}. + * @hide */ public int getSubId() { return mSubId; } /** - * Get the VCN provided UDP port 4500 NAT timeout + * Get the minimum duration that the VCN Gateway guarantees to preserve a NAT mapping. * - * @return the UDP 4500 NAT timeout, or + * <p>To ensure uninterrupted connectivity, the device must send keepalive packets before the + * timeout. Failure to do so may result in the mapping being cleared and connection termination. + * This value is used as a power-optimization hint for other IKEv2/IPsec use cases (e.g. VPNs, + * or IWLAN) to reduce the necessary keepalive frequency, thus conserving power and data. + * + * @return the minimum duration that the VCN Gateway guarantees to preserve a NAT mapping, or * VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET if not set. + * @see VcnGatewayConnectionConfig.Builder#setMinUdpPort4500NatTimeoutSeconds(int) + * @hide */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public int getMinUdpPort4500NatTimeoutSeconds() { return mMinUdpPort4500NatTimeoutSeconds; } @@ -129,12 +149,21 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { && mMinUdpPort4500NatTimeoutSeconds == that.mMinUdpPort4500NatTimeoutSeconds; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Override public int describeContents() { return 0; } + /** @hide */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Override @NonNull public TransportInfo makeCopy(long redactions) { @@ -149,6 +178,9 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { mMinUdpPort4500NatTimeoutSeconds); } + /** @hide */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Override public long getApplicableRedactions() { long redactions = REDACT_FOR_NETWORK_SETTINGS; @@ -161,7 +193,13 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { return redactions; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mSubId); @@ -174,7 +212,13 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { return "VcnTransportInfo { mWifiInfo = " + mWifiInfo + ", mSubId = " + mSubId + " }"; } - /** Implement the Parcelable interface */ + /** + * Implement the Parcelable interface + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final @NonNull Creator<VcnTransportInfo> CREATOR = new Creator<VcnTransportInfo>() { public VcnTransportInfo createFromParcel(Parcel in) { @@ -201,37 +245,63 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { } }; - /** This class can be used to construct a {@link VcnTransportInfo}. */ + /** + * This class can be used to construct a {@link VcnTransportInfo}. + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final class Builder { private int mMinUdpPort4500NatTimeoutSeconds = MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET; - /** Construct Builder */ + /** + * Construct Builder + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public Builder() {} /** - * Sets the maximum supported IKEv2/IPsec NATT keepalive timeout. + * Set the minimum duration that the VCN Gateway guarantees to preserve a NAT mapping. * * <p>This is used as a power-optimization hint for other IKEv2/IPsec use cases (e.g. VPNs, * or IWLAN) to reduce the necessary keepalive frequency, thus conserving power and data. * - * @param minUdpPort4500NatTimeoutSeconds the maximum keepalive timeout supported by the VCN - * Gateway Connection, generally the minimum duration a NAT mapping is cached on the VCN - * Gateway. + * @param minUdpPort4500NatTimeoutSeconds the minimum duration that the VCN Gateway + * guarantees to preserve a NAT mapping, or {@link MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET} + * to clear this value. To ensure uninterrupted connectivity, the device must send + * keepalive packets within this interval. Failure to do so may result in the mapping + * being cleared and connection termination. * @return this {@link Builder} instance, for chaining + * @see VcnGatewayConnectionConfig.Builder#setMinUdpPort4500NatTimeoutSeconds(int) + * @hide */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @NonNull public Builder setMinUdpPort4500NatTimeoutSeconds( @IntRange(from = MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS) int minUdpPort4500NatTimeoutSeconds) { Preconditions.checkArgument( - minUdpPort4500NatTimeoutSeconds >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS, - "Timeout must be at least 120s"); + minUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET + || minUdpPort4500NatTimeoutSeconds + >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS, + "Timeout must be at least 120s or MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET"); mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds; return Builder.this; } - /** Build a VcnTransportInfo instance */ + /** + * Build a VcnTransportInfo instance + * + * @hide + */ + @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) @NonNull public VcnTransportInfo build() { return new VcnTransportInfo( diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig index 1b2c575917b2..b461f95fec53 100644 --- a/core/java/android/net/vcn/flags.aconfig +++ b/core/java/android/net/vcn/flags.aconfig @@ -1,5 +1,5 @@ package: "android.net.vcn" -container: "system" +container: "com.android.tethering" flag { name: "safe_mode_config" @@ -15,14 +15,4 @@ flag { description: "Expose APIs from VCN for mainline migration" is_exported: true bug: "376339506" -} - -flag { - name: "fix_config_garbage_collection" - namespace: "vcn" - description: "Handle race condition in subscription change" - bug: "370862489" - metadata { - purpose: PURPOSE_BUGFIX - } }
\ No newline at end of file diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS index e63b6648a9ef..94259d7cf819 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -89,6 +89,8 @@ per-file DdmSyncState.java = sanglardf@google.com, rpaquay@google.com per-file DdmSyncStageUpdater.java = sanglardf@google.com, rpaquay@google.com # PerformanceHintManager +per-file CpuHeadroom*.aidl = file:/ADPF_OWNERS +per-file GpuHeadroom*.aidl = file:/ADPF_OWNERS per-file PerformanceHintManager.java = file:/ADPF_OWNERS per-file WorkDuration.java = file:/ADPF_OWNERS per-file IHintManager.aidl = file:/ADPF_OWNERS diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java index d5630fd46eb4..4123209eb755 100644 --- a/core/java/android/os/RemoteCallbackList.java +++ b/core/java/android/os/RemoteCallbackList.java @@ -214,7 +214,7 @@ public class RemoteCallbackList<E extends IInterface> { if (mFrozenCalleePolicy != FROZEN_CALLEE_POLICY_UNSET) { try { mBinder.removeFrozenStateChangeCallback(this); - } catch (UnsupportedOperationException e) { + } catch (UnsupportedOperationException | IllegalArgumentException e) { // The kernel does not support frozen notifications. Ignore the error and move // on. } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 1d70d18ac4c8..455e680e0bbc 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -830,7 +830,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall /** * Sets the desired amount of HDR headroom to be used when HDR content is presented on this - * SurfaceView. + * SurfaceView. This is expressed as the ratio of maximum HDR white point over the SDR + * white point, not as absolute nits. * * <p>By default the system will choose an amount of HDR headroom that is appropriate * for the underlying device capabilities & bit-depth of the panel. However, for some types @@ -844,6 +845,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall * See {@link Display#getHdrSdrRatio()} for more information as well as how to query the * current value.</p> * + * <p>Note: This API operates independently of both the + * {@link Window#setColorMode Widow color mode} and the + * {@link Window#setDesiredHdrHeadroom Window desiredHdrHeadroom}</p> + * * @param desiredHeadroom The amount of HDR headroom that is desired. Must be >= 1.0 (no HDR) * and <= 10,000.0. Passing 0.0 will reset to the default, automatically * chosen value. diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 0582afe6655d..cbee56365606 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -1334,6 +1334,9 @@ public abstract class Window { * <p>The requested color mode is not guaranteed to be honored. Please refer to * {@link #getColorMode()} for more information.</p> * + * <p>Note: This does not impact SurfaceViews or SurfaceControls, as those have their own + * independent color mode and HDR parameters.</p> + * * @see #getColorMode() * @see Display#isWideColorGamut() * @see Configuration#isScreenWideColorGamut() @@ -1361,6 +1364,9 @@ public abstract class Window { * See {@link Display#getHdrSdrRatio()} for more information as well as how to query the * current value.</p> * + * <p>Note: This does not impact SurfaceViews or SurfaceControls, as those have their own + * independent desired HDR headroom and HDR capabilities.</p> + * * @param desiredHeadroom The amount of HDR headroom that is desired. Must be >= 1.0 (no HDR) * and <= 10,000.0. Passing 0.0 will reset to the default, automatically * chosen value. diff --git a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java index 75aca1b8820c..7ce2ed823540 100644 --- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java +++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java @@ -23,10 +23,11 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import android.platform.test.ravenwood.RavenwoodConfig; +import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; +import org.junit.Rule; import org.junit.Test; import java.util.Objects; @@ -39,8 +40,8 @@ public class SystemPropertiesTest { private static final String PERSIST_KEY = "persist.sys.testkey"; private static final String NONEXIST_KEY = "doesnotexist_2341431"; - @RavenwoodConfig.Config - public static final RavenwoodConfig mRavenwood = new RavenwoodConfig.Builder() + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() .setSystemPropertyMutable(KEY, null) .setSystemPropertyMutable(UNSET_KEY, null) .setSystemPropertyMutable(PERSIST_KEY, null) diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 96edd63a9b12..782db358bf9f 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -1876,6 +1876,8 @@ public final class MediaCodecInfo { * Codecs with this security model is not included in * {@link MediaCodecList#REGULAR_CODECS}, but included in * {@link MediaCodecList#ALL_CODECS}. + * + * @hide */ @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2; diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index bd65b2ecb76a..bc09aee9ac11 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -1748,6 +1748,7 @@ public final class MediaFormat { (1 << MediaCodecInfo.SECURITY_MODEL_MEMORY_SAFE); /** * Flag for {@link MediaCodecInfo#SECURITY_MODEL_TRUSTED_CONTENT_ONLY}. + * @hide */ @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC) public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY = @@ -1759,8 +1760,7 @@ public final class MediaFormat { * The associated value is a flag of the following values: * {@link FLAG_SECURITY_MODEL_SANDBOXED}, * {@link FLAG_SECURITY_MODEL_MEMORY_SAFE}, - * {@link FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY}. The default value is - * {@link FLAG_SECURITY_MODEL_SANDBOXED}. + * The default value is {@link FLAG_SECURITY_MODEL_SANDBOXED}. * <p> * When passed to {@link MediaCodecList#findDecoderForFormat} or * {@link MediaCodecList#findEncoderForFormat}, MediaCodecList filters diff --git a/nfc/api/current.txt b/nfc/api/current.txt index 9a7a39f213ee..2aa73db06204 100644 --- a/nfc/api/current.txt +++ b/nfc/api/current.txt @@ -202,6 +202,7 @@ package android.nfc.cardemulation { method public boolean categoryAllowsForegroundPreference(String); method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService(); method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String); + method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public int getDefaultNfcSubscriptionId(); method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService(); method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter); method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService(); @@ -228,6 +229,10 @@ package android.nfc.cardemulation { field public static final String CATEGORY_PAYMENT = "payment"; field public static final String EXTRA_CATEGORY = "category"; field public static final String EXTRA_SERVICE_COMPONENT = "component"; + field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3; // 0x3 + 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_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 @@ -239,8 +244,13 @@ package android.nfc.cardemulation { } @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventListener { + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidConflictOccurred(@NonNull String); + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidNotRouted(@NonNull String); + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onInternalErrorReported(int); + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onNfcStateChanged(int); method @FlaggedApi("android.nfc.nfc_event_listener") public default void onObserveModeStateChanged(boolean); method @FlaggedApi("android.nfc.nfc_event_listener") public default void onPreferredServiceChanged(boolean); + method @FlaggedApi("android.nfc.nfc_event_listener") public default void onRemoteFieldChanged(boolean); } public abstract class HostApduService extends android.app.Service { diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt index c5b22ac398d6..d81ebc55ffc5 100644 --- a/nfc/api/system-current.txt +++ b/nfc/api/system-current.txt @@ -98,6 +98,7 @@ package android.nfc { method public void onDisableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>); method public void onDisableStarted(); method public void onEeListenActivated(boolean); + method public void onEeUpdated(); method public void onEnableFinished(int); method public void onEnableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>); method public void onEnableStarted(); @@ -121,6 +122,11 @@ package android.nfc { @FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry { method public int getNfceeId(); + method public int getType(); + field public static final int TYPE_AID = 0; // 0x0 + field public static final int TYPE_PROTOCOL = 1; // 0x1 + field public static final int TYPE_SYSTEM_CODE = 3; // 0x3 + field public static final int TYPE_TECHNOLOGY = 2; // 0x2 } @FlaggedApi("android.nfc.nfc_oem_extension") public final class OemLogItems implements android.os.Parcelable { @@ -187,14 +193,19 @@ package android.nfc.cardemulation { public final class CardEmulation { method @FlaggedApi("android.permission.flags.wallet_role_enabled") @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static android.content.ComponentName getPreferredPaymentService(@NonNull android.content.Context); method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int); - method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void overrideRoutingTable(@NonNull android.app.Activity, int, int); - method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void recoverRoutingTable(@NonNull android.app.Activity); + method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overrideRoutingTable(@NonNull android.app.Activity, int, int); + method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void recoverRoutingTable(@NonNull android.app.Activity); + method @FlaggedApi("android.nfc.enable_card_emulation_euicc") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setDefaultNfcSubscriptionId(int); method @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setServiceEnabledForCategoryOther(@NonNull android.content.ComponentName, boolean); field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3; // 0x3 field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1; // 0x1 field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2; // 0x2 field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4; // 0x4 field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_OK = 0; // 0x0 + field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2; // 0x2 + 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 } } diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl index 633d8bfbbb67..bb9fe959dc06 100644 --- a/nfc/java/android/nfc/INfcCardEmulation.aidl +++ b/nfc/java/android/nfc/INfcCardEmulation.aidl @@ -53,6 +53,8 @@ interface INfcCardEmulation void overrideRoutingTable(int userHandle, String protocol, String technology, in String pkg); void recoverRoutingTable(int userHandle); boolean isEuiccSupported(); + int getDefaultNfcSubscriptionId(in String pkg); + int setDefaultNfcSubscriptionId(int subscriptionId, in String pkg); void setAutoChangeStatus(boolean state); boolean isAutoChangeEnabled(); List<String> getRoutingStatus(); diff --git a/nfc/java/android/nfc/INfcEventListener.aidl b/nfc/java/android/nfc/INfcEventListener.aidl index 5162c26ac536..774d8f875192 100644 --- a/nfc/java/android/nfc/INfcEventListener.aidl +++ b/nfc/java/android/nfc/INfcEventListener.aidl @@ -8,4 +8,9 @@ import android.nfc.ComponentNameAndUser; oneway interface INfcEventListener { void onPreferredServiceChanged(in ComponentNameAndUser ComponentNameAndUser); void onObserveModeStateChanged(boolean isEnabled); + void onAidConflictOccurred(in String aid); + void onAidNotRouted(in String aid); + void onNfcStateChanged(in int nfcState); + void onRemoteFieldChanged(boolean isDetected); + void onInternalErrorReported(in int errorType); }
\ No newline at end of file diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl index 1a21c0bae413..e5eac0b4d6fd 100644 --- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl +++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl @@ -48,6 +48,7 @@ interface INfcOemExtensionCallback { void onRfFieldActivated(boolean isActivated); void onRfDiscoveryStarted(boolean isDiscoveryStarted); void onEeListenActivated(boolean isActivated); + void onEeUpdated(); void onGetOemAppSearchIntent(in List<String> firstPackage, in ResultReceiver intentConsumer); void onNdefMessage(in Tag tag, in NdefMessage message, in ResultReceiver hasOemExecutableContent); void onLaunchHceAppChooserActivity(in String selectedAid, in List<ApduServiceInfo> services, in ComponentName failedComponent, in String category); diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java index 5be23fd900db..b2e672e7997c 100644 --- a/nfc/java/android/nfc/NfcOemExtension.java +++ b/nfc/java/android/nfc/NfcOemExtension.java @@ -392,6 +392,15 @@ public final class NfcOemExtension { void onEeListenActivated(boolean isActivated); /** + * Notifies that some NFCEE (NFC Execution Environment) has been updated. + * + * <p> This indicates that some applet has been installed/updated/removed in + * one of the NFCEE's. + * </p> + */ + void onEeUpdated(); + + /** * Gets the intent to find the OEM package in the OEM App market. If the consumer returns * {@code null} or a timeout occurs, the intent from the first available package will be * used instead. @@ -863,6 +872,12 @@ public final class NfcOemExtension { } @Override + public void onEeUpdated() throws RemoteException { + mCallbackMap.forEach((cb, ex) -> + handleVoidCallback(null, (Object input) -> cb.onEeUpdated(), ex)); + } + + @Override public void onStateUpdated(int state) throws RemoteException { mCallbackMap.forEach((cb, ex) -> handleVoidCallback(state, cb::onStateUpdated, ex)); diff --git a/nfc/java/android/nfc/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java index 4e913776a030..c2cbbede9b75 100644 --- a/nfc/java/android/nfc/NfcRoutingTableEntry.java +++ b/nfc/java/android/nfc/NfcRoutingTableEntry.java @@ -17,8 +17,12 @@ package android.nfc; import android.annotation.FlaggedApi; +import android.annotation.IntDef; import android.annotation.SystemApi; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Class to represent an entry of routing table. This class is abstract and extended by * {@link RoutingTableTechnologyEntry}, {@link RoutingTableProtocolEntry}, @@ -30,10 +34,42 @@ import android.annotation.SystemApi; @SystemApi public abstract class NfcRoutingTableEntry { private final int mNfceeId; + private final int mType; + + /** + * AID routing table type. + */ + public static final int TYPE_AID = 0; + /** + * Protocol routing table type. + */ + public static final int TYPE_PROTOCOL = 1; + /** + * Technology routing table type. + */ + public static final int TYPE_TECHNOLOGY = 2; + /** + * System Code routing table type. + */ + public static final int TYPE_SYSTEM_CODE = 3; + + /** + * Possible type of this routing table entry. + * @hide + */ + @IntDef(prefix = "TYPE_", value = { + TYPE_AID, + TYPE_PROTOCOL, + TYPE_TECHNOLOGY, + TYPE_SYSTEM_CODE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface RoutingTableType {} /** @hide */ - protected NfcRoutingTableEntry(int nfceeId) { + protected NfcRoutingTableEntry(int nfceeId, @RoutingTableType int type) { mNfceeId = nfceeId; + mType = type; } /** @@ -43,4 +79,13 @@ public abstract class NfcRoutingTableEntry { public int getNfceeId() { return mNfceeId; } + + /** + * Get the type of this entry. + * @return an integer defined in {@link RoutingTableType} + */ + @RoutingTableType + public int getType() { + return mType; + } } diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java index 7634fe342ab9..bf697d662bd6 100644 --- a/nfc/java/android/nfc/RoutingTableAidEntry.java +++ b/nfc/java/android/nfc/RoutingTableAidEntry.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.SystemApi; /** - * Represents an AID entry in current routing table. + * Represents an Application ID (AID) entry in current routing table. * @hide */ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) @@ -30,7 +30,7 @@ public class RoutingTableAidEntry extends NfcRoutingTableEntry { /** @hide */ public RoutingTableAidEntry(int nfceeId, String value) { - super(nfceeId); + super(nfceeId, TYPE_AID); this.mValue = value; } diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java index 0c5be7dd9d97..536de4d7430e 100644 --- a/nfc/java/android/nfc/RoutingTableProtocolEntry.java +++ b/nfc/java/android/nfc/RoutingTableProtocolEntry.java @@ -97,7 +97,7 @@ public class RoutingTableProtocolEntry extends NfcRoutingTableEntry { /** @hide */ public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value) { - super(nfceeId); + super(nfceeId, TYPE_PROTOCOL); this.mValue = value; } diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java index f87ad5f95195..f61892d31668 100644 --- a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java +++ b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java @@ -20,7 +20,9 @@ import android.annotation.NonNull; import android.annotation.SystemApi; /** - * Represents a system code entry in current routing table. + * Represents a system code entry in current routing table, where system codes are two-byte values + * used in NFC-F technology (a type of NFC communication) to identify specific + * device configurations. * @hide */ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) @@ -30,7 +32,7 @@ public class RoutingTableSystemCodeEntry extends NfcRoutingTableEntry { /** @hide */ public RoutingTableSystemCodeEntry(int nfceeId, byte[] value) { - super(nfceeId); + super(nfceeId, TYPE_SYSTEM_CODE); this.mValue = value; } diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java index f51a5299be11..2dbc94232b0b 100644 --- a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java +++ b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java @@ -30,22 +30,27 @@ import java.lang.annotation.RetentionPolicy; @SystemApi public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry { /** - * Technology-A + * Technology-A. + * <p>Tech-A is mostly used for payment and ticketing applications. It supports various + * Tag platforms including Type 1, Type 2 and Type 4A tags. </p> */ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) public static final int TECHNOLOGY_A = 0; /** - * Technology-B + * Technology-B which is based on ISO/IEC 14443-3 standard. */ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) public static final int TECHNOLOGY_B = 1; /** - * Technology-F + * Technology-F. + * <p>Tech-F is a standard which supports Type 3 Tags and NFC-DEP protocol etc.</p> */ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) public static final int TECHNOLOGY_F = 2; /** - * Technology-V + * Technology-V. + * <p>Tech-V is an NFC technology used for communication with passive tags that operate + * at a longer range than other NFC technologies. </p> */ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) public static final int TECHNOLOGY_V = 3; @@ -73,7 +78,7 @@ public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry { /** @hide */ public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value) { - super(nfceeId); + super(nfceeId, TYPE_TECHNOLOGY); this.mValue = value; } diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java index 891752475824..cb364fb3298e 100644 --- a/nfc/java/android/nfc/cardemulation/CardEmulation.java +++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java @@ -22,6 +22,7 @@ import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; @@ -45,6 +46,7 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; +import android.telephony.SubscriptionManager; import android.util.ArrayMap; import android.util.Log; @@ -947,7 +949,7 @@ public final class CardEmulation { * * @param service The ComponentName of the service * @param status true to enable, false to disable - * @return true if preferred service is successfully set or unset, otherwise return false. + * @return status code defined in {@link SetServiceEnabledStatusCode} * * @hide */ @@ -1010,6 +1012,7 @@ public final class CardEmulation { * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE) public void overrideRoutingTable( @NonNull Activity activity, @ProtocolAndTechnologyRoute int protocol, @@ -1037,6 +1040,7 @@ public final class CardEmulation { * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE) public void recoverRoutingTable(@NonNull Activity activity) { if (!activity.isResumed()) { @@ -1058,6 +1062,97 @@ public final class CardEmulation { } /** + * Setting the default subscription ID succeeded. + * @hide + */ + @SystemApi + @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC) + public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0; + + /** + * Setting the default subscription ID failed because the subscription ID is invalid. + * @hide + */ + @SystemApi + @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC) + public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1; + + /** + * Setting the default subscription ID failed because there was an internal error processing + * the request. For ex: NFC service died in the middle of handling the API. + * @hide + */ + @SystemApi + @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC) + public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2; + + /** + * Setting the default subscription ID failed because this feature is not supported on the + * device. + * @hide + */ + @SystemApi + @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC) + public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3; + + /** @hide */ + @IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_", + value = { + SET_SUBSCRIPTION_ID_STATUS_SUCCESS, + SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID, + SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR, + SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SetSubscriptionIdStatus {} + + /** + * 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> + * + * @param subscriptionId the default NFC subscription Id to set. + * @return status of the operation. + * + * @throws UnsupportedOperationException If the device does not have + * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. + * @hide + */ + @SystemApi + @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION) + @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) + @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC) + public @SetSubscriptionIdStatus int setDefaultNfcSubscriptionId(int subscriptionId) { + return callServiceReturn(() -> + sService.setDefaultNfcSubscriptionId( + subscriptionId, mContext.getPackageName()), + SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR); + } + + /** + * 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> + * <p> If the device has no UICC that can serve as NFCEE, this will return + * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.</p> + * + * @return the default NFC subscription Id if set, + * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} otherwise. + * + * @throws UnsupportedOperationException If the device does not have + * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}. + */ + @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION) + @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC) + public int getDefaultNfcSubscriptionId() { + return callServiceReturn(() -> + sService.getDefaultNfcSubscriptionId(mContext.getPackageName()), + SubscriptionManager.INVALID_SUBSCRIPTION_ID); + } + + /** * Returns the value of {@link Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT}. * * @param context A context @@ -1144,6 +1239,40 @@ public final class CardEmulation { }; } + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0; + + /** + * This error is reported when the NFC command watchdog restarts the NFC stack. + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1; + + /** + * This error is reported when the NFC controller does not respond or there's an NCI transport + * error. + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2; + + /** + * This error is reported when the NFC stack times out while waiting for a response to a command + * sent to the NFC hardware. + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + @IntDef(prefix = "NFC_INTERNAL_ERROR_", value = { + NFC_INTERNAL_ERROR_UNKNOWN, + NFC_INTERNAL_ERROR_NFC_CRASH_RESTART, + NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR, + NFC_INTERNAL_ERROR_COMMAND_TIMEOUT, + }) + public @interface NfcInternalErrorType {} + /** Listener for preferred service state changes. */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) public interface NfcEventListener { @@ -1166,6 +1295,57 @@ public final class CardEmulation { */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) default void onObserveModeStateChanged(boolean isEnabled) {} + + /** + * This method is called when an AID conflict is detected during an NFC transaction. This + * can happen when multiple services are registered for the same AID. + * + * @param aid The AID that is in conflict + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onAidConflictOccurred(@NonNull String aid) {} + + /** + * This method is called when an AID is not routed to any service during an NFC + * transaction. This can happen when no service is registered for the given AID. + * + * @param aid the AID that was not routed + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onAidNotRouted(@NonNull String aid) {} + + /** + * This method is called when the NFC state changes. + * + * @see NfcAdapter#getAdapterState() + * + * @param state The new NFC state + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onNfcStateChanged(@NfcAdapter.AdapterState int state) {} + /** + * This method is called when the NFC controller is in card emulation mode and an NFC + * reader's field is either detected or lost. + * + * @param isDetected true if an NFC reader is detected, false if it is lost + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onRemoteFieldChanged(boolean isDetected) {} + + /** + * This method is called when an internal error is reported by the NFC stack. + * + * No action is required in response to these events as the NFC stack will automatically + * attempt to recover. These errors are reported for informational purposes only. + * + * Note that these errors can be reported when performing various internal NFC operations + * (such as during device shutdown) and cannot always be explicitly correlated with NFC + * transaction failures. + * + * @param errorType The type of the internal error + */ + @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER) + default void onInternalErrorReported(@NfcInternalErrorType int errorType) {} } private final ArrayMap<NfcEventListener, Executor> mNfcEventListeners = new ArrayMap<>(); @@ -1185,25 +1365,61 @@ public final class CardEmulation { mContext.getPackageName(), componentNameAndUser.getComponentName() .getPackageName()); - synchronized (mNfcEventListeners) { - mNfcEventListeners.forEach( - (listener, executor) -> { - executor.execute( - () -> listener.onPreferredServiceChanged(isPreferred)); - }); - } + callListeners(listener -> listener.onPreferredServiceChanged(isPreferred)); } public void onObserveModeStateChanged(boolean isEnabled) { if (!android.nfc.Flags.nfcEventListener()) { return; } + callListeners(listener -> listener.onObserveModeStateChanged(isEnabled)); + } + + public void onAidConflictOccurred(String aid) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onAidConflictOccurred(aid)); + } + + public void onAidNotRouted(String aid) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onAidNotRouted(aid)); + } + + public void onNfcStateChanged(int state) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onNfcStateChanged(state)); + } + + public void onRemoteFieldChanged(boolean isDetected) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onRemoteFieldChanged(isDetected)); + } + + public void onInternalErrorReported(@NfcInternalErrorType int errorType) { + if (!android.nfc.Flags.nfcEventListener()) { + return; + } + callListeners(listener -> listener.onInternalErrorReported(errorType)); + } + + interface ListenerCall { + void invoke(NfcEventListener listener); + } + + private void callListeners(ListenerCall listenerCall) { synchronized (mNfcEventListeners) { mNfcEventListeners.forEach( - (listener, executor) -> { - executor.execute( - () -> listener.onObserveModeStateChanged(isEnabled)); - }); + (listener, executor) -> { + executor.execute(() -> listenerCall.invoke(listener)); + }); } } }; diff --git a/packages/SettingsProvider/src/com/android/providers/settings/OWNERS b/packages/SettingsProvider/src/com/android/providers/settings/OWNERS index 0b7181606247..b0086c180cbd 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/OWNERS +++ b/packages/SettingsProvider/src/com/android/providers/settings/OWNERS @@ -1 +1,2 @@ -per-file WritableNamespacePrefixes.java = cbrubaker@google.com,tedbauer@google.com +per-file WritableNamespacePrefixes.java = mpgroover@google.com,tedbauer@google.com +per-file WritableNamespaces.java = mpgroover@google.com,tedbauer@google.com diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS index 9de229e2ddb8..a594ad64c1a7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS +++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS @@ -14,6 +14,14 @@ per-file *Keyboard* = set noparent per-file *Keyboard* = file:../keyguard/OWNERS per-file *Keyguard* = set noparent per-file *Keyguard* = file:../keyguard/OWNERS +# Not setting noparent here, since *Notification* also matches some status bar notification chips files (statusbar/chips/notification) which should be owned by the status bar team. +per-file *Notification* = file:notification/OWNERS +# Not setting noparent here, since *Mode* matches many other classes (e.g., *ViewModel*) +per-file *Mode* = file:notification/OWNERS +per-file *RemoteInput* = set noparent +per-file *RemoteInput* = file:notification/OWNERS +per-file *EmptyShadeView* = set noparent +per-file *EmptyShadeView* = file:notification/OWNERS per-file *Lockscreen* = set noparent per-file *Lockscreen* = file:../keyguard/OWNERS per-file *Scrim* = set noparent diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java index 869d854f7b23..9b71f8050c80 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java @@ -30,6 +30,8 @@ import android.util.Log; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.ravenwood.common.RavenwoodCommonUtils; + import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.Runner; @@ -229,7 +231,9 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase s.evaluate(); onAfter(description, scope, order, null); } catch (Throwable t) { - if (onAfter(description, scope, order, t)) { + var shouldReportFailure = RavenwoodCommonUtils.runIgnoringException( + () -> onAfter(description, scope, order, t)); + if (shouldReportFailure == null || shouldReportFailure) { throw t; } } diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java index 678a97be60a2..979076eaabfd 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java @@ -22,6 +22,8 @@ import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_INST_R import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK; import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING; import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERSION_JAVA_SYSPROP; +import static com.android.ravenwood.common.RavenwoodCommonUtils.parseNullableInt; +import static com.android.ravenwood.common.RavenwoodCommonUtils.withDefault; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -39,6 +41,7 @@ import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.os.Binder; import android.os.Build; +import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.HandlerThread; import android.os.Looper; @@ -64,6 +67,7 @@ import com.android.ravenwood.common.SneakyThrow; import com.android.server.LocalServices; import com.android.server.compat.PlatformCompat; +import org.junit.internal.management.ManagementFactory; import org.junit.runner.Description; import java.io.File; @@ -154,6 +158,13 @@ public class RavenwoodRuntimeEnvironmentController { private static RavenwoodAwareTestRunner sRunner; private static RavenwoodSystemProperties sProps; + private static final int DEFAULT_TARGET_SDK_LEVEL = VERSION_CODES.CUR_DEVELOPMENT; + private static final String DEFAULT_PACKAGE_NAME = "com.android.ravenwoodtests.defaultname"; + + private static int sTargetSdkLevel; + private static String sTestPackageName; + private static String sTargetPackageName; + /** * Initialize the global environment. */ @@ -194,6 +205,8 @@ public class RavenwoodRuntimeEnvironmentController { // Some process-wide initialization. (maybe redirect stdout/stderr) RavenwoodCommonUtils.loadJniLibrary(LIBRAVENWOOD_INITIALIZER_NAME); + dumpCommandLineArgs(); + // We haven't initialized liblog yet, so directly write to System.out here. RavenwoodCommonUtils.log(TAG, "globalInitInner()"); @@ -235,9 +248,22 @@ public class RavenwoodRuntimeEnvironmentController { System.setProperty("android.junit.runner", "androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner"); + loadRavenwoodProperties(); + assertMockitoVersion(); } + private static void loadRavenwoodProperties() { + var props = RavenwoodSystemProperties.readProperties("ravenwood.properties"); + + sTargetSdkLevel = withDefault( + parseNullableInt(props.get("targetSdkVersionInt")), DEFAULT_TARGET_SDK_LEVEL); + sTargetPackageName = withDefault(props.get("packageName"), DEFAULT_PACKAGE_NAME); + sTestPackageName = withDefault(props.get("instPackageName"), sTargetPackageName); + + // TODO(b/377765941) Read them from the manifest too? + } + /** * Initialize the environment. */ @@ -256,7 +282,9 @@ public class RavenwoodRuntimeEnvironmentController { initInner(runner.mState.getConfig()); } catch (Exception th) { Log.e(TAG, "init() failed", th); - reset(); + + RavenwoodCommonUtils.runIgnoringException(()-> reset()); + SneakyThrow.sneakyThrow(th); } } @@ -267,6 +295,14 @@ public class RavenwoodRuntimeEnvironmentController { Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler); } + config.mTargetPackageName = sTargetPackageName; + config.mTestPackageName = sTestPackageName; + config.mTargetSdkLevel = sTargetSdkLevel; + + Log.i(TAG, "TargetPackageName=" + sTargetPackageName); + Log.i(TAG, "TestPackageName=" + sTestPackageName); + Log.i(TAG, "TargetSdkLevel=" + sTargetSdkLevel); + RavenwoodRuntimeState.sUid = config.mUid; RavenwoodRuntimeState.sPid = config.mPid; RavenwoodRuntimeState.sTargetSdkLevel = config.mTargetSdkLevel; @@ -349,8 +385,11 @@ public class RavenwoodRuntimeEnvironmentController { * Partially re-initialize after each test method invocation */ public static void reinit() { - var config = sRunner.mState.getConfig(); - Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid)); + // sRunner could be null, if there was a failure in the initialization. + if (sRunner != null) { + var config = sRunner.mState.getConfig(); + Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid)); + } } private static void initializeCompatIds(RavenwoodConfig config) { @@ -380,6 +419,9 @@ public class RavenwoodRuntimeEnvironmentController { /** * De-initialize. + * + * Note, we call this method when init() fails too, so this method should deal with + * any partially-initialized states. */ public static void reset() { if (RAVENWOOD_VERBOSE_LOGGING) { @@ -411,7 +453,9 @@ public class RavenwoodRuntimeEnvironmentController { config.mState.mSystemServerContext.cleanUp(); } - Looper.getMainLooper().quit(); + if (Looper.getMainLooper() != null) { + Looper.getMainLooper().quit(); + } Looper.clearMainLooperForTest(); ActivityManager.reset$ravenwood(); @@ -547,4 +591,18 @@ public class RavenwoodRuntimeEnvironmentController { + " access to system property '" + key + "' denied via RavenwoodConfig"); } } + + private static void dumpCommandLineArgs() { + Log.i(TAG, "JVM arguments:"); + + // Note, we use the wrapper in JUnit4, not the actual class ( + // java.lang.management.ManagementFactory), because we can't see the later at the build + // because this source file is compiled for the device target, where ManagementFactory + // doesn't exist. + var args = ManagementFactory.getRuntimeMXBean().getInputArguments(); + + for (var arg : args) { + Log.i(TAG, " " + arg); + } + } } diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java index 3ed8b0a748e1..7ca9239d2062 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java @@ -22,7 +22,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Instrumentation; import android.content.Context; -import android.os.Build; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -30,16 +29,12 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; /** - * Represents how to configure the ravenwood environment for a test class. - * - * If a ravenwood test class has a public static field with the {@link Config} annotation, - * Ravenwood will extract the config from it and initializes the environment. The type of the - * field must be of {@link RavenwoodConfig}. + * @deprecated This class will be removed. Reach out to g/ravenwood if you need any features in it. */ +@Deprecated public final class RavenwoodConfig { /** * Use this to mark a field as the configuration. @@ -66,7 +61,7 @@ public final class RavenwoodConfig { String mTestPackageName; String mTargetPackageName; - int mTargetSdkLevel = Build.VERSION_CODES.CUR_DEVELOPMENT; + int mTargetSdkLevel; final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties(); @@ -91,12 +86,6 @@ public final class RavenwoodConfig { return RavenwoodRule.isOnRavenwood(); } - private void setDefaults() { - if (mTargetPackageName == null) { - mTargetPackageName = mTestPackageName; - } - } - public static class Builder { private final RavenwoodConfig mConfig = new RavenwoodConfig(); @@ -120,28 +109,27 @@ public final class RavenwoodConfig { } /** - * Configure the package name of the test, which corresponds to - * {@link Instrumentation#getContext()}. + * @deprecated no longer used. Package name is set in the build file. (for now) */ + @Deprecated public Builder setPackageName(@NonNull String packageName) { - mConfig.mTestPackageName = Objects.requireNonNull(packageName); return this; } /** - * Configure the package name of the target app, which corresponds to - * {@link Instrumentation#getTargetContext()}. Defaults to {@link #setPackageName}. + * @deprecated no longer used. Package name is set in the build file. (for now) */ + @Deprecated public Builder setTargetPackageName(@NonNull String packageName) { - mConfig.mTargetPackageName = Objects.requireNonNull(packageName); return this; } + /** - * Configure the target SDK level of the test. + * @deprecated no longer used. Target SDK level is set in the build file. (for now) */ + @Deprecated public Builder setTargetSdkLevel(int sdkLevel) { - mConfig.mTargetSdkLevel = sdkLevel; return this; } @@ -154,34 +142,32 @@ public final class RavenwoodConfig { } /** - * Configure the given system property as immutable for the duration of the test. - * Read access to the key is allowed, and write access will fail. When {@code value} is - * {@code null}, the value is left as undefined. - * - * All properties in the {@code debug.*} namespace are automatically mutable, with no - * developer action required. - * - * Has no effect on non-Ravenwood environments. + * @deprecated Use {@link RavenwoodRule.Builder#setSystemPropertyImmutable(String, Object)} */ + @Deprecated public Builder setSystemPropertyImmutable(@NonNull String key, @Nullable Object value) { - mConfig.mSystemProperties.setValue(key, value); - mConfig.mSystemProperties.setAccessReadOnly(key); return this; } /** - * Configure the given system property as mutable for the duration of the test. - * Both read and write access to the key is allowed, and its value will be reset between - * each test. When {@code value} is {@code null}, the value is left as undefined. - * - * All properties in the {@code debug.*} namespace are automatically mutable, with no - * developer action required. - * - * Has no effect on non-Ravenwood environments. + * @deprecated Use {@link RavenwoodRule.Builder#setSystemPropertyMutable(String, Object)} */ + @Deprecated public Builder setSystemPropertyMutable(@NonNull String key, @Nullable Object value) { + return this; + } + + Builder setSystemPropertyImmutableReal(@NonNull String key, + @Nullable Object value) { + mConfig.mSystemProperties.setValue(key, value); + mConfig.mSystemProperties.setAccessReadOnly(key); + return this; + } + + Builder setSystemPropertyMutableReal(@NonNull String key, + @Nullable Object value) { mConfig.mSystemProperties.setValue(key, value); mConfig.mSystemProperties.setAccessReadWrite(key); return this; @@ -205,7 +191,6 @@ public final class RavenwoodConfig { } public RavenwoodConfig build() { - mConfig.setDefaults(); return mConfig; } } diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java index bfa3802ce583..5681a9040f63 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java @@ -36,10 +36,8 @@ import java.util.Objects; import java.util.regex.Pattern; /** - * @deprecated Use {@link RavenwoodConfig} to configure the ravenwood environment instead. - * A {@link RavenwoodRule} is no longer needed for {@link DisabledOnRavenwood}. To get the - * {@link Context} and {@link Instrumentation}, use - * {@link androidx.test.platform.app.InstrumentationRegistry} instead. + * @deprecated This class is undergoing a major change. Reach out to g/ravenwood if you need + * any featues in it. */ @Deprecated public final class RavenwoodRule implements TestRule { @@ -128,11 +126,10 @@ public final class RavenwoodRule implements TestRule { } /** - * Configure the identity of this process to be the given package name for the duration - * of the test. Has no effect on non-Ravenwood environments. + * @deprecated no longer used. */ + @Deprecated public Builder setPackageName(@NonNull String packageName) { - mBuilder.setPackageName(packageName); return this; } @@ -155,7 +152,7 @@ public final class RavenwoodRule implements TestRule { * Has no effect on non-Ravenwood environments. */ public Builder setSystemPropertyImmutable(@NonNull String key, @Nullable Object value) { - mBuilder.setSystemPropertyImmutable(key, value); + mBuilder.setSystemPropertyImmutableReal(key, value); return this; } @@ -170,7 +167,7 @@ public final class RavenwoodRule implements TestRule { * Has no effect on non-Ravenwood environments. */ public Builder setSystemPropertyMutable(@NonNull String key, @Nullable Object value) { - mBuilder.setSystemPropertyMutable(key, value); + mBuilder.setSystemPropertyMutableReal(key, value); return this; } diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java index 3e4619f55c6d..9bd376a76f77 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java @@ -52,7 +52,7 @@ public class RavenwoodSystemProperties { "vendor_dlkm", }; - private static Map<String, String> readProperties(String propFile) { + static Map<String, String> readProperties(String propFile) { // Use an ordered map just for cleaner dump log. final Map<String, String> ret = new LinkedHashMap<>(); try { @@ -60,7 +60,7 @@ public class RavenwoodSystemProperties { .map(String::trim) .filter(s -> !s.startsWith("#")) .map(s -> s.split("\\s*=\\s*", 2)) - .filter(a -> a.length == 2) + .filter(a -> a.length == 2 && a[1].length() > 0) .forEach(a -> ret.put(a[0], a[1])); } catch (IOException e) { throw new RuntimeException(e); diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java index 520f050f0655..2a04d4469ef4 100644 --- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java +++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java @@ -30,6 +30,7 @@ import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; +import java.util.function.Supplier; public class RavenwoodCommonUtils { private static final String TAG = "RavenwoodCommonUtils"; @@ -277,11 +278,55 @@ public class RavenwoodCommonUtils { (isStatic ? "static" : ""))); } + /** + * Run a supplier and swallow the exception, if any. + * + * It's a dangerous function. Only use it in an exception handler where we don't want to crash. + */ + @Nullable + public static <T> T runIgnoringException(@NonNull Supplier<T> s) { + try { + return s.get(); + } catch (Throwable th) { + log(TAG, "Warning: Exception detected! " + getStackTraceString(th)); + } + return null; + } + + /** + * Run a runnable and swallow the exception, if any. + * + * It's a dangerous function. Only use it in an exception handler where we don't want to crash. + */ + public static void runIgnoringException(@NonNull Runnable r) { + runIgnoringException(() -> { + r.run(); + return null; + }); + } + @NonNull - public static String getStackTraceString(@Nullable Throwable th) { + public static String getStackTraceString(@NonNull Throwable th) { StringWriter stringWriter = new StringWriter(); PrintWriter writer = new PrintWriter(stringWriter); th.printStackTrace(writer); return stringWriter.toString(); } + + /** Same as {@link Integer#parseInt(String)} but accepts null and returns null. */ + @Nullable + public static Integer parseNullableInt(@Nullable String value) { + if (value == null) { + return null; + } + return Integer.parseInt(value); + } + + /** + * @return {@code value} if it's non-null. Otherwise, returns {@code def}. + */ + @Nullable + public static <T> T withDefault(@Nullable T value, @Nullable T def) { + return value != null ? value : def; + } } diff --git a/ravenwood/tests/bivalentinst/Android.bp b/ravenwood/tests/bivalentinst/Android.bp index 41e45e5a6d95..31e3bcc3634f 100644 --- a/ravenwood/tests/bivalentinst/Android.bp +++ b/ravenwood/tests/bivalentinst/Android.bp @@ -27,6 +27,9 @@ android_ravenwood_test { "junit", "truth", ], + + package_name: "com.android.ravenwood.bivalentinsttest_self_inst", + resource_apk: "RavenwoodBivalentInstTest_self_inst_device", auto_gen_config: true, } @@ -53,6 +56,10 @@ android_ravenwood_test { "truth", ], resource_apk: "RavenwoodBivalentInstTestTarget", + + package_name: "com.android.ravenwood.bivalentinst_target_app", + inst_package_name: "com.android.ravenwood.bivalentinsttest_nonself_inst", + inst_resource_apk: "RavenwoodBivalentInstTest_nonself_inst_device", auto_gen_config: true, } diff --git a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java index 77874bd28677..919aa439d4ef 100644 --- a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java +++ b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java @@ -19,8 +19,6 @@ import static com.google.common.truth.Truth.assertThat; import android.app.Instrumentation; import android.content.Context; -import android.platform.test.ravenwood.RavenwoodConfig; -import android.platform.test.ravenwood.RavenwoodConfig.Config; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; @@ -40,11 +38,6 @@ public class RavenwoodInstrumentationTest_nonself { private static final String TEST_PACKAGE_NAME = "com.android.ravenwood.bivalentinsttest_nonself_inst"; - @Config - public static final RavenwoodConfig sConfig = new RavenwoodConfig.Builder() - .setPackageName(TEST_PACKAGE_NAME) - .setTargetPackageName(TARGET_PACKAGE_NAME) - .build(); private static Instrumentation sInstrumentation; private static Context sTestContext; diff --git a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java index 203923bb551b..81cfa662920c 100644 --- a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java +++ b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java @@ -19,8 +19,6 @@ import static com.google.common.truth.Truth.assertThat; import android.app.Instrumentation; import android.content.Context; -import android.platform.test.ravenwood.RavenwoodConfig; -import android.platform.test.ravenwood.RavenwoodConfig.Config; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; @@ -41,13 +39,6 @@ public class RavenwoodInstrumentationTest_self { private static final String TEST_PACKAGE_NAME = "com.android.ravenwood.bivalentinsttest_self_inst"; - @Config - public static final RavenwoodConfig sConfig = new RavenwoodConfig.Builder() - .setPackageName(TEST_PACKAGE_NAME) - .setTargetPackageName(TARGET_PACKAGE_NAME) - .build(); - - private static Instrumentation sInstrumentation; private static Context sTestContext; private static Context sTargetContext; diff --git a/ravenwood/tests/bivalenttest/Android.bp b/ravenwood/tests/bivalenttest/Android.bp index 40e6672a3c63..ac545dfb06cc 100644 --- a/ravenwood/tests/bivalenttest/Android.bp +++ b/ravenwood/tests/bivalenttest/Android.bp @@ -84,6 +84,8 @@ java_defaults { android_ravenwood_test { name: "RavenwoodBivalentTest", defaults: ["ravenwood-bivalent-defaults"], + target_sdk_version: "34", + package_name: "com.android.ravenwoodtest.bivalenttest", auto_gen_config: true, } diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java index a5a16c14600b..306c2b39c70d 100644 --- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java +++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java @@ -20,8 +20,6 @@ import static android.platform.test.ravenwood.RavenwoodConfig.isOnRavenwood; import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeTrue; -import android.platform.test.ravenwood.RavenwoodConfig; - import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; @@ -33,13 +31,7 @@ import org.junit.runner.RunWith; */ @RunWith(AndroidJUnit4.class) public class RavenwoodConfigTest { - private static final String PACKAGE_NAME = "com.test"; - - @RavenwoodConfig.Config - public static RavenwoodConfig sConfig = - new RavenwoodConfig.Builder() - .setPackageName(PACKAGE_NAME) - .build(); + private static final String PACKAGE_NAME = "com.android.ravenwoodtest.bivalenttest"; @Test public void testConfig() { diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt index a95760db1a61..882c91c43ee9 100644 --- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt +++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt @@ -16,8 +16,6 @@ package com.android.ravenwoodtest.bivalenttest.compat import android.app.compat.CompatChanges -import android.os.Build -import android.platform.test.ravenwood.RavenwoodConfig import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.internal.ravenwood.RavenwoodEnvironment.CompatIdsForTest import org.junit.Assert @@ -26,14 +24,6 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class RavenwoodCompatFrameworkTest { - companion object { - @JvmField // Expose as a raw field, not as a property. - @RavenwoodConfig.Config - val config = RavenwoodConfig.Builder() - .setTargetSdkLevel(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) - .build() - } - @Test fun testEnabled() { Assert.assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_1)) @@ -53,4 +43,4 @@ class RavenwoodCompatFrameworkTest { fun testEnabledAfterUForUApps() { Assert.assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_4)) } -}
\ No newline at end of file +} diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java index 02d10732245d..f94b98bc1fb8 100644 --- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java +++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java @@ -24,6 +24,7 @@ import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; @@ -32,6 +33,10 @@ import org.junit.runner.RunWith; /** * Test for @Config field extraction and validation. + * + * TODO(b/377765941) Most of the tests here will be obsolete and deleted with b/377765941, but + * some of the tests may need to be re-implemented one way or another. (e.g. the package name + * test.) Until that happens, we'll keep all tests here but add an {@code @Ignore} instead. */ @NoRavenizer // This class shouldn't be executed with RavenwoodAwareTestRunner. public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase { @@ -59,6 +64,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase testRunFinished: 1,0,0,0 """) // CHECKSTYLE:ON + @Ignore // Package name is no longer set via config. public static class ConfigInBaseClassTest extends ConfigInBaseClass { @Test public void test() { @@ -83,6 +89,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase testRunFinished: 1,0,0,0 """) // CHECKSTYLE:ON + @Ignore // Package name is no longer set via config. public static class ConfigOverridingTest extends ConfigInBaseClass { static String PACKAGE_NAME_OVERRIDE = "com.ConfigOverridingTest"; @@ -376,6 +383,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase testRunFinished: 1,0,0,0 """) // CHECKSTYLE:ON + @Ignore // Package name is no longer set via config. public static class RuleInBaseClassSuccessTest extends RuleInBaseClass { @Test @@ -437,6 +445,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase testRunFinished: 1,1,0,0 """) // CHECKSTYLE:ON + @Ignore // Package name is no longer set via config. public static class RuleWithDifferentTypeInBaseClassSuccessTest extends RuleWithDifferentTypeInBaseClass { @Test diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java index f7a2198a9bc4..0e3d053e90b1 100644 --- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java +++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java @@ -25,6 +25,8 @@ import android.util.Log; import junitparams.JUnitParamsRunner; import junitparams.Parameters; + +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.Description; import org.junit.runner.JUnitCore; @@ -103,6 +105,7 @@ public abstract class RavenwoodRunnerTestBase { var thisClass = this.getClass(); var ret = Arrays.stream(thisClass.getNestMembers()) .filter((c) -> c.getAnnotation(Expected.class) != null) + .filter((c) -> c.getAnnotation(Ignore.class) == null) .toArray(Class[]::new); assertThat(ret.length).isGreaterThan(0); diff --git a/ravenwood/tests/runtime-test/Android.bp b/ravenwood/tests/runtime-test/Android.bp index 0c0df1f993aa..c3520031ea7d 100644 --- a/ravenwood/tests/runtime-test/Android.bp +++ b/ravenwood/tests/runtime-test/Android.bp @@ -9,7 +9,7 @@ package { android_ravenwood_test { name: "RavenwoodRuntimeTest", - + target_sdk_version: "34", libs: [ "ravenwood-helper-runtime", ], diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt index 8ec0932d89dd..61e254b225c3 100644 --- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt +++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt @@ -43,7 +43,7 @@ fun checkClass(cn: ClassNode, classes: ClassNodes): Boolean { } var allOk = true - log.i("Checking ${cn.name.toHumanReadableClassName()}") + log.v("Checking ${cn.name.toHumanReadableClassName()}") // See if there's any class that extends a legacy base class. // But ignore the base classes in android.test. diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 0c99fcfd221a..f50eb18cf2d2 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -327,7 +327,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku SystemUiDeviceConfigFlags.GENERATED_PREVIEW_API_RESET_INTERVAL_MS, DEFAULT_GENERATED_PREVIEW_RESET_INTERVAL_MS); final int generatedPreviewMaxCallsPerInterval = DeviceConfig.getInt(NAMESPACE_SYSTEMUI, - SystemUiDeviceConfigFlags.GENERATED_PREVIEW_API_RESET_INTERVAL_MS, + SystemUiDeviceConfigFlags.GENERATED_PREVIEW_API_MAX_CALLS_PER_INTERVAL, DEFAULT_GENERATED_PREVIEW_MAX_CALLS_PER_INTERVAL); mGeneratedPreviewsApiCounter = new ApiCounter(generatedPreviewResetInterval, generatedPreviewMaxCallsPerInterval); diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java index 9b987e9850c4..8c83ad70625a 100644 --- a/services/core/java/com/android/server/SystemConfig.java +++ b/services/core/java/com/android/server/SystemConfig.java @@ -1319,6 +1319,7 @@ public class SystemConfig { } XmlUtils.skipCurrentTag(parser); } break; + case "disabled-in-sku": case "disabled-until-used-preinstalled-carrier-app": { if (allowAppConfigs) { String pkgname = parser.getAttributeValue(null, "package"); @@ -1335,6 +1336,24 @@ public class SystemConfig { } XmlUtils.skipCurrentTag(parser); } break; + case "enabled-in-sku-override": { + if (allowAppConfigs) { + String pkgname = parser.getAttributeValue(null, "package"); + if (pkgname == null) { + Slog.w(TAG, + "<" + name + "> without " + + "package in " + permFile + " at " + + parser.getPositionDescription()); + } else if (!mDisabledUntilUsedPreinstalledCarrierApps.remove(pkgname)) { + Slog.w(TAG, + "<" + name + "> packagename:" + pkgname + " not included" + + "in disabled-in-sku"); + } + } else { + logNotAllowedInPartition(name, permFile, parser); + } + XmlUtils.skipCurrentTag(parser); + } break; case "privapp-permissions": { if (allowPrivappPermissions) { // privapp permissions from system, apex, vendor, product and diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java index 06e6c8b1ec53..2012f5632a64 100644 --- a/services/core/java/com/android/server/VcnManagementService.java +++ b/services/core/java/com/android/server/VcnManagementService.java @@ -48,7 +48,6 @@ import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; -import android.net.vcn.Flags; import android.net.vcn.IVcnManagementService; import android.net.vcn.IVcnStatusCallback; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; @@ -890,20 +889,11 @@ public class VcnManagementService extends IVcnManagementService.Stub { while (configsIterator.hasNext()) { final ParcelUuid subGrp = configsIterator.next(); - if (Flags.fixConfigGarbageCollection()) { - if (!subGroups.contains(subGrp)) { - // Trim subGrps with no more subscriptions; must have moved to another subGrp - logDbg("Garbage collect VcnConfig for group=" + subGrp); - configsIterator.remove(); - shouldWrite = true; - } - } else { - final List<SubscriptionInfo> subscriptions = subMgr.getSubscriptionsInGroup(subGrp); - if (subscriptions == null || subscriptions.isEmpty()) { - // Trim subGrps with no more subscriptions; must have moved to another subGrp - configsIterator.remove(); - shouldWrite = true; - } + if (!subGroups.contains(subGrp)) { + // Trim subGrps with no more subscriptions; must have moved to another subGrp + logDbg("Garbage collect VcnConfig for group=" + subGrp); + configsIterator.remove(); + shouldWrite = true; } } diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 211f952551d9..0b61a80a2416 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -2181,7 +2181,7 @@ public final class CachedAppOptimizer { Slog.d(TAG_AM, "Performing native compaction for pid=" + pid + " type=" + compactProfile.name()); - Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactSystem"); + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactNative"); try { mProcessDependencies.performCompaction(compactProfile, pid); } catch (Exception e) { diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index 4ec2a04551e9..90f92b079220 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -449,7 +449,7 @@ public class SettingsToPropertiesMapper { proto.write(StorageRequestMessage.FlagOverrideMessage.FLAG_NAME, flagName); proto.write(StorageRequestMessage.FlagOverrideMessage.FLAG_VALUE, flagValue); proto.write(StorageRequestMessage.FlagOverrideMessage.OVERRIDE_TYPE, isLocal - ? StorageRequestMessage.LOCAL_ON_REBOOT + ? StorageRequestMessage.LOCAL_IMMEDIATE : StorageRequestMessage.SERVER_ON_REBOOT); proto.end(msgToken); proto.end(msgsToken); diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java index f085647c9676..645206a91c0a 100644 --- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java +++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java @@ -174,10 +174,6 @@ class PreAuthInfo { return BIOMETRIC_NO_HARDWARE; } - if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) { - return BIOMETRIC_HARDWARE_NOT_DETECTED; - } - final boolean wasStrongEnough = Utils.isAtLeastStrength(sensor.oemStrength, requestedStrength); final boolean isStrongEnough = @@ -189,6 +185,10 @@ class PreAuthInfo { return BIOMETRIC_INSUFFICIENT_STRENGTH; } + if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) { + return BIOMETRIC_HARDWARE_NOT_DETECTED; + } + try { if (!sensor.impl.isHardwareDetected(opPackageName)) { return BIOMETRIC_HARDWARE_NOT_DETECTED; diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java index 82d5d4d8141d..e8786be4d8e6 100644 --- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java +++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java @@ -677,10 +677,11 @@ public class BiometricScheduler<T, U> { * Start the timeout for the watchdog. */ public void startWatchdog() { - if (mCurrentOperation == null) { + final BiometricSchedulerOperation operation = mCurrentOperation; + if (operation == null) { + Slog.e(TAG, "Current operation is null,no need to start watchdog"); return; } - final BiometricSchedulerOperation operation = mCurrentOperation; mHandler.postDelayed(() -> { if (operation == mCurrentOperation && !operation.isFinished()) { Counter.logIncrement("biometric.value_scheduler_watchdog_triggered_count"); diff --git a/services/core/java/com/android/server/input/InputShellCommand.java b/services/core/java/com/android/server/input/InputShellCommand.java index 4c5a3c27e156..d8cf68e1b87c 100644 --- a/services/core/java/com/android/server/input/InputShellCommand.java +++ b/services/core/java/com/android/server/input/InputShellCommand.java @@ -472,6 +472,7 @@ public class InputShellCommand extends ShellCommand { } } } + event = KeyEvent.changeTimeRepeat(event, SystemClock.uptimeMillis(), 0); injectKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP), async); } diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS index e8fc577d9f0f..62b89f3252e6 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -38,19 +38,19 @@ per-file SELinuxMMAC* = alanstokes@google.com, cbrubaker@google.com, jeffv@googl per-file SaferIntentUtils.java = topjohnwu@google.com # shortcuts -per-file LauncherAppsService.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShareTargetInfo.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutBitmapSaver.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutDumpFiles.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutLauncher.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutNonPersistentUser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutPackage.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutPackageInfo.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutPackageItem.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutParser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutRequestPinProcessor.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutService.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com -per-file ShortcutUser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com +per-file LauncherAppsService.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShareTargetInfo.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutBitmapSaver.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutDumpFiles.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutLauncher.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutNonPersistentUser.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutPackage.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutPackageInfo.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutPackageItem.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutParser.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutRequestPinProcessor.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutService.java = pinyaoting@google.com, sunnygoyal@google.com +per-file ShortcutUser.java = pinyaoting@google.com, sunnygoyal@google.com # background install control service -per-file BackgroundInstall* = file:BACKGROUND_INSTALL_OWNERS
\ No newline at end of file +per-file BackgroundInstall* = file:BACKGROUND_INSTALL_OWNERS diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 52a2fd6e4955..688312e7e004 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -2968,7 +2968,10 @@ public final class SystemServer implements Dumpable { if (com.android.ranging.flags.Flags.rangingStackEnabled()) { if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB) || context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_WIFI_RTT)) { + PackageManager.FEATURE_WIFI_RTT) + || (com.android.ranging.flags.Flags.rangingCsEnabled() + && context.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING))) { t.traceBegin("RangingService"); // TODO: b/375264320 - Remove after RELEASE_RANGING_STACK is ramped to next. try { diff --git a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java index b40d7ee39a4c..67202174535c 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java @@ -20,6 +20,7 @@ import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NO import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; import static android.hardware.biometrics.BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE; +import static android.hardware.biometrics.BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE; import static com.android.server.biometrics.sensors.LockoutTracker.LOCKOUT_NONE; @@ -55,6 +56,7 @@ public class PreAuthInfoTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + private static final int USER_ID = 0; private static final int SENSOR_ID_FINGERPRINT = 0; private static final int SENSOR_ID_FACE = 1; private static final String TEST_PACKAGE_NAME = "PreAuthInfoTestPackage"; @@ -184,6 +186,20 @@ public class PreAuthInfoTest { assertThat(preAuthInfo.eligibleSensors.get(0).modality).isEqualTo(TYPE_FINGERPRINT); } + @Test + public void prioritizeStrengthErrorBeforeCameraUnavailableError() throws Exception { + final BiometricSensor sensor = getFaceSensorWithStrength( + BiometricManager.Authenticators.BIOMETRIC_WEAK); + final PromptInfo promptInfo = new PromptInfo(); + promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG); + promptInfo.setNegativeButtonText(TEST_PACKAGE_NAME); + final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, + mSettingObserver, List.of(sensor), USER_ID , promptInfo, TEST_PACKAGE_NAME, + false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager); + + assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo(BIOMETRIC_ERROR_NO_HARDWARE); + } + private BiometricSensor getFingerprintSensor() { BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FINGERPRINT, TYPE_FINGERPRINT, BiometricManager.Authenticators.BIOMETRIC_STRONG, @@ -202,9 +218,10 @@ public class PreAuthInfoTest { return sensor; } - private BiometricSensor getFaceSensor() { + private BiometricSensor getFaceSensorWithStrength( + @BiometricManager.Authenticators.Types int sensorStrength) { BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FACE, TYPE_FACE, - BiometricManager.Authenticators.BIOMETRIC_STRONG, mFaceAuthenticator) { + sensorStrength, mFaceAuthenticator) { @Override boolean confirmationAlwaysRequired(int userId) { return false; @@ -218,4 +235,8 @@ public class PreAuthInfoTest { return sensor; } + + private BiometricSensor getFaceSensor() { + return getFaceSensorWithStrength(BiometricManager.Authenticators.BIOMETRIC_STRONG); + } } diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java index 3bc089fb3f5d..842c441e09f2 100644 --- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java @@ -691,6 +691,40 @@ public class SystemConfigTest { assertThat(actual).isEqualTo(expected); } + /** + * Tests that readPermissions works correctly for the tags: + * disabled-in-sku, enabled-in-sku-override. + * I.e. that disabled-in-sku add package to block list and + * enabled-in-sku-override removes package from the list. + */ + @Test + public void testDisablePackageInSku() throws Exception { + final String disable_in_sku = + "<config>\n" + + " <disabled-in-sku package=\"com.sony.product1.app\"/>\n" + + " <disabled-in-sku package=\"com.sony.product2.app\"/>\n" + + "</config>\n"; + + final String enable_in_sku_override = + "<config>\n" + + " <enabled-in-sku-override package=\"com.sony.product2.app\"/>\n" + + "</config>\n"; + + final File folder1 = createTempSubfolder("folder1"); + createTempFile(folder1, "permissionFile1.xml", disable_in_sku); + + final File folder2 = createTempSubfolder("folder2"); + createTempFile(folder2, "permissionFile2.xml", enable_in_sku_override); + + readPermissions(folder1, /* Grant all permission flags */ ~0); + readPermissions(folder2, /* Grant all permission flags */ ~0); + + final ArraySet<String> blocklist = mSysConfig.getDisabledUntilUsedPreinstalledCarrierApps(); + + assertThat(blocklist).contains("com.sony.product1.app"); + assertThat(blocklist).doesNotContain("com.sony.product2.app"); + } + private void parseSharedLibraries(String contents) throws IOException { File folder = createTempSubfolder("permissions_folder"); createTempFile(folder, "permissions.xml", contents); diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index 3828a71d7b28..4ab8e6abbbef 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -70,7 +70,6 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.Uri; -import android.net.vcn.Flags; import android.net.vcn.IVcnStatusCallback; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; import android.net.vcn.VcnConfig; @@ -293,8 +292,6 @@ public class VcnManagementServiceTest { doReturn(Collections.singleton(TRANSPORT_WIFI)) .when(mMockDeps) .getRestrictedTransports(any(), any(), any()); - - mSetFlagsRule.enableFlags(Flags.FLAG_FIX_CONFIG_GARBAGE_COLLECTION); } |